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 включительно. Я могу генерировать случайные целые числа, но проблема, которую я имею, - это проверка уникальности. Моя попытка проверить уникальность содержится в моем коде выше, но массив по-прежнему содержит дубликаты целых чисел. Что я делаю не так и может ли кто-нибудь дать мне подсказку?
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; }Уточнение ответа Картика.
Comments