-1

It's been asked before, I know, but I really don't know why my code isn't working. I'm trying to figure out how many unique values are in an undefined array. (i.e. {0, 0, 1, 1, 1, 5, 5, 6, 6, 7} should return a value of 5. This is what I have so far:

public static int numUnique(double[] list) {
    int counter = 0;
    
    for(int i = 0; i < list.length; i++) {
        for(int j = i + 1; j < list.length; j++) {
            if(list[i] != list[j])
                counter ++;
        }
    }
    
    
    return counter;
}
Unmitigated
  • 76,500
  • 11
  • 62
  • 80
Ulises Pico
  • 27
  • 1
  • 4

2 Answers2

7

Assuming that the array is sorted, you should only be checking if each element is not equal to the element immediately after it. The counter should also be initialized to 1 since if all elements are the same, the number of unique elements is 1. We also need to add a check for a null or empty array, for which the result is 0. (If it isn't sorted, you could use Arrays.sort to sort it, but that is not the fastest method.)

public static int numUnique(double[] list) {
    if(list == null || list.length == 0) return 0;
    int counter = 1;
    
   for(int i = 1; i < list.length; i++)
       if(list[i - 1] != list[i]) ++counter;
    
    
    return counter;
}

Alternate methods include using Stream#distinct or a Set, which do not rely on order*.

System.out.println(java.util.Arrays.stream(array).distinct().count());

or

System.out.println(java.util.stream.IntStream.of(array).distinct().count());

* LinkedHashSet implementation provides you with predictable iteration order.

Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110
Unmitigated
  • 76,500
  • 11
  • 62
  • 80
2

If the input array is sorted as in your example, you do not need a nested loop:

public static int numUnique (double[] list) {
    if (null == list || 0 == list.length) {
        return 0;
    }
    int counter = 1;
    
    for (int i = 1; i < list.length; i++) {
        if (list[i] != list[i - 1]) {
            counter ++;
        }
    }
    
    
    return counter;
}

It is possible to use Stream API, functions distinct and count to achieve the same result (input array does not need to be sorted then):

public static int numUniqueStream (double ... list) {
    if (null == list) {
        return 0;
    }
    return (int) Arrays.stream(list).distinct().count();
}
Nowhere Man
  • 19,170
  • 9
  • 17
  • 42