2017-07-15 10 views
2

構造は{{Dog,Cat,Human},{Human,Dog,Whale,rabbit,Cow},{Monkey,Human,Dog}}です。2つ以上の交差する方法のリストを交差させる代わりに?

出力は、Dog,Humanである必要があります。

私は大きなリストの中でリスト要素の共通部分を見つけなければなりません。以前は、私は別のArrayListsの交差点を見つけるコードを見ましたが、同じArrayList(2つ以上)の中でどうやってそれを行うことができるかわかりません。

別途ArrayLists次のようなコードです。しかし、どのように私はそれが複数のArrayListsの中でより大きくなるようにしますかArrayList?私はインタビューでこれを尋ねられました。別のリストのために働いたが、同じArrayListのためにそれをチョークアウトできませんでした。

インタビュアーは文字列のみで動作することを明示していたので、説明の後に汎用タイプのトークンを{<T>}から{<String>}に変更しました。

これにより、2つの別々のArrayListsに対して正しい出力が生成されます。しかし、入力がわずかに変更された場合、例えば、交差方法は入力a,a,aa,a,に対してa,a,aを返しますが、a,aa,a,aの場合はa,aとなります。論理的な前提は、パラメータの順序にかかわらず常にa,aを返すことです。

入力順に関係なくこれをどのように修正できるかについてのご意見はありますか?そして、どのように私は複数のリスト(2つ以上)の交差点を1つの大きなリストの中に見つけることができましたか?

+1

で繰り返し交差点メソッドを呼び出すで、あなただけの繰り返しリストとの交点を見つけることができますその交差点が返され、新しいリストが返されます。機能指向言語では、 'intersection'を使ってリストのリストを折りたたんだり縮小したりするだけです。 – Carcigenicate

+0

リストがソートされている場合は、ジッパー技術を使って 'O(n)'に実装することができます。各リストには、最初はインデックス0にマーカーを配置します。すべての値を比較し、異なる場合は、より小さな値を示すすべてのリスト上でマーカーを進めます。マーカーがリストの終わりに達するまで続けます(1つは交差のために十分です)。 *情報検索*の一般的なトリック。 – Zabuza

答えて

1

あなたがする必要があるすべてはあなたが働い `intersection`機能を持って提供し、このfashion-

import java.util.List; 
import java.util.ArrayList; 
import java.util.Arrays; 
import java.util.Iterator; 
public class HelloWorld{ 

public static void main(String []args){ 
    List<String> list1 = new ArrayList<String>(Arrays.asList("Dog", "Cat", "Human")); 
    List<String> list2 = new ArrayList<String>(Arrays.asList("Human", "Dog", "Whale", "rabbit", "Cow")); 

    List<List<String>> lists=new ArrayList<List<String>>(); 

    lists.add(list1); 
    lists.add(list2); 
    Iterator<List<String>> iterator=lists.iterator(); 
    List<String>intersect=null; 
    while(iterator.hasNext()){ 
     List<String> current=iterator.next(); 
      if(intersect==null){ 
       intersect=current; 
      } 
      else{ 
       intersect=intersection(intersect,current); 
      } 
    } 
    System.out.println(intersect); 
} 

public static List<String> intersection(List<String> list1, List<String> list2) { 
    List<String> list = new ArrayList<>(); 

    for (String t: list1) { 
     if(list2.contains(t)) { 
      list.add(t); 
     } 
    } 

    return list; 
} 

}

+0

私はアプローチが好きです。しかし、これはどういうわけか機能していません。実行して確認してください。 – coder1532

+0

@ coder1532私はコード全体を見てください。私のソリューションが気に入ったら、それを受け入れてupvoteしてください。 –

+0

作品@JoeyPinto – coder1532

2

あなたはStreamfilterを使用してリストを交差することができます。

List<String> list1 = new ArrayList<String>(Arrays.asList("Dog", "Cat", "Human")); 
List<String> list2 = new ArrayList<String>(Arrays.asList("Human", "Dog", "Whale", "rabbit", "Cow")); 
System.out.println(list1.stream() 
      .filter(list2::contains) 
      .collect(Collectors.toList())); 

OUTPUT:

[Dog, Human] 
+3

彼は交差点が組合でないと言った –

+0

@JoeyPintoは訂正してくれてありがとう。一定! – alfasin

+0

いい仕事@alfasinですが、これは複数のリストでどのように機能しますか? –

6

交差点あなたは二つのリストの交差点を実施し、その後に、繰り返し同じアルゴリズムを適用することができ、associativeです残りのリスト

JavaはretainAll操作で交差点を行うための組み込みの方法を提供します:

List<String> a = ... 
List<String> b = ... 
List<String> c = ... 
List<String> intersection = new ArrayList<>(a); 
intersection.retainAll(b); 
intersection.retainAll(c); 
+0

作品..この方法では、別の方法は必要ない。 – coder1532

1

だけintersectionを使用してリストのリストを折り、intersection作品と仮定すると:

List<ArrayList<String>> lists = /* Lists of lists here */; 

List<String> finalIntersection = 
    lists.stream() 
     .reduce(intersection) 
     .collect(Collectors.toList()) 
未テスト

が、提供intersectionのタイプは、reduceが期待するものと一致し、reduceは、アキュムレータが最初のエレメントとして開始することを可能にする過負荷を有する。

残念ながら、この解決策はストリームのためにreduceメソッドを持つJavaのために膨らんでいます。 Clojureの(別のJVM言語)では、コードのほぼ同等のスニペットは、単純に次のようになります。ただ美しいです

(reduce intersection lists) 

を。

関連する問題