1

Hi so I am supposed to count the number of unique elements after an array sort excluding duplicates but i'm getting the wrong output.

In in = new In(args[0]);
int[] whitelist = in.readAllInts();
Arrays.sort(whitelist);

int count = 0;
   for (int i = 0; i < whitelist.length; i++) {
       if (whitelist[i] == whitelist[count]) {
           count++;
       }
   }
while (!StdIn.isEmpty()) {
    int key = StdIn.readInt();
    rank(key, whitelist);
}
   System.out.println(count);

} }

expected output: java InstrumentedBinarySearch tinyW.txt < tinyT.txt

65

got: 16

Did i count the number of duplicates or something?

WallyWest
  • 5
  • 1
  • 5

3 Answers3

0
  int flag = 0;
  int count = 0;
       for (int i = 0; i < whitelist.length; i++) //Element to be checked for
  {
           for (int j=0; j< whitelist.length ; j++) //Loop that goes through the whole array 
       {
               if (whitelist[i] == whitelist[j]) //checks if there are duplicates
               {
                   flag++; // count
               }
       }
    if( flag==1) //There should be only 1 instance of the element in the array and that is the element itself
    { 
       System.out.println(whitelist[i]); //displays unique element
       count++; // Keeps count 
    }
 }
Augmented Jacob
  • 1,567
  • 19
  • 45
  • This was my answer before you edited the question. This code will find the unique elements in an array. – Augmented Jacob Feb 18 '15 at 03:08
  • I've added the comments to explain each line. the OPs code uses whitelist[count] which makes no sense since the count is the number of duplicates count, and it does not browse through the rest of the array the same way j variable works in my code. Hope it helps. – Augmented Jacob Feb 18 '15 at 03:13
  • this method is giving me the answer 10 instead of 65 – WallyWest Feb 18 '15 at 03:23
0

This algorithm counts how many different unique numbers there are in the array. A number appearing more than once will only count for 1. I am assuming this is what you mean, as opposed to "numbers which appear exactly once".

There is a more trivial way to do it, as proposed in another answer, but it requires a nested for-loop and therefore executes in quadratic complexity. My algorithm below attempts to solve the problem in linear time proportional to the array size.

int uniquesFound = 0;

// Assume that array is sorted, so duplicates would be next to another.
// If we find duplicates, such as 12223, we will only count its last instance (i.e. the last '2')
for (int i = 0; i < whitelist.length; i++) {

    // If we are at the last element, we know we can count it
    if (i != whitelist.length - 1) {
        if (whitelist[i] != whitelist[i+1]) {
            uniquesFound++;
        }
        else {
            // Nothing! If they are the same, move to the next step element
        }
    } else {
        uniquesFound++;
    }
}

For instance, given the array:

{1,2,3} this will yield 3 because there are 3 unique numbers

{1,2,3,3,3,4,4,4,5} this will yield 5 because there are still 5 unique numbers

iFytil
  • 459
  • 3
  • 7
  • to be more clear, im supposed to remove the duplicate keys in the whitelist after the sort. So the number of keys examined should be smaller than when the duplicates weren't removed in which according to your logic it seems correct. But its not producing any results, just blank – WallyWest Feb 18 '15 at 03:39
  • If your sorting step also happens to remove duplicate keys, then the number of unique items is simply equal to the length of the array. This is because if you remove duplicate keys, the only thing left in the array are unique numbers. – iFytil Feb 18 '15 at 03:46
  • How do i print the number of unique keys in this case? – WallyWest Feb 18 '15 at 04:00
  • If you're telling me that whitelist is sorted and has been stripped of all duplicate keys, then the number of unique keys is the length of the whitelist array. Just print whitelist.length. If you're still confused, why don't you give me an example and tell me what is in whitelist and what the answer should be. – iFytil Feb 18 '15 at 04:11
  • thats weird your solution is giving me the same answer as the one i have posted. – WallyWest Feb 18 '15 at 04:23
  • Could you provide an example? Tell me what is inside whitelist, what the actual result is and what the expected result is. – iFytil Feb 18 '15 at 04:25
  • Well it I am supposed to read numbers from the file TinyT.txt which contains the numbers {23,50,10,99,18,23,98,84,11,10,48,77,13,54,98,77,77,68} and add those numbers to the list contained in TinyW.txt { 84, 48 ,68, 10, 18, 98, 12, 23, 54, 57, 48, 33, 16, 77, 11, 29. I've checked the duplicates myself and removed them and the number of unique results is 18 but the expected result is 65. I'm not too sure what whitelist contains because i assume it is the combination of both files – WallyWest Feb 18 '15 at 04:51
  • How can the number of unique items be 65 if there are not even 65 numbers in the sum of both of your files? – iFytil Feb 18 '15 at 04:53
0

First let's take a look at your loop:

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

You should be comparing consecutive elements in the list, like whitelist[0] == whitelist[1]?, whitelist[1] == whitelist[2]?, whitelist[3] == whitelist[4]?, etc. Doing whitelist[i] == whitelist[count] makes no sense in this context.

Now you have two options:

a. Increment your counter when you find two consecutive elements that are equal and subtract the result from the total size of the array:

for (int i = 0; i < whitelist.length - 1; i++) {
    if (whitelist[i] == whitelist[i + 1]) {
        count++;
    }
}
int result = whitelist.length - count;

b. Change the condition to count the transitions between consecutive elements that are not equal. Since you are counting the number of transitions, you need to add 1 to count in the end to get the number of unique elements in the array:

for (int i = 0; i < whitelist.length - 1; i++) {
    if (whitelist[i] != whitelist[i + 1]) {
         count++;
    }
}
int result = count + 1;

Note that, in both cases, we loop only until whitelist.length - 1, so that whitelist[i + 1] does not go out of bounds.

Anderson Vieira
  • 8,919
  • 2
  • 37
  • 48