|
Вопрос # 3 313/ вопрос открыт / |
|
Здравствуйте, уважаемые эксперты!
Предыдущий вопрос слава богу решился, но есть еще один, имеется функция RANDOM(число). которая генерирует случайное число. А как сделать так чтобы это самое случайное число исключить из следующего рандома ? то есть имеется допустим 4 числа.
1
2
3
4
нужно их все по 1му разу рандомно использовать, то есть выпал случайно рандом на 4, и чтобы больше он его не вызывал... можно конечно вести запись вызванных чисел, например в массиве строчек
Stolbik:Array[0..1] of stringlist и вести в одном столбике числа, а во втором столбике использовалось ли число или нет, и если нет то использовать, и изменить во втором столбике число на то что использовалось, если оно уже использовалось, то продолжить рандом.. то есть:
1|no не исп. можно использовать
2|no не исп. можно использовать
3|yes исп. нельзя использовать, искать другой рандом...
4|no не исп. можно использовать
и если выпало допустим 4, то во втором столбике изменить no на yes... но мне кажется есть в сотни раз легче и быстрее способы, веть список чисел вероятно до 1 000 000 дойдет...
извините если вопрос очень глупый :-[
 |
Вопрос задал: BloodVIRUS (статус: Посетитель)
Вопрос отправлен: 22 октября 2009, 00:20
Состояние вопроса: открыт, ответов: 1.
|
Ответ #1. Отвечает эксперт: Вадим К
Здравствуйте, BloodVIRUS!
Да, с таким подходом к кодированию далеко не уедешь.
Данная задача относиться к классическим алгоритмическим задачам. Поищите трехтомник Кнута, эта задача кажется в третьем томе рассматривается.
А тут я расскажу о двух алгоритмах. Думаю, что и для миллиона будут работать хорошо.
Первый алгоритм основан на перемешивании. То есть берем массив нужной длины, заполняем его последовательно числами, а дальше начинаем перемешивать.
uses
Math, ...;
//.....
const n = 100;
var
a:array[1..n] of integer;
i:integer;
t,i1,i2, p:integer;
begin
for i := 1 to n do a[i] := i;
p := RandomRange(1000,2000);
for i :=1 to p do begin
i1 := RandomRange(1,n);
i2 := RandomRange(1,n);
t := a[i1];
a[i1] := a[i2];
a[i2] := t;
end;
//массив готов.
end;
второй алгоритм построен на заполнении массива и в некоторых случаях может работать очень долго (алгоритм потенциально может зацикливаться!). Привожу набросок, а доделать предлагаю самостоятельно.
for i:= 1 to n do a[i] := 0;
for i:= 1 to n do begin
repeat
x := RandomRange(1,n);
until a[x] <> 0;
a[x] := i;
end;
суть - мы генерируем случайное число, которое будет новым индексом и смотрим в табличку, не занято ли оно вообще. Если занято - пытаемся ещё раз. Исправленный алгоритм должен в случае занятого числа сделать поиск вперед до ближайшей свободной ячейки.
 |
Ответ отправил: Вадим К (статус: Академик)
Время отправки: 22 октября 2009, 00:49
|
Мини-форум вопроса
Мини-форум пуст.
Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.
|