#java #алгоритм #случайные_числа
Есть числа с 0 по 23. Как сделать так, что бы при нажатии на кнопку генерировалось случайное число, которое не встречалось еще как минимум 2 раза?
Ответы
Ответ 1
Метод, не требующий повторной генерации, гарантирующий, что в каждой тройке последовательных чисел нет повтора (т.е. задачу я понимаю так же, как Kromster в комментарии) Ideone с ограничением 8, а не 24 (для более лёгкого контроля) int n = 8; final Random rnd = new Random(); int lastlast = rnd.nextInt(n); int last = (lastlast + 1 + rnd.nextInt(n - 1)) % n; for (int i = 0; i < 30; i++) { int r = (lastlast + 1 + rnd.nextInt(n - 2)) % n; if (r == last) r = (lastlast + n - 1) % n; lastlast = last; last = r; System.out.println(last); } Python версия с выводом гистограммы распределения для контроля равномерностиОтвет 2
Я понял твой вопрос как: "создать список из 24 рандомных(от 0 до 24) чисел, чтобы каждое число не повторялось более 2 раз". И действительно - два сета. В каждом уникальные числа от 0 до 24. Максимальное кол-во повторений - 2 раза на число. Просто доставайте отсюда(res) значения по необходимости. ArrayListfirst = new ArrayList<>(12); ArrayList second = new ArrayList<>(12); int randTemp; while(first.size()!=12){ randTemp=getMyRandMethod(); if(!first.contains(randTemp)){ first.add(randTemp); } } while(second.size()!=12){ randTemp=getMyRandMethod(); if(!second.contains(randTemp)){ second.add(randTemp); }; } ArrayList res = new ArrayList<>(24); for(int i=0;i<12;i++){ res.add(first.get(i)); res.add(second.get(i)); } Ответ 3
Реализация того что предложил товарищ @Kromster: public class Rand24 extends Random { LinkedListl = new LinkedList<>(); public synchronized int next24() { int result; do result = nextInt(24); while (l.contains(result)); l.add(result); if (l.size() == 3) l.removeFirst(); return result; } } Вариант похитрее, в нем отсутствует повторная генерация и в целом код понятнее: В листе лежат 24 возможных значения, берем случайное из диапазона 0-21 и перемещаем его в конец листа. Недостаток - заранее исключены 2 числа, ситуацию можно слегка улучшить расставив элементы в исходном массиве не по порядку. public class Rand24_2 extends Random { List values = IntStream.range(0, 24).boxed().collect(Collectors.toList()); public synchronized int next24() { int rnd = values.remove(nextInt(values.size() - 2)); values.add(rnd); return rnd; } } https://ideone.com/ Ответ 4
Вот еще 1 вариант Здесь, вы в Map вносите свое число, как ключ, а в качестве значения количество его выводов. Если у вас допустимо, чтобы число повторялось 2 раза ставьте maxCount = 3 public void rand() { Mapmap = new HashMap<>(); int maxCount = 2; while (true) { int number = new Random().nextInt(23); if (!map.containsKey(number)) { map.put(number, 1); showNumber(number); break; } else { Integer value = map.get(number); if (value < maxCount) { showNumber(number); } else { value++; map.put(number, value); } } } } private void showNumber(int number) { System.out.println(number); } Ответ 5
Могу предложить такой вариант public final class RandomGenerator { private final int[] numbers; private int size; public RandomGenerator(int size) { numbers = new int[size]; for (int i = 0; i < numbers.length; i++) numbers[i] = i; this.size = size; } private static void swap(int[] array, int i1, int i2) { int value = array[i1]; array[i1] = array[i2]; array[i2] = value; } public synchronized int getNumber() { if (size == 0) size = numbers.length; int index = ThreadLocalRandom.current().nextInt(size); int value = numbers[index]; size--; swap(numbers, size, index); return value; } }
Комментариев нет:
Отправить комментарий