![]() |
![]() |
#1 |
Участник
Регистрация: 15.07.2008
Сообщений: 197
Репутация: 313
|
![]()
Псевдослучайная последовательность без повторов элементов.
Иногда возникает необходимость получить псевдослучайную последовательность без повторов получаемых элементов. Предлагаю Вашему вниманию один из простых способов получения необходимого результата, которым я пользуюсь много лет. Хочу сразу сказать, что его я нашёл в одной из книг по программированию(за давностью лет, уже не помню в какой) и на авторство не претендую. Пример будет написан на языке программирования Pascal, но перевести его на другой язык программирования, я думаю, не составит большого труда. В примере мы получим последовательность целых положительных чисел, но применять способ можно для любых типов данных. Итак, приступим. Зададим количество получаемых чисел. Пусть мы хотим получить 10 чисел из диапазона 1..10. Код:
const NumCount=10; Код:
var RandAr: array[1..NumCount] of Cardinal; i, j, n: Cardinal; Теперь проинициализируем массив. Код:
for i:=1 to NumCount do RandAr[i]:=i; А теперь перемешаем массив чисел в псевдослучайном порядке. Код:
Randomize; for i:=1 to (NumCount-1) do begin j:=Random(NumCount-i+1)+i; n:=RandAr[i]; RandAr[i]:=RandAr[j]; RandAr[j]:=n; end; Несколько замечаний. 1. В примере использован статический массив, но современные диалекты языка позволяют использовать и динамический массив, что оказывается очень удобно, когда число элементов заранее неизвестно и определяется в ходе выполнения программы. 2. Если Вам нужна последовательность начинающееся с 0, то вместо Код:
for i:=1 to NumCount do RandAr[i]:=i; Код:
for i:=1 to NumCount do RandAr[i]:=i-1; Само собой разумеется, что массив можно заполнить любыми числами, псевдослучайную последовательность которых Вы хотите получить на выходе. Для этого, например, можно инициализировать массив в тексте программы или прочитать числа с любого устройства ввода. 3. Можно создать массив любого типа и, перемешав его, получить, соответственно, псевдослучайную последовательность любых данных. Однако для этого можно применить более эффективный, в некоторых случаях, способ, описанный ниже. 4. В некоторых случаях перемешивание можно ускорить, проверяя соотношение переменных i и j и, в случае их равенства пропускать перестановку. Это может оказаться выгодно в случае применения замечания номер 3. 5. Если элементы данных имеют размер больше Cardinal(например, строки), то, на мой взгляд, будет выгоднее с точки скорости работы программы создать дополнительный массив или список из этих элементов, а полученную в рабочем массиве псевдослучайную последовательность использовать в качестве индекса при обращении к дополнительному массиву(списку). О некоторых ограничениях метода. 1. Поскольку рабочий(ие) массив(ы) располагаются в оперативной памяти компьютера, то размеры псевдослучайной последовательности ограничены. Особенно это касается 32-х разрядных ОС. Если в Вашем компьютере не меньше 1 Гб ОЗУ, то разумным ограничением будет порядка 100 млн. 2. Перемешивание может занять существенное время. На медленных системах, при озвученном выше числе это может вылиться в несколько секунд. 3. Сам по себе встроенный генератор случайных чисел компилятора имеет ограничения. В случае необходимости - пользуйтесь самописным. (c)2011, Cepreu4. Оригинальная статья была написана для GraBBerZ.CoM При копировании ссылка на оригинал желательна. |
![]() |