2017-01-29 16 views
0

文字列のリストが完全に別の文字列に含まれているかどうかを確認するコードを書きました。他の文字列リストに完全に含まれている文字列のリストを確認する

public static void main(String[] args) { 
    LinkedList<String> l1 = new LinkedList<String>(); 
    LinkedList<String> l2 = new LinkedList<String>(); 
    l1.add("Cc"); 
    l1.add("Dd"); 
    l2.add("Cc"); 
    l2.add("Dd"); 
    l2.add("Ee"); 
    LinkedList<LinkedList<String>> l = new LinkedList<LinkedList<String>>(); 
    l.add(l1); 
    l.add(l2); 
    System.out.println("OUTPUT: " + filterSublist(l)); 

} 

static List<LinkedList<String>> filterSublist(LinkedList<LinkedList<String>> l) { 
    List<LinkedList<String>> uniq = new LinkedList<LinkedList<String>>(l); 
    l.forEach(elem -> uniq.removeIf(x -> !x.equals(elem) && elem.contains(x))); 
    return uniq; 
} 

function filterSubListは、他のリストに完全に含まれるリストのないリストのリストを返さなければなりません。

  • リスト1: "CC、DD"
  • リスト2: "CC、Ddは、Eeと"

リスト1は、全体リスト2に含まれているので、我々が持っている例では これは間違っている

OUTPUT: [[Cc, Dd], [Cc, Dd, Ee]] 

:関数は、私は両方を含むリストである出力を得たプログラムを実行するときにのみ、リスト2 が含まれています。しかしリストのリストを返す必要があります。 filterSubList関数に間違いがありますか?

+0

2つの 'lists'の** equality **をチェックするために' equals() 'メソッドを使用しない理由はありますか? –

+0

良い方法があるかどうかわかりません。何を指示してるんですか? –

+0

さて、 'equals()'メソッドを使うと、比較された2つのリストが等しい場合に 'true'を返すことができます。例 'System.out.println(list1.equals(list2))'のように。しかし、内容の順序が重要であることに注意してください。注文について気にしない場合は、 'HashSet' @Walriderを使うことができます –

答えて

1

別のリスト(オブジェクト)を含む1つのリスト(オブジェクト)を確認しています。新しいオブジェクトが作成されるたびに新しいリストがのcon​​tainsAllと内部のオブジェクトをチェックする代わりに、メモリに異なっallotedされます。

代わりにこれを試してみてください:

static List<LinkedList<String>> filterSublist(LinkedList<LinkedList<String>> l) { 
List<LinkedList<String>> uniq = new LinkedList<LinkedList<String>>(l); 
l.forEach(elem -> uniq.removeIf(x -> !x.equals(elem) && elem.containsAll(x))); 
return uniq; 
} 

をルネさんがOPに関連するいくつかのポイントを提起した場合、しかし、ここでは、彼のリードにかなり違う方法で実装されています。

static List<LinkedList<String>> filterSublistAlternate(LinkedList<LinkedList<String>> l) { 
boolean[] removed = new boolean[ l.size() ]; 
outer: for(int i=0; i< l.size() ; i++) 
    inner: for(int j=0; j< l.size() ; j++) 
    { 
     if(i != j) 
     if(l.get(j).containsAll(l.get(i))) 
     { 
      System.out.println(i+" and "+j); 
      if(l.get(i).size() == l.get(j).size()) 
       if(removed[i] == removed[j] && !removed[i]) 
        removed[i] = true; 
       else 
        continue outer; 
      else 
      { 
       removed[i] = true; 
       continue outer; 
      } 

     } 
    } 

for(int i=removed.length-1; i>=0 ; i--) 
    if(removed[i]) 
     l.remove(i); 

return l; 
} 
+0

この解決法は、 'uniq'が' equals'の使用のために同じリストを複数回含んでいるかもしれないという問題があります。 –

+0

同じリストがそれ自身と比較されないように、等しいが使用されます。 – dev8080

+0

正確には「等しい」のために、結果が重複している可能性があります。 lに別のl3 = ["Cc"、 "Dd"、 "Ee"]を追加して、結果を見てみましょう。 –

0

それがあるように私は以下のソリューションを提案している。それは本当に、単一の要素だけではなく(サブリストをチェックして、それが元のリスト

  • は、より正確な重複しないよう

    • より多くのメモリ効率的有無)の結果から
    • それは重複を削除するように、より正確な

    コード:

    static List<LinkedList<String>> filterSublist(LinkedList<LinkedList<String>> l) { 
        return l.stream() 
         .filter(x -> l.stream().noneMatch(elem -> !elem.equals(x) && Collections.indexOfSubList(elem, x) != -1)) 
         .distinct() 
         .collect(Collectors.toList()); 
    } 
    
  • +0

    「元のリストを複製しないのでメモリをより効率的に使用できます」 - 別のリストを返すことが要件だったことを理解しました。他のものは簡単に救済することができます。 – dev8080

    +0

    @ dev8080要件が満たされていれば、リストが返されます。しかし、このソリューションでは、元の完全なリストを前もってコピーしているわけではありません。したがって、削除されるサブリストが多数ある場合は、メモリ使用量が少なくなります。 –

    関連する問題