2

Can someone please explain why System.out.println("Doesn't repeat: "+a[i]); does not print anything?

import java.util.Arrays;
import java.util.Random;




public class Practice {


public static void main(String[] args) {
    int []a=new int[100];

    Random rand =new Random();
        for(int i=0;i<100;i++)
           {
        a[i]=rand.nextInt((100-1)+1)+1;

           }
    Arrays.sort(a);
        for(int i=0;i<100;i++)
           {
        System.out.print(a[i]+ " ");

           }
boolean flag;
    System.out.print(" ");
    System.out.print(" ");
    for(int i=0;i<100;i++)
    {
        flag=false;
        for(int j=0;j<100;j++) 
        {
            if(a[i]==a[j])
            {
            flag=true;
            break;
            }
        }
        if(flag==false)
        {
            System.out.println("Doesn't repeat: "+a[i]);
        }
    }       
}
}

I am getting only the current array of 100 elements and the lines with elements which doesn't appear twice or more don't show up.

Edit:

import java.util.Arrays;
import java.util.Random;




public class Practice {


    public static void main(String[] args) {
        int []a=new int[100];

        Random rand =new Random();
        for(int i=0;i<100;i++)
        {
            a[i]=rand.nextInt((100-1)+1)+1;

        }
        Arrays.sort(a);
        for(int i=0;i<100;i++)
        {
            System.out.print(a[i]+ " ");

        }
    boolean flag;
        System.out.print(" ");
        System.out.print(" ");
        for(int i=0;i<100;i++)
        {
            flag=false;
            for(int j=0;j<100;j++) 
            {

             if (i==j) {
                    continue;
                }
             else if(a[i]==a[j])
                {
                flag=true;
                break;
                }

            }
            if(flag==false)
            {
                System.out.println("Doesn't repeat: "+a[i]);
            }
        }

    }
}

For now this is the best I can get, but the code excludes equal elements even if they are the unique ones.

Mezja
  • 55
  • 7
  • 1
    The most likely cause is that `flag` is never false. It only takes one match for that to be the case. – Robert Harvey Jan 02 '19 at 18:44
  • 2
    `flag` will always end up being true, because `a[i] == a[j]` when `i == j`. – Andy Turner Jan 02 '19 at 18:45
  • @AndyTurner I added i==j, the code seems to work, but there is a problem, that the first element gets excluded even being the only number in the array, how can I fix it, that even the equal elements get to be checked? – Mezja Jan 02 '19 at 18:59

4 Answers4

2

You always check for a duplicate against its own position. Each nested loop iteration, i will equal j and you will find a "duplicate". The simplest fix to your current code is to test if i is not equal to j.

Additionally, because you've sorted the array, any duplicates will be found in consecutive positions. You only need to scan the array once, instead of 100 times, to find duplicates. Just store what the previous value was so you can see if the current element is a duplicate.

You should be getting many elements that are not duplicates, but not all of them. On populating the last (100th) random element, even if all 99 integers chosen previously were unique, there is only a 1 in 100 chance of picking the only unchosen integer to prevent a duplicate. Before that, on the 99th random element, there would be only a 2 in 100 chance of picking one of the 2 unchosen integers to prevent a duplicate, and so on for each chosen integer. If you do get a line printed for all elements, then you should have played the lottery instead.

In case you wanted all unique elements, then initialize the values sequentially, then shuffle them.

rgettman
  • 176,041
  • 30
  • 275
  • 357
1

Change

for (int j = 0; j < 100; j++) // ends up comparing a number with itself as well

to

 for (int j = i+1; j < 100; j++) // compares with the rest of the elements ahead of it
Naman
  • 27,789
  • 26
  • 218
  • 353
1

Since you are sorting an array already, you need to check the repeating element from i+1(i.e, j) And Also Of you are having more than 1 repeating element you need to skip those elements using while loop as

                    while(j<100 && a[i] == a[j]) { // skip all repeating items
                        j++;
                    }
                    i=j-1;

The code is as below

    for (int i = 0; i < 100; i++) {
        flag = false;
        int j = i + 1;
        if (j<100 && a[i] == a[j]) {
            flag = true;
            while (j < 100 && a[i] == a[j]) { // skip all repeating items
                j++;
            }
            i = j - 1;// Because for loop is incrementing by again
        }
        if (flag == false) {
            System.out.println("Doesn't repeat: " + a[i]);
        }
    }
Naghaveer R
  • 2,890
  • 4
  • 30
  • 52
  • @Mezja Edited. Added this i=j-1;//Because for loop is incrementing by again – Naghaveer R Jan 02 '19 at 19:42
  • @Mezja Even you don't need 2 for-loops here. You can do it single for-loop – Naghaveer R Jan 02 '19 at 19:51
  • For now it is not so important to optimize this code, but later I will come back to it and I will try to optimize it the best way I can, for now, I just need a solution which I can use in exam. – Mezja Jan 02 '19 at 20:04
1

I made some changes to your code (removed flag and use unique as it is more readable).
Also I added an inner loop that modifies i, to the last index that contains a non unique item:

boolean unique;
System.out.println();
for (int i = 0; i < 100; i++) {
    unique = true;
    for (int j = i + 1; j < 100; j++) {
        if (a[i] == a[j]) {
            unique = false;
            break;
        }
    }
    if (unique) {
        System.out.println("Doesn't repeat: " + a[i]);
    } else {
        for (int k = i + 1; k < 100; k++) {
            if (a[k] != a[i]) {
                i = k - 1;
                break;
            }
        }
    }
}
forpas
  • 160,666
  • 10
  • 38
  • 76