Java массив уникальных случайно сгенерированных целых чисел



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;
}

У меня есть метод выше, который должен генерировать массив случайных элементов, которые пользователь указывает. Случайно сгенерированные целые числа должны быть от 0 до 10 включительно. Я могу генерировать случайные целые числа, но проблема, которую я имею, - это проверка уникальности. Моя попытка проверить уникальность содержится в моем коде выше, но массив по-прежнему содержит дубликаты целых чисел. Что я делаю не так и может ли кто-нибудь дать мне подсказку?

140   6  

6 ответов:

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!
        }
    }   
}

Вы находите повторяющиеся значения. Однако вы заменяете его другим случайным числом, которое может быть дубликатом. Вместо этого попробуйте сделать следующее:

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;
        }
    }  
}
Однако этот метод неэффективен. Я рекомендую составить список чисел, а затем рандомизировать его:
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

Или вы можете сделать это:

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()));
}

Если у вас есть дубликат, вы только один раз регенерируете соответствующее число. Но это может создать еще один дубликат. Дубликат кода проверки должен быть заключен в цикл:

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;
}   
Но убедитесь, что size меньше, чем 10, иначе вы получите бесконечный цикл.

Edit : хотя описанный выше метод решает проблему, он не эффективен и не должен использоваться для массивов большого размера. Кроме того, это не имеет гарантированной верхней границы для числа итерации нужно было закончить.

Лучшим решением (которое, к сожалению, решает только второй пункт) может быть создание последовательности различных чисел, которые вы хотите создать (числа 10), произвольно перестановка этой последовательности, а затем выбрать только первые элементы этой последовательности size и скопировать их в свой массив. Вы обменяете некоторое пространство на гарантию в пределах времени.
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];

Или, вы можете создать ArrayList с теми же числами и вместо среднего цикла вы можете позвоните по нему Collections.shuffle(). Тогда вам все равно понадобится третий цикл, чтобы получить элементы в a.

Может оказаться быстрее начать с последовательного массива и перетасовать его. Тогда все они будутуникальны по определению .

Взгляните на случайное перетасование массива и на коллекции.функция shuffle.

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

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

Если вы просто не хотите платить за добавленные накладные расходы в ArrayList, вы можете просто использовать массив и использовать 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;
}

Приведенный выше код производит последовательные целые числа numElements, без дублирования в равномерно случайном перемешанном порядке.

 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]);
    }
}
}

Введите свой размер и получите список случайных уникальных чисел, используя коллекции.

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;
}

Уточнение ответа Картика.

    Ничего не найдено.

Добавить ответ:
Отменить.