6

Java で複数のリストの共通部分を取得するのに問題があります。私がやっていることはこれです:私は(言ってみましょう)整数の3つのリストを取得します:

リスト 1: [2, 2, 2, 2, 5, 5]

リスト 2: [2, 2, 103]

リスト 3: [2, 431]

残りの各リストを使用して、retainAll を最初のリストに適用しています。

list1.retainAll(list2);
list1.retainAll(list3);

そして、私はこの結果を得ています:

list1: [2, 2, 2, 2]

しかし、私はこれを手に入れることを期待しています:

リスト1: [2]

...すべてのリストが共有する唯一の要素は4 つの2ではなく、 1 つの 2 であるためです。

これはおそらく、retainAll 関数の予期される動作であることはわかっていますが、上記の結果を取得する必要があります。

何か助けはありますか?

編集: HashSetを使用して重複を禁止しても、うまくいきません。この場合、例えば:

リスト 1: [2, 2, 2, 2, 5, 5]

リスト 2: [2, 2, 103]

リスト 3: [2, 2, 2, 431]

次の結果を取得する必要があります。

list 1: [2, 2] (すべてのリストには少なくとも 2 のペアがあるため)

それ以外の

リスト 1: [2]

4

6 に答える 6

6

この方法はどうですか:

public static <T> Collection <T> intersect (Collection <? extends T> a, Collection <? extends T> b)
{
    Collection <T> result = new ArrayList <T> ();

    for (T t: a)
    {
        if (b.remove (t)) result.add (t);
    }

    return result;
}

public static void main (String [] args)
{
    List <Integer> list1 = new ArrayList <Integer> (Arrays.<Integer>asList (2, 2, 2, 2, 5, 5));
    List <Integer> list2 = new ArrayList <Integer> (Arrays.<Integer>asList (2, 2, 103));
    List <Integer> list3 = new ArrayList <Integer> (Arrays.<Integer>asList (2, 431));

    System.out.println (intersect (list1, intersect (list2, list3)));
}
于 2013-02-08T23:29:01.350 に答える
2

私はある種のSet、おそらくを使用しHashSetます。重複する要素を追加することはなく、retainAllメソッドがあります。

Set<Integer> uniqueNums = new HashSet<Integer>(list1);
uniqueNums.retainAll(list2);
uniqueNums.retainAll(list3);

これがのjavadocsですSet

于 2013-02-08T23:33:56.450 に答える
2

この問題は、マルチセット データ構造を使用すると簡単に解決できます。たとえば、グアバの を使用する場合はMultiset、次を使用できますMultisets.retainOccurrences()

于 2013-02-08T23:29:54.690 に答える
0

リストの代わりに、bag または multiset と呼ばれるデータ構造が必要です。たとえば、Apache commons collections ライブラリには次のものが含まれます。

http://commons.apache.org/collections/apidocs/org/apache/commons/collections/Bag.html#retainAll(java.util.Collection)

于 2013-02-08T23:27:20.857 に答える
0

あなたretainAllが言ったように、あなたは間違った答えを得るでしょう。ペアをHashMap維持integer/countし、お互いのリストをスキャンして、map.

  1. の値mapから を設定しますlist1
  2. 互いのリストを反復処理し、 を取得して、その値でmin(# of intg in other_list, map.get(intg))を更新mapします。
  3. 結果mapは、すべてのリストの共通部分になります。
于 2013-02-08T23:27:56.923 に答える
0

これはあなたが好きなもので、再帰的です。

public static <T> List<T> intersect(List<T> c1, List<T> c2) {
    List<T> inter = new ArrayList<>(c1);
    inter.retainAll(c2);
    return inter;
}

public static <T> List<T> intersect(List<T> first, List<T>... rest) {
    if (rest.length == 0)
        return first;

    List<T> second = rest[0];

    first = intersect(first,second);
    rest = Arrays.copyOfRange(rest, 1, rest.length);

    return intersect(first, rest);
}
于 2015-09-25T23:19:44.303 に答える