2012-01-10 11 views
3

は、二つの配列リストがあります:削除行が1

ArrayList<Integer[]> arr1 = new ArrayList<Integer[]>(); 
ArrayList<Integer[]> arr2 = new ArrayList<Integer[]>(); 
arr1.add(new Integer[]{1,2,3}); 
arr1.add(new Integer[]{1,2,2}); 
arr1.add(new Integer[]{1,2,3}); 
arr1.add(new Integer[]{1,1,1}); 
arr1.add(new Integer[]{1,1,1}); 

arr2.add(new Integer[]{1,2,3}); 
arr2.add(new Integer[]{1,2,2}); 

arr2に表示されていることarr1から行を削除する方法arr1ではユニークではありませんか?例えば。この例では、arr1に複数回表示されるため、{1,2,3}だけを削除する必要があります。私の心に来る唯一の解決策は、4 FORループを使用することですが、非常に非効率的な解決策であるようです。 [1]から始まるリスト1を通じてarr1: {1,2,3},{1,2,2},{1,1,1},{1,1,1}

+1

あなたの例では、結果として得られる 'arr1'はどのようなものになると思いますか? – NPE

+0

結果arr1:{1,2,3}、{1,2,2}、{1,1,1}、{1,1,1} –

答えて

2

あなたの代わりに、配列のListを使用することができる場合は、次のよう、あなたは何かができる:

List<List<Integer>> arr1 = new ArrayList<List<Integer>>();   
List<List<Integer>> arr2 = new ArrayList<List<Integer>>(); 

arr1.add(Arrays.asList(new Integer[]{1, 2, 3})); 
arr1.add(Arrays.asList(new Integer[]{1, 2, 3})); 
arr1.add(Arrays.asList(new Integer[]{1, 2, 2})); 
arr1.add(Arrays.asList(new Integer[]{1, 2, 3})); 
arr1.add(Arrays.asList(new Integer[]{1, 1, 1})); 
arr1.add(Arrays.asList(new Integer[]{1, 1, 1})); 

arr2.add(Arrays.asList(new Integer[]{1, 2, 3})); 
arr2.add(Arrays.asList(new Integer[]{1, 2, 2})); 

System.out.println(arr1); 
System.out.println(arr2); 

Set<List<Integer>> set1 = new HashSet<List<Integer>>();   
Iterator<List<Integer>> it = arr1.iterator(); 

while(it.hasNext()) { 
    List<Integer> curr = it.next(); 
    if(!set1.add(curr) && arr2.contains(curr)) { 
     it.remove(); 
    } 
} 

System.out.println(arr1); 

出力:リストを使用して

 
[[1, 2, 3], [1, 2, 3], [1, 2, 2], [1, 2, 3], [1, 1, 1], [1, 1, 1]] 
[[1, 2, 3], [1, 2, 2]] 
[[1, 2, 3], [1, 2, 2], [1, 1, 1], [1, 1, 1]] 
+0

List ではなくList がある場合に、Iteratorを使用するにはどうすればよいですか? –

+0

@KlausosKlausos:Iterator it = myClassList.iterator(); –

+0

リストに対して(!set1.add(curr)&& selectedTokens.contains(curr))が正しく動作しないとします。 MyClassには、StringキーとInteger []の2つのフィールドがあります。私はあなたの解決策をチェックした。リストでは正常に動作しますが、MyClass(?)では機能しません。 –

2

ソートリスト1.ループを結果として生じる

編集#1 。重複している(a[i] == a[i-1])がある場合は、リスト2の配列を探します。存在する場合は、a[i]を削除します。

Javaでは、リストをループするときにリストを変更することはできません。実際にループが終了したら、リスト1から削除する配列のリストを個別に保管する必要があります。

これは、リストから1

+1

arr1のような2次元配列の効率的なソリューションですか{ 1,2,3}、{1,2,2}、{1,1,1}? –

1

使用非ユニークを削除しますSet Sを、重複をすべて取り除くになります。 removeAllretainAllを使用できます。 Arrays.equalsを使用できるInteger[](またはint[])のラッパークラスを使用します。場合

public class IntArray implements Comparable<IntArray> { 
    Integer[] items; 

    public IntArray() { 
     this.items = new Integer[0]; 
    } 

    public IntArray(int... items) { 
     this.items = items; 
    } 
    ... 
} 
+0

この特定のケースでは、どのようにしてremoveAllとretainAllを使用できますか? –

+0

'arr1.removeAll(arr2)'は、arr2内にあるものもすべて削除することによってarr1を縮小します。私は 'retainAll'を、あいまいな名前と、補数の等価な有用性についてのみ述べました:arr2の_not_でない要素を取り除くこと。 –

1

はこのようなものになります。

Loop through 2 
For every element A, loop through 1 and delete element B if it matches A. 

削除された要素をnullのままにして、要素を常にシフトしようとするのではなく、削除によって残された空の部分だけをクリーンアップするだけでは、シフト量(O(n)操作) O(n^2*m^2)からO(n*m)に全体の時間を改善します。

あなたがルックアップするために許可し、Oに削除されます、あなたが sorted List1を使用できる場合は、ルックアップし、O(LOGN)で削除することができますが、 HashMapを使用することができた場合は、合計複雑さは、その後 mlogn

なります

、 (1)を使用すると、時間の複雑さを基本的にO(m)に減らすことができます。次に、1つのループを使用してリスト2を通過させ、同じ要素をすべてセット1から削除することができます。

実際にこれを行う場合は、途中でヘルパーメソッドが使用されます。