AvP
AvP

Reputation: 359

Java Array of unique randomly generated integers

public static int[] uniqueRandomElements (int size) {

    int[] a = new int[size];

    for (int i = 0; i < size; i++) {
        a[i] = (int)(Math.random()*10);

        for (int j = 0; j < i; j++) {
            if (a[i] == a[j]) {
                a[j] = (int)(Math.random()*10);
            }
        }   
    }

    for (int i = 0; i < a.length; i++) {
        System.out.print(a[i]+" ");
    }
    System.out.println();
    return a;
}

I have a method above which should generate an array of random elements that the user specifies. The randomly generated integers should be between 0 and 10 inclusive. I am able to generate random integers but the problem I have is checking for uniqueness. My attempt to check for uniqueness is in my code above but the array still contains duplicates of integers. What am I doing wrong and could someone give me a hint?

Upvotes: 5

Views: 38183

Answers (10)

yuen26
yuen26

Reputation: 1028

You can try this solution:

public static int[] uniqueRandomElements(int size) {
    List<Integer> numbers = IntStream.rangeClosed(0, size).boxed().collect(Collectors.toList());
    return Collections.shuffle(numbers);
}

Upvotes: 0

user3171451
user3171451

Reputation:

//Initialize array with 9 elements
int [] myArr = new int [9];
//Creating new ArrayList of size 9
//and fill it with number from 1 to 9
ArrayList<Integer> myArrayList = new ArrayList<>(9);
    for (int i = 0; i < 9; i++) {
        myArrayList.add(i + 1);
        }
//Using Collections, I shuffle my arrayList
Collections.shuffle(myArrayList);
//With for loop and method get() of ArrayList
//I fill my array
for(int i = 0; i < myArrayList.size(); i++){
    myArr[i] = myArrayList.get(i);
    }

//printing out my array
for(int i = 0; i < myArr.length; i++){
    System.out.print(myArr[i] + " ");
        }

Upvotes: 0

David Mancera
David Mancera

Reputation: 1

    int[] a = new int [size];

    for (int i = 0; i < size; i++) 
    {
        a[i] = (int)(Math.random()*16); //numbers from 0-15
        for (int j = 0; j < i; j++) 
        {
            //Instead of the if, while verifies that all the elements are different with the help of j=0
            while (a[i] == a[j])
            {
                a[i] = (int)(Math.random()*16); //numbers from 0-15
                j=0;
            }
        }
    }

    for (int i = 0; i < a.length; i++)
    {
        System.out.println(i + ".   " + a[i]);
    }

Upvotes: 0

Tamer M. Abu Rass
Tamer M. Abu Rass

Reputation: 1

int[] a = new int[20];

for (int i = 0; i < size; i++) {
    a[i] = (int) (Math.random() * 20);

    for (int j = 0; j < i; j++) {
        if (a[i] == a[j]) {
            a[i] = (int) (Math.random() * 20); //What's this! Another random number!
            i--;
            break;
        }
    }
}

Upvotes: 0

Axay Prajapati
Axay Prajapati

Reputation: 811

Input your size and get list of random unique numbers using Collections.

public static ArrayList<Integer> noRepeatShuffleList(int size) {
    ArrayList<Integer> arr = new ArrayList<>();
    for (int i = 0; i < size; i++) {
        arr.add(i);
    }
    Collections.shuffle(arr);
    return arr;
}

Elaborating Karthik's answer.

Upvotes: 0

Sachin Choudhary
Sachin Choudhary

Reputation: 1

 import java.util.Scanner;
 class Unique
{
public static void main(String[]args)
{
    int i,j;
    Scanner in=new Scanner(System.in);
    int[] a=new int[10];
    System.out.println("Here's a unique no.!!!!!!");
    for(i=0;i<10;i++)
    {
        a[i]=(int)(Math.random()*10);
        for(j=0;j<i;j++)
        {
            if(a[i]==a[j])
            {
                i--;

            }
        }   
    }
    for(i=0;i<10;i++)
    {
        System.out.print(a[i]);
    }
}
}

Upvotes: 0

balajeerc
balajeerc

Reputation: 4098

If you just don't want to pay for the added overhead to ArrayList, you can just use an array and use Knuth shuffle:

public Integer[] generateUnsortedIntegerArray(int numElements){
    // Generate an array of integers
    Integer[] randomInts = new Integer[numElements];
    for(int i = 0; i < numElements; ++i){
        randomInts[i] = i;
    }
    // Do the Knuth shuffle
    for(int i = 0; i < numElements; ++i){
        int randomIndex = (int)Math.floor(Math.random() * (i + 1));
        Integer temp = randomInts[i];
        randomInts[i] = randomInts[randomIndex];
        randomInts[randomIndex] = temp;
    }
    return randomInts;
}

The above code produces numElements consecutive integers, without duplication in a uniformly random shuffled order.

Upvotes: 0

Justin
Justin

Reputation: 25297

for (int i = 0; i < size; i++) {
    a[i] = (int)(Math.random()*10);

    for (int j = 0; j < i; j++) {
        if (a[i] == a[j]) {
            a[j] = (int)(Math.random()*10); //What's this! Another random number!
        }
    }   
}

You do find the duplicate values. However, you replace it with another random number that may be a duplicate. Instead, try this:

for (int i = 0; i < size; i++) {
    a[i] = (int)(Math.random()*10);//note, this generates numbers from [0,9]

    for (int j = 0; j < i; j++) {
        if (a[i] == a[j]) {
            i--; //if a[i] is a duplicate of a[j], then run the outer loop on i again
            break;
        }
    }  
}

However, this method is inefficient. I recommend making a list of numbers, then randomizing it:

ArrayList<Integer> a = new ArrayList<>(11);
for (int i = 0; i <= 10; i++){ //to generate from 0-10 inclusive. 
                               //For 0-9 inclusive, remove the = on the <=
    a.add(i);
}
Collections.shuffle(a);
a = a.sublist(0,4);
//turn into array

Or you could do this:

ArrayList<Integer> list = new ArrayList<>(11);
for (int i = 0; i <= 10; i++){
    list.add(i);
}
int[] a = new int[size];
for (int count = 0; count < size; count++){
    a[count] = list.remove((int)(Math.random() * list.size()));
}

Upvotes: 19

Mihai Maruseac
Mihai Maruseac

Reputation: 21435

If you have a duplicate you only regenerate the corresponding number once. But it might create another duplicate. You duplicate checking code should be enclosed in a loop:

while (true) {
    boolean need_to_break = true;
    for (int j = 0; j < i; j++) {
        if (a[i] == a[j]) {
            need_to_break = false; // we might get another conflict
            a[j] = (int)(Math.random()*10);
        }
    }
    if (need_to_break) break;
}   

But make sure that size is less than 10, otherwise you will get an infinite loop.

Edit: while the above method solves the problem, it is not efficient and should not be used for large sized arrays. Also, this doesn't have a guaranteed upper bound on the number of iterations needed to finish.

A better solution (which unfortunately only solves second point) might be to generate a sequence of the distinct numbers you want to generate (the 10 numbers), randomly permute this sequence and then select only the first size elements of that sequence and copy them to your array. You'll trade some space for a guarantee on the time bounds.

int max_number = 10;
int[] all_numbers = new int[max_number];
for (int i = 0; i < max_number; i++)
    all_numbers[i] = i;

/* randomly permute the sequence */
for (int i = max_number - 1; i >= 0; i--) {
    int j = (int)(Math.random() * i); /* pick a random number up to i */

    /* interchange the last element with the picked-up index */
    int tmp = all_numbers[j];
    all_numbers[j] = a[i];
    all_numbers[i] = tmp;
}

/* get the a array */
for (int i = 0; i < size; i++)
    a[i] = all_numbers[i];

Or, you can create an ArrayList with the same numbers and instead of the middle loop you can call Collections.shuffle() on it. Then you'd still need the third loop to get elements into a.

Upvotes: 1

Karthik T
Karthik T

Reputation: 31952

It might work out faster to start with a sequential array and shuffle it. Then they will all be unique by definition.

Take a look at Random shuffling of an array, and at the Collections.shuffle function.

int [] arr = [1,2,3,.....(size)]; //this is pseudo code

Collections.shuffle(arr);// you probably need to convert it to list first

Upvotes: 2

Related Questions