-1

This post - "Java + Count duplicates from int array without using any Collection or another intermediate Array", was also a sample exercise in my book at school, but what I want to do is get the elements that has duplicates without sorting it.

What I did is I removed the duplicates of arrays first, to get only the unique elements and then I compare it to the original array and count how many times the element has been found. But the problem is it doesn't print the correct elements which has duplicates.

int[] num = {7, 2, 6, 1, 4, 7, 4, 5, 4, 7, 7, 3, 1};

the correct output should be: 7, 1, 4

but instead it outputs: 7, 6, 1

This is my codes:

//method for removing duplicates
public static int[] removeDuplicates(int[] n) {
    int limit = n.length;

    for(int i = 0; i < limit; i++) {
        for(int j = i + 1; j < limit; j++) {
            if(n[i] == n[j]) {
                for(int k = j; k < limit - 1; k++) {
                    n[k] = n[k + 1];
                }
                limit--;
                j--;
            }
        }
    }

    int[] uniqueValues = new int[limit];
    for(int i = 0; i < uniqueValues.length; i++) {
        uniqueValues[i] = n[i];
    }

    return uniqueValues;
}

//method for getting elements that has duplicates
public static int[] getDuplicatedElements(int[] n) {
    int[] nCopy = n.clone();
    int[] u = removeDuplicates(nCopy);
    int count = 0;
    int limit = u.length;

    for(int i = 0; i < u.length; i++) {
        for(int j = 0; j < n.length; j++) {
            if(u[i] == n[j]) {
                count++;
            }
        }

        if(count == 1) {
            for(int k = i; k < limit - 1; k++) {
                u[k] = u[k + 1];
            }
            limit--;
        }
        count = 0;
    }

    int[] duplicated =  new int[limit];
    for(int i = 0; i < duplicated.length; i++) {
        duplicated[i] = u[i];
    }

    return duplicated;
}

//main
public static void main(String[] args) {
    int[] num = {7, 2, 6, 1, 4, 7, 4, 5, 4, 7, 7, 3, 1};

    //printing original values
    System.out.print(Arrays.toString(num));
    System.out.println();


    int[] a = getDuplicatedElements(num);
    System.out.print("Elements with Duplicates: " + Arrays.toString(a)); 
}

What's the error in my codes here? Please help thanks...

robert
  • 249
  • 4
  • 11
  • 1
    Did you debug your application? – f1sh Feb 18 '19 at 10:20
  • 1
    Everytime I see multiple nested loops, I start to shiver. – MC Emperor Feb 18 '19 at 10:22
  • @Robert I think it is better to sort the cloned array first, then you can get threw in a linear way, if a variable is the same to the last one then you know it is a duplicate. – clankill3r Feb 18 '19 at 10:24
  • Or maybe use a HashSet? – clankill3r Feb 18 '19 at 10:25
  • @clankill3r as much as possible I want to do it with just ordinary arrays... Is that possible?? – robert Feb 18 '19 at 10:28
  • use `Arrays.sort(nCopy);`, forget the HashSet for now. This one is good practise. – clankill3r Feb 18 '19 at 10:32
  • @f1sh well, what I did is I tried to print how many times a an element has been found. For example: `Element 7 is 3 times found` `Element 2 is 1 times found` and so on... and if the counter is just equal to one then it will be removed in the arrays – robert Feb 18 '19 at 10:32
  • If you wan't that I would go for a `HashMap` where the key is the number and the value is how many times you found it. – clankill3r Feb 18 '19 at 10:34

2 Answers2

1

It's fairly simple when using a stream

int[] num = {7, 2, 6, 1, 4, 7, 4, 5, 4, 7, 7, 3, 1};
List<Integer> list = Arrays.stream(num).boxed().collect(Collectors.toList());
list.stream().filter(i -> Collections.frequency(list, i) > 1)
    .collect(Collectors.toSet()).forEach(System.out::println);
baao
  • 71,625
  • 17
  • 143
  • 203
1

You have two issues:

public static int[] getDuplicatedElements(int[] n) {
    int[] nCopy = n.clone();
    int[] u = removeDuplicates(nCopy);
    System.out.println ("unique " + Arrays.toString (u));
    int count = 0;
    int limit = u.length;

    for(int i = 0; i < limit; i++) { // you must use limit instead of u.length
                                     // in order for the loop to terminate
        for(int j = 0; j < n.length; j++) {
            if(u[i] == n[j]) {
                count++;
            }
        }

        if(count == 1) {
            for(int k = i; k < limit - 1; k++) {
                u[k] = u[k + 1];
            }
            limit--;
            i--; // you must decrement i after you find a unique element in u
                 // otherwise you'll be skipping elements in the u array
        }
        count = 0;
    }

    int[] duplicated =  new int[limit];
    for(int i = 0; i < duplicated.length; i++) {
        duplicated[i] = u[i];
    }

    return duplicated;
}

With those fixes, you'll get the expected output:

Elements with Duplicates: [7, 1, 4]
Eran
  • 387,369
  • 54
  • 702
  • 768