2012-01-10 86 views
3

有兩個的ArrayList:刪除行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}); 

如何刪除arr1出現在arr2和那些行非唯一arr1?例如。在這個例子中,我只需要刪除{1,2,3},因爲它在arr1中出現不止一次。我想到的唯一解決方案是使用4個FOR循環,但它似乎是非常低效的解決方案。

編輯#1 所得arr1: {1,2,3},{1,2,2},{1,1,1},{1,1,1}

+1

在你的例子中,你期望得到的'arr1'是什麼? – NPE 2012-01-10 18:38:54

+0

生成的arr1:{1,2,3},{1,2,2},{1,1,1},{1,1,1} – 2012-01-10 18:49:44

回答

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

如何使用Iterator以防列表而不是列表? – 2012-01-10 19:08:24

+0

@KlausosKlausos:迭代器 it = myClassList.iterator(); – 2012-01-10 19:10:27

+0

我假設如果(!set1.add(curr)&& selectedTokens.contains(curr))對列表無法正常工作。 MyClass有兩個字段:字符串鍵和整數[]值。我查了你的解決方案。它適用於列表,但不適用於MyClass(?)。 – 2012-01-10 19:26:28

2

排序清單1.遍歷目錄1開始[1]。如果有重複的(a[i] == a[i-1]),請在列表2中查找該數組。如果存在,請刪除a[i]

請注意,在Java中,當您循環訪問時,無法修改列表,因此實際上需要保留一個單獨的列表,以便在完成循環後從列表1中刪除該列表。

這將導致從列表1

+1

對於像arr1這樣的二維數組,它是一個高效的解決方案:{ 1,2,3},{1,2,2},{1,1,1}? – 2012-01-10 18:58:41

1

使用Set,這便是刪除非唯一身份刪除所有重複的。然後您可以使用removeAllretainAll。 對Integer[](或int[])使用包裝類,它可以使用Arrays.equals

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? – 2012-01-10 18:59:32

+0

'arr1.removeAll(arr2)'會通過刪除arr2中的所有內容來縮小arr1。我提到'retainAll'只是因爲它的模糊名稱和它對補語的等同用途:刪除了arr2中的_not_元素。 – 2012-01-10 20:13:55

1

使用名單將是這樣的:

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

如果您只是將刪除的元素保留爲空,並且只清理最後刪除剩下的空白位置,而不是嘗試始終移動元素,則這會減少移位量(O(n)操作)並將總體時間從O(n^2*m^2)提高到O(n*m)

如果你可以使用sorted List1,你可以查找和O(LOGN),總的複雜性後會有mlogn

如果你可以使用HashMap,這將允許您查找的O刪除刪除(1),您可以進一步將時間複雜度降低到基本爲O(m),然後您可以使用一個循環遍歷列表2並從集合1中刪除所有相同的元素。

Loop through List 1 
    Add element to HashMap:Element -> Count (the count is here to preserve duplicates) 
    If already exist in HashMap, Count++ 
Loop through List 2 
    For every element A, set B.get(A) = 0 
Iterate through the HashMap 
    For every entry, add the entry to the List *Count* times (rebuild list) 

如果你真的這樣做,每個步驟都有輔助方法,使用它們。