How to remove duplicates from a list using helper array in Java?

I am trying to remove duplicates from the list by creating a temporary array that stores the indexes where the duplicates are located, and then copy the original array to another temporary array, comparing the indexes with the indexes that I saved in my first temporary array.

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; } 

and although the logic seems correct, my compiler gives me an arrayindexoutofbounds error in

 tempa[counter] = j; 

I don’t understand how a counter can grow above items.length, where is there a logical flaw?

+4
source share
8 answers

You are doing something rather difficult for yourself. Let Java do the hard work for you. For example, LinkedHashSet gives you uniqueness and preserves the insertion order. It will also be more efficient than comparing each value with any other value.

 double [] input = {1,2,3,3,4,4}; Set<Double> tmp = new LinkedHashSet<Double>(); 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)); 
+13
source

Done for int arrays, but can easily be converted to double.

1) If you do not care about the initial elements of the array:

 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) if you care about the initial elements of the array:

 private static int[] withoutDuplicates2(int[] a) { HashSet<Integer> keys = new HashSet<Integer>(); 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) If you do not care about the initial elements of the array:

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

Imagine this was your input:

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

Then, according to your algorithm, tempa should be:

 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 

Why do you have this problem? Since the first set of nested loops doesn't stop you from trying to insert duplicate indices of repeating arrays!

What is the best solution?

Use the kit! Sets ensure that there are no duplicate entries. If you create a new Set and then add all the elements of the array to it, Set will change the duplicates. Then it's just a matter of returning from the set to the array.

Alternatively, here is a very C-shaped way to do the same:

 //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 } } } } 

I will leave it to you to figure out how to finish.

+2
source
 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<Integer>(); for(int i=0;i<arr.length;i++){ set.add(Integer.valueOf(arr[i])); } System.out.println(set); } } 
+2
source

You have already used num_items to link your loop. Use this variable to set the array size for tempa.

 double tempa [] = new double [num_items]; 
0
source

Instead of doing this in an array, you can just use java.util.Set .

Here is an example:

 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<Double> singleValues = new HashSet<Double>(); for (Double value : values) { singleValues.add(value); } System.out.println("singleValues: "+singleValues); // now convert it into double array Double[] dValues = singleValues.toArray(new Double[]{}); } 
0
source

Here's another alternative without using sets, only primitive types:

 public static double [] removeDuplicates(double arr[]) { double [] tempa = new double[arr.length]; int uniqueCount = 0; for (int i=0;i<arr.length;i++) { boolean unique = true; for (int j=0;j<uniqueCount && unique;j++) { if (arr[i] == tempa[j]) { unique = false; } } if (unique) { tempa[uniqueCount++] = arr[i]; } } return Arrays.copyOf(tempa, uniqueCount); } 

This requires a temporary array of double objects on the way to getting your actual result.

0
source

You can use the set to remove multiples.

0
source

Source: https://habr.com/ru/post/1436727/


All Articles