如何使用Java中的辅助数组从列表中删除重复项?

我试图通过创建一个临时数组来删除列表中的重复项,该数组存储重复项所在的索引,然后将原始数组复制到另一个临时数组中,同时将索引与我存储在第一个临时数组中的索引进行比较。

public void removeDuplicates() { double tempa [] = new double [items.length]; int counter = 0; for ( int i = 0; i< numItems ; i++) { for(int j = i + 1; j < numItems; j++) { if(items[i] ==items[j]) { tempa[counter] = j; counter++; } } } double tempb [] = new double [ items.length]; int counter2 = 0; int j =0; for(int i = 0; i < numItems; i++) { if(i != tempa[j]) { tempb[counter2] = items[i]; counter2++; } else { j++; } } items = tempb; numItems = counter2; } 

虽然逻辑似乎正确,但我的编译器在给我一个arrayindexoutofbounds错误

 tempa[counter] = j; 

我不明白计数器如何增长到items.length的值以上,逻辑缺陷在哪里?

你为自己制造的东西很难。 让Java为您做繁重的工作。 例如,LinkedHashSet为您提供唯一性并保留插入顺序。 它比将每个值与每个其他值进行比较也更有效。

 double [] input = {1,2,3,3,4,4}; Set tmp = new LinkedHashSet(); for (Double each : input) { tmp.add(each); } double [] output = new double[tmp.size()]; int i = 0; for (Double each : tmp) { output[i++] = each; } System.out.println(Arrays.toString(output)); 

完成int数组,但很容易转换为double。

1)如果你不关心初始数组元素的顺序:

 private static int[] withoutDuplicates(int[] a) { Arrays.sort(a); int hi = a.length - 1; int[] result = new int[a.length]; int j = 0; for (int i = 0; i < hi; i++) { if (a[i] == a[i+1]) { continue; } result[j] = a[i]; j++; } result[j++] = a[hi]; return Arrays.copyOf(result, j); } 

2)如果你关心初始数组元素的顺序:

 private static int[] withoutDuplicates2(int[] a) { HashSet keys = new HashSet(); int[] result = new int[a.length]; int j = 0; for (int i = 0 ; i < a.length; i++) { if (keys.add(a[i])) { result[j] = a[i]; j++; } } return Arrays.copyOf(result, j); } 

3)如果你不关心初始数组元素的顺序:

 private static Object[] withoutDuplicates3(int[] a) { HashSet keys = new HashSet(); for (int value : a) { keys.add(value); } return keys.toArray(); } 

想象一下这是你的输入数据:

 Index: 0, 1, 2, 3, 4, 5, 6, 7, 8 Value: 1, 2, 3, 3, 3, 3, 3, 3, 3 

然后根据你的算法, tempa需要是:

 Index: 0, 1, 2, 3, 4, 5, 6, 7, 8, ....Exception!!! Value: 3, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8, 5, 6, 7, 8, 6, 7, 8, 7, 8, 8 

你为什么遇到这个问题? 因为第一组嵌套for循环不会阻止您尝试插入重复数组索引的重复项!

什么是最好的解决方案?

使用套装! 设置保证其中没有重复的条目。 如果您创建一个新的Set然后将所有数组项添加到它,Set将修剪重复项。 然后,这只是从Set回到数组的问题。

或者,这是一个非常C方式做同样的事情:

 //duplicates will be a truth table indicating which indices are duplicates. //initially all values are set to false boolean duplicates[] = new boolean[items.length]; for ( int i = 0; i< numItems ; i++) { if (!duplicates[i]) { //if i is not a known duplicate for(int j = i + 1; j < numItems; j++) { if(items[i] ==items[j]) { duplicates[j] = true; //mark j as a known duplicate } } } } 

我留给你弄清楚如何完成。

 import java.util.HashSet; import sun.security.util.Length; public class arrayduplication { public static void main(String[] args) { int arr[]={1,5,1,2,5,2,10}; TreeSet< Integer>set=new TreeSet(); for(int i=0;i 

您已经使用num_items来绑定循环。 使用该变量也可以为tempa设置数组大小。

 double tempa [] = new double [num_items]; 

您可以简单地使用java.util.Set而不是在数组中执行此操作。

这是一个例子:

 public static void main(String[] args) { Double[] values = new Double[]{ 1.0, 2.0, 2.0, 2.0, 3.0, 10.0, 10.0 }; Set singleValues = new HashSet(); for (Double value : values) { singleValues.add(value); } System.out.println("singleValues: "+singleValues); // now convert it into double array Double[] dValues = singleValues.toArray(new Double[]{}); } 

这是另一种不使用集合的替代方法,只有原始类型:

 public static double [] removeDuplicates(double arr[]) { double [] tempa = new double[arr.length]; int uniqueCount = 0; for (int i=0;i 

它确实需要一个临时的双重对象数组来获得实际结果。

您可以使用一组来删除倍数。