2016-07-28 4 views
1

Я знаю, что подобный вопрос был задан раньше, но медведь со мной.Как генерировать случайные числа из массива без повторения?

У меня есть массив:

int [] arr = {1,2,3,4,5,6,7,8,9}; 

Я хочу цифры, которые будут генерироваться случайным образом 10 раз. Что-то вроде этого:

4,6,8,2,4,9,3,8,7 

Хотя некоторые числа повторяются, число раз больше, чем один раз подряд. Так что не так:

7,3,1,8,8,2,4,9,5,6 

Как видите, номер 8 повторяется сразу после его создания. Это не желаемый эффект.

Так что, в общем, я в порядке с повторением числа, если оно не появляется более одного раза подряд.

+1

Покажите нам некоторый код. Что вы пробовали, и с какими проблемами вы столкнулись? –

+0

Эта проблема называется «случайная выборка без замены». Он хорошо изучен. – AShelly

+0

@ Осторожно: кроме того, здесь не проблема. Вопрос, который вы говорите, - это дубликат, который хочет повторить номер. Проблема OP заключается в том, чтобы просто не повторять заданное число два раза подряд, но вы могли бы законно создавать «8, 4, 8». Я бы не удивился, если бы это был дубликат, но это не тот, который вы связывали при закрытии в качестве дубликата. – ShadowRanger

ответ

1
  • Создать произвольное число.
  • Сравните это с последним номером, который вы создали
  • Если это то же самое; отбросить его
  • Если он отличается, добавить его в массив
  • Вернуться к шагу 1 до тех пор, пока достаточное количество номеров
1
  1. генерировать случайный индекс в массиве.

  2. повторяйте, пока он не отличается от последнего используемого индекса.

  3. вывести значение, соответствующее этому индексу, из массива.

  4. повторите с самого начала, пока у вас не будет столько цифр, сколько вам нужно.

1

Хотя ответы размещены не плохо, и будет хорошо работать, кто-то может быть не доволен решением, как это возможно (жесткий невероятно маловероятно) для того, чтобы повесить, если вы генерировать достаточно длинную последовательность же номера.

алгоритм, который имеет дело с этой «проблемы», сохраняя при этом распределение чисел будет:

  • Выберите случайное число из исходного массива, давайте назовем его п и выводить его.
  • Сделать массив всех элементов, кроме n
  • Создать случайный индекс из более короткого массива. Переведите элемент по индексу с помощью n. Выход n.
  • Повторите последний шаг, пока не появится достаточное количество цифр.
+0

Вы можете пропустить копию на шаге 2, заменив элемент 'n' последним элементом, а затем выбрав элемент из диапазона' [0..size-1) ' – AShelly

0
int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9}; 
    int[] result = new int[10]; 
    int previousChoice = -1; 

    int i = 0; 
    while (i < 10) { 
     int randomIndex = (int) (Math.random() * arr.length); 
     if (arr[randomIndex] != previousChoice) { 
      result[i] = arr[randomIndex]; 
      i++; 
     } 
    } 
0

Решения приведены до сих пор все включают непостоянную работу каждого поколения; если вы повторно генерируете индексы и проверяете повторение, вы могли бы, вероятно, генерировать один и тот же индекс много раз, прежде чем, наконец, получить новый индекс. (Исключение составляет Kiraa's answer, но это связано с большими постоянными издержками для создания копий частичных массивов)

Лучшее решение здесь (если вы хотите уникальные индексы, а не уникальные значения и/или что исходный массив имеет уникальные значения) состоит в том, чтобы цитировать индексы, чтобы вы всегда генерировали новый индекс в (низком) постоянном времени.

В принципе, вы бы иметь с петлей, как это (с использованием Python для языка в основном для краткости):

# randrange(x, y) generates an int in range x to y-1 inclusive 
from random import randrange 

arr = [1, 2, 3, 4, 5, 6, 7, 8, 9] 
result = [] 
selectidx = 0 
randstart = 0 

for _ in range(10): # Runs loop body 10 times 
    # Generate offset from last selected index (randstart is initially 0 
    # allowing any index to be selected; on subsequent loops, it's 1, preventing 
    # repeated selection of last index 
    offset = randrange(randstart, len(arr)) 
    randstart = 1 

    # Add offset to last selected index and wrap so we cycle around the array 
    selectidx = (selectidx + offset) % len(arr) 

    # Append element at newly selected index 
    result.append(arr[selectidx]) 

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

Смежные вопросы