2016-07-18 16 views
0

)2つのリストが等しい場所まで、すばやくスマートな方法を探しています。つまり、共通の要素を含む最小のパーティションを2つ以上のリストの同じ順序で見つける必要があります。 それは少し混乱に聞こえるが、ここで私が達成したいものの一例であるかもしれません。2つ以上のリストの共通要素のJava最小パーティション(

List 1: A, B, C, L, M Z 
List 2: A, B, C, K, F 
Output -> List 3: A, B, C 

私は大の入力と、私が来ているすべてのソリューションと呼ばれるべき再帰的方法でこれを使用する必要がありますとにかく遅すぎる。事前にあなたの答えのための

おかげ


EDIT: 不明確であることのために私を許しなさい。これは私の最初の質問であり、英語は母国語ではありません。

より良い方法で問題を説明してください。リストの最初の要素から始まる2つ以上のリストの共通部分を見つける必要があります。要素は同じ順序でなければならないので、それは正確には交差点ではなく、よりパーティションに似ていることに注意してください。

"再帰的な"ことは、何度も実行される再帰的なメソッドにこれを含める必要があると言っていたので、多くの時間を失わないようにできるだけ早く解決したいと思います。私は私自身の解決策を考え出した削除されているような答えに取り組ん

List<String> list1 = new ArrayList<>(Arrays.asList("ciao", "come")); 
    List<String> list2 = new ArrayList<>(Arrays.asList("ciao", "come", "va")); 
    List<String> list3 = new ArrayList<>(Arrays.asList("ciao", "come", "va", "?", "tutto", "ok")); 
    List<List<String>> allLists = new ArrayList<>(); 
    allLists.addAll(Arrays.asList(list1, list2, list3)); 

    int min = Integer.MAX_VALUE; 
    int listIndex = 0; 
    for(List<String> list : allLists){ 
     if(min > list.size()){ 
      min = list.size(); 
      listIndex = allLists.indexOf(list); 
     } 
    } 


    int index = 0; 
    boolean same = true; 
    while(index<min && same == true) { 
     String element = allLists.get(listIndex).get(index); 
     for(List<String> list : allLists){ 
      if(!list.get(index).equals(element)){ 
       same = false; 
       break; 
      } 
      element = allLists.get(listIndex).get(index); 
     } 
     if(same == true) ++index; 
    } 
    System.out.println("OUTPUT:" + allLists.get(listIndex).subList(0, index)); 
----> Output: ciao, come 

EDIT2:

ものgarnfulソリューションは、魔法のように動作し、私はそれを見つけます私よりもはっきり分かります。おかげでみんな

+0

質問は何ですか? – Li357

+0

この問題を解決する良い方法は何ですか? –

+0

アルゴリズムは再帰的でなければなりませんか? – Keiwan

答えて

0

これは仕事をし、そして、できればパフォーマンスに関するかなり大丈夫でなければなりません:

public List<String> getEqualsPart(List<String>[] listsToCheck) { 
    if (listsToCheck.length == 0) { 
     return Collections.emptyList(); 
    } 
    int minLength = getShortesListLength(listsToCheck); 
    if (minLength == 0) { 
     return Collections.emptyList(); 
    } 
    return getEqualPartsForIndex(listsToCheck, 0, minLength, new ArrayList<String>()); 

} 

private int getShortesListLength(List<String>[] listsToCheck) { 
    int min = Integer.MAX_VALUE; 
    for (List<String> currentList : listsToCheck) { 
     min = Math.min(min, currentList.size()); 
    } 
    return min; 
} 

private List<String> getEqualPartsForIndex(List<String>[] listsToCheck, int index, int minLength, 
     List<String> result) { 
    if (index == minLength) { 
     return result; 
    } 
    Set<String> setForIndex = new HashSet<>(); 
    Arrays.stream(listsToCheck).forEach(list -> setForIndex.add(list.get(index))); 
    if (setForIndex.size() > 1) { 
     return result; 
    } else { 
     result.add(setForIndex.iterator().next()); 
     return getEqualPartsForIndex(listsToCheck, index + 1, minLength, result); 
    } 

}` 
+0

この解決法の性能は、入力リストがArrayListsの場合に適しています。これが当てはまらない場合は、うまくいくソリューションが少し複雑になります。 – garnulf

+0

メソッド自体が必然的に再帰的でなければならないという事実以外は、私の質問はとてもうまく説明できませんでしたが、それは魅力のように機能します。ありがとう –

0

試してみてください。

public List<E> equalUntil(List<E> l1, List<E> l2) { 
    return equalUntilRec(l1.iterator(), l2.iterator(), new ArrayList<E>()); 
} 

private int equalUntilRec(Iterator<E> it1, Iterator<E> it2, List<E> acc) { 
    if(!it1.hasNext() || !it2.hasNext()) { 
     return acc; 
    } else { 
     E e1 = it1.next(); 
     E e2 = it2.next(); 
     if(!e1.equals(e2)) { 
      return acc; 
     } 
     acc.add(e1); 
     return equalUntilRec(it1, it2, acc); 
    } 
} 
+0

メソッド自体は再帰的である必要はなく、OPに従って 'int'ではなくリストを返さなければなりません –

関連する問題