| 
| 
 | Вопрос # 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
 
 |  
 Мини-форум вопросаМини-форум пуст. Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте. |