Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Потрепаться";
Текущий архив: 2002.11.11;
Скачать: [xml.tar.bz2];

Вниз

Помогите! Прошу!   Найти похожие ветки 

 
Нужна помощь!!!   (2002-10-14 16:18) [0]

Уважаемые мастера Delphi! Помогите кому не лень мне с такой ужасной и в то же время простой задачей.

Необходимо 5 разным переменным (RandomNum1, RandomNum2, RandomNum3, RandomNum4, RandomNum5)придать 5 разных значений. Причём надо сделать так чтоб они все были произвольными и в то же время разные.

Одна из этих переменных, в зависимости от флага (flag) должна принять значение RandomNum, причём только одна она.
Для этого приходиться проверить все условия, при которых значения переменных не одинаковые.

Пишу такой код:


...

Flag:=Random(5);
If Flag=0 then
Begin
RandomNum1:=RandomNum; //если flag=0 тогда первая переменная принмает значение RandomNum
Repeat
RandomNum2:=Random(4); // все остальные должны быть произвольными
RandomNum3:=Random(4); // все остальные должны быть произвольными
RandomNum4:=Random(4); // все остальные должны быть произвольными
RandomNum5:=Random(4); // все остальные должны быть произвольными
Until (RandomNum2<>RandomNum)and(RandomNum3<>RandomNum)and(RandomNum4<>RandomNum)and(RandomNum5<>RandomNum)
and(RandomNum2<>RandomNum3)and(RandomNum2<>RandomNum4)and(RandomNum2<>RandomNum5)and(RandomNum3<>RandomNum4)
and(RandomNum3<>RandomNum5)and(RandomNum4<>RandomNum5) //повторяем это до тех пор, пока абсолютно все //переменные будут разными
End

Else If Flag=1 then
Begin
RandomNum2:=RandomNum;
Repeat
RandomNum1:=Random(4);
RandomNum3:=Random(4);
RandomNum4:=Random(4);
RandomNum5:=Random(4);
Until (RandomNum1<>RandomNum)and(RandomNum3<>RandomNum)and(RandomNum4<>RandomNum)and(RandomNum5<>RandomNum)
and(RandomNum1<>RandomNum3)and(RandomNum1<>RandomNum4)and(RandomNum1<>RandomNum5)and(RandomNum3<>RandomNum4)
and(RandomNum3<>RandomNum5)and(RandomNum4<>RandomNum5)
End
Else If Flag=2 then
Begin
RandomNum3:=RandomNum;
Repeat
RandomNum1:=Random(4);
RandomNum2:=Random(4);
RandomNum4:=Random(4);
RandomNum5:=Random(4);
Until (RandomNum1<>RandomNum)and(RandomNum2<>RandomNum)and(RandomNum4<>RandomNum)and(RandomNum5<>RandomNum)
and(RandomNum1<>RandomNum2)and(RandomNum1<>RandomNum4)and(RandomNum1<>RandomNum5)and(RandomNum2<>RandomNum4)
and(RandomNum2<>RandomNum5)and(RandomNum4<>RandomNum5)
End
Else If Flag=3 then
Begin
RandomNum4:=RandomNum;
Repeat
RandomNum1:=Random(4);
RandomNum2:=Random(4);
RandomNum3:=Random(4);
RandomNum5:=Random(4);
Until (RandomNum1<>RandomNum)and(RandomNum2<>RandomNum)and(RandomNum3<>RandomNum)and(RandomNum5<>RandomNum)
and(RandomNum1<>RandomNum2)and(RandomNum1<>RandomNum3)and(RandomNum1<>RandomNum5)and(RandomNum2<>RandomNum3)
and(RandomNum2<>RandomNum5)and(RandomNum3<>RandomNum5)
End
Else If Flag=4 then
Begin
RandomNum5:=RandomNum;
Repeat
RandomNum1:=Random(4);
RandomNum2:=Random(4);
RandomNum3:=Random(4);
RandomNum4:=Random(4);
Until (RandomNum1<>RandomNum)and(RandomNum2<>RandomNum)and(RandomNum3<>RandomNum)and(RandomNum4<>RandomNum)
and(RandomNum1<>RandomNum2)and(RandomNum1<>RandomNum3)and(RandomNum1<>RandomNum4)and(RandomNum2<>RandomNum3)
and(RandomNum2<>RandomNum4)and(RandomNum4<>RandomNum5)

End;

...



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

СПАСИБО!


 
Kaban   (2002-10-14 16:23) [1]

а вы слышали такое слово, как функция (процедура)?


 
Song   (2002-10-14 16:24) [2]

Да...


 
Нужна помощь!!!   (2002-10-14 16:29) [3]

Что-то слышал...
Но очень смутно.
Я вообще новичок в Delphi (около недели назад начал).
Допустим функция. И как здесь с ней???
Вы можете сократить код этот?


 
Kaban   (2002-10-14 16:35) [4]

Ну допустим,

function Check(Value1, Value2, Value3, Value4, Value5:Integer);
begin
// Сюда поместите то, что стояло в until
end;

procedure SetRandomValues(Value : Integer; var Value1, Value2, Value3, Value4, Value5 : Integer)
begin
repeat
Value1:=Value;
Value2:=Random();
Value3:=Random();
Value4:=Random();
Value5:=Random();
until Check(Value1, Value2, Value3, Value4, Value5);
end;

case Flag of
1:SetRandomValues(1, Value1, Value2, Value3, Value4, Value5);
2:SetRandomValues(1, Value2, Value1, Value3, Value4, Value5);
3:SetRandomValues(1, Value3, Value2, Value1, Value4, Value5);
4:SetRandomValues(1, Value4, Value2, Value3, Value1, Value5);
5:SetRandomValues(1, Value5, Value2, Value3, Value4, Value1);
end;


 
han_malign   (2002-10-14 16:36) [5]

примерно так, удаляя из банка значений уже использованные
const rv: array[0..4]of word=(0,1,2,3,4);
var RandomNum: array[0..4]of word;
i,j: integer;
...
begin
for i:=0 to 4 do begin
j:=Random(4-i);
RandomNum[i]:=rv[j];
if(j<(4-i))Move(rv[j+1],rv[j],(4-i)-j);
end;
end;


 
han_malign   (2002-10-14 16:38) [6]

упс - then пропустил - получилось как в сях


 
^Sanya   (2002-10-14 16:49) [7]

Рассчитаем вероятность того, что можно выбрать 4 числа в диапазоне [1..4] (так как одно уже выбрали), которые будут разными:

p-вероятность
m-количество удачных решений
n-общее количество комбинаций

p = m/n

m = 4! = 24
n = 4^4 = 256

p = 24/256 = 0,09375


Вероятность очень маааленькая...

Поэтому делай алгоритм по-другому...
Создавай множество выбираемых значений, из которых поэтапно вычёркиваются принятые RandomNumi-тыми переменными...
То есть, если ты уже попал в одну мишень, то снимай её, дабы случайно не попасть во второй(или 3-ий или 4-ый или...) раз.

Вот так вот я мыслю...


 
KSergey   (2002-10-14 17:28) [8]

Да..., пока отлаживал, много народ наклепал...
Тогда еще немного "улучшу", чтобы уж совсем ничего не разобрать было. ;)

Сначала первоначальый вариант. Работает точно.

procedure TMainForm.Button3Click(Sender: TObject);
var
Flag: Integer;
a: array[1..4] of Real;
i,j: Integer;
fl: Boolean;
RandomNum1, RandomNum2, RandomNum3, RandomNum4, RandomNum5: Real;
RandomNum: Real;
begin

procedure SetVal (I, Fl: Integer; var F: Float);
begin
if Fl = I then F := RandomNum
else
begin
if Fl < I then
end;
end;

RandomNum := -1; // ну надо же ее как-то инициализировать
// сначала сформируем массив точно разных случайных чисел
for i := 1 to 4 do // это цикл перебора эелемнтов массива,
begin // в который сечас будем вставлять очередное число
repeat // ну а в этом цикле крутимся до тех пор, пока
fl := True; // новое случ. число не будет равно предыдущим элементам массива
a[i] := Random(5); // вот оно собственно новое число
for j := 1 to i-1 do // переберем предыдущие элементы массива
if a[i] = a[j] then // на предмет проверки с тек. элементом; есди найдено
begin // совпадение с одним из предыдущих элеметов -
fl := False; // не дадим выйти из цикла repeat
break; // ну и выйдем из for j - нет смысла проверять остальные
end;
until fl;
end; // for i := 1 to 4 do
// ну а теперь присвоим значения из массива нашим выходным переменным
Flag := Floor(Random(5)); // приведем типы для порядку
i := 1; // начнем брать неповторяющиеся числа, начиная с 1-го элемента a[]
if Flag = 0 then // что там у нас во flag получилось?
RandomNum1 := RandomNum // присваиваем переменной либо предустановленную константу
else begin
RandomNum1 := a[i]; // либо ранее полученное случ. число из массива,
Inc(i); // тогда след. переменной надо будет уже взять значение след. элемента массива a[]
end;
if Flag = 1 then // ну и т.д.
RandomNum2 := RandomNum
else begin
RandomNum2 := a[i];
Inc(i);
end;
if Flag = 2 then
RandomNum3 := RandomNum
else begin
RandomNum3 := a[i];
Inc(i);
end;
if Flag = 3 then
RandomNum4 := RandomNum
else begin
RandomNum4 := a[i];
Inc(i);
end;
if Flag = 4 then
RandomNum5 := RandomNum
else
RandomNum5 := a[i]; // ну а тут уже inc(i) не нужен - идти не за чем.

// для проверки что же мы там нагенерили такое - если интересно, конечно
ListBox1.Items.Clear;
ListBox1.Items.Add (FloatToStr(RandomNum1));
ListBox1.Items.Add (FloatToStr(RandomNum2));
ListBox1.Items.Add (FloatToStr(RandomNum3));
ListBox1.Items.Add (FloatToStr(RandomNum4));
ListBox1.Items.Add (FloatToStr(RandomNum5));
end;


 
KSergey   (2002-10-14 17:29) [9]


Ну а теперь несколько сокращенный - убраны "некрасивые" куча if из конца, хотя мне они больше навятся, чем эти хитрые нижеследующие выкрутасы с ф-цией. Хотя и короче явно. И даже работает.

procedure TMainForm.Button3Click(Sender: TObject);
var
Flag: Integer;
a: array[1..4] of Real;
i,j: Integer;
fl: Boolean;
RandomNum1, RandomNum2, RandomNum3, RandomNum4, RandomNum5: Real;
RandomNum: Real;

// я не буду вникать что это за ф-ция, кто хочет - поймет.
procedure SetVal (I, Fl: Integer; var F: Real);
// Ну Fl передаем для порядку, вообще-то это всегда перемнная Flag - можно и ее запользовать
begin
if Fl = (I-1) then F := RandomNum
else
begin
if Fl < I then Dec(I);
F := a[I];
end;
end;

begin
RandomNum := -1; // ну надо же ее как-то инициализировать
// сначала сформируем массив точно разных случайных чисел
for i := 1 to 4 do // это цикл перебора эелемнтов массива,
begin // в который сечас будем вставлять очередное число
repeat // ну а в этом цикле крутимся до тех пор, пока
fl := True; // новое случ. число не будет равно предыдущим элементам массива
a[i] := Random(5); // вот оно собственно новое число
for j := 1 to i-1 do // переберем предыдущие элементы массива
if a[i] = a[j] then // на предмет проверки с тек. элементом; есди найдено
begin // совпадение с одним из предыдущих элеметов -
fl := False; // не дадим выйти из цикла repeat
break; // ну и выйдем из for j - нет смысла проверять остальные
end;
until fl;
end; // for i := 1 to 4 do
// ну а теперь присвоим значения из массива нашим выходным переменным
Flag := Floor(Random(5)); // приведем типы для порядку
SetVal (1, Flag, RandomNum1);
SetVal (2, Flag, RandomNum2);
SetVal (3, Flag, RandomNum3);
SetVal (4, Flag, RandomNum4);
SetVal (5, Flag, RandomNum5);

// для проверки что же мы там нагенерили такое - если интересно, конечно
ListBox1.Items.Clear;
ListBox1.Items.Add (FloatToStr(RandomNum1));
ListBox1.Items.Add (FloatToStr(RandomNum2));
ListBox1.Items.Add (FloatToStr(RandomNum3));
ListBox1.Items.Add (FloatToStr(RandomNum4));
ListBox1.Items.Add (FloatToStr(RandomNum5));
end;


PS:
Вообще-то я всегда выступал "наезжальщиком" в плане "а как на счет самому подумать", но тут от нефиг делать...
А вообще-то есть такая штука, как отладчик, в котором вы бы, думаю, без труда нашли ошибку в вашем же коде, пусть и не очень коротком, это не важно. Так что лучше старайтесь думать своей головой... А то такого можете наполучать тут ;))


 
KSergey   (2002-10-14 17:32) [10]

Вот, елки, не уследил, пока с длиной сообщения боролся...

Разумеется, что кусок
procedure SetVal (I, Fl: Integer; var F: Float);
begin
if Fl = I then F := RandomNum
else
begin
if Fl < I then
end;
end;

в первом варианте не нужен вовсе, да с ним (в его приведенном местоположении) и не скомпилирует ;)


 
KSergey   (2002-10-14 17:35) [11]

И с комментариями поднакосячил

Вместо
repeat // ну а в этом цикле крутимся до тех пор, пока
fl := True; // новое случ. число не будет равно предыдущим элементам

следует читать
repeat // ну а в этом цикле крутимся до тех пор, пока
fl := True; // новое случ. число не будет уникальным (т.е. не равным всем предыдущим элементам)


 
TTCustomDelphiMaster   (2002-10-14 18:36) [12]

procedure SetVal(var r1, r2, r3, r4, r5: integer; flag, RandomNum: integer);
const
Rn: array [0..4] of integer = (0, 1, 2, 3, 4);
var
i, k, n: integer;
begin
for i := 0 to 4 do
begin
n := random(5);
k := Rn[n];
Rn[n] := Rn[i];
Rn[i] := k;
end;
for i := 0 to 4 do
if Rn[i] = RandomNum then
begin
k := Rn[flag];
Rn[flag] := Rn[i];
Rn[i] := k;
break;
end;
r1 := Rn[0];
r2 := Rn[1];
r3 := Rn[2];
r4 := Rn[3];
r5 := Rn[4];
end;

procedure TForm1.Button2Click(Sender: TObject);
var
r1, r2, r3, r4, r5, flag, rnum: integer;
begin
// Проверка
randomize;
flag := random(5);
rnum := random(5);
SetVal(r1, r2, r3, r4, r5, flag, rnum);
ShowMessage("flag="+inttostr(flag)+#13#10+
"R1="+inttostr(r1)+#13#10+
"R2="+inttostr(r2)+#13#10+
"R3="+inttostr(r3)+#13#10+
"R4="+inttostr(r4)+#13#10+
"R5="+inttostr(r5)+#13#10+
"Rnum="+inttostr(rnum));
end;


 
Нужна помощь!!!   (2002-10-14 18:48) [13]

Как много ответов!
Буду сегодня весь вечер разбирать!
Спасибо!
Вот это называется настоящий форум мастеров!


 
KSergey   (2002-10-15 08:52) [14]

Во, блин... Надо же ;)
А то тут некоторые говорят "Злые вы, просот злющие" ;)
Наверное, как вопрос поставлен ;)

Хотя вот как-нибудь бы без массива бы выкрутиться... Но чот-то сильно тогда заумные условия выходят.
А может по условию задачи достаточно просто все же в массиве все это оставить? По сути у всех так и вышло: формируется массив, а уже из него все так или иначе переписывается в выходные пременные...


 
Vit@ly   (2002-10-15 11:55) [15]

procedure TForm1.Button1Click(Sender: TObject);
Var N: Integer;
RandomNum: Array [0..9] of Integer;
RandomFlag: Array [0..9] of Boolean;
Label A;
begin
N:= ???; // естественно любое целое
For I:= 0 to N do RandomFlag[I]:= False;
For I:= 0 to N do RandomNum[I]:= 0;
Randomize;
For I:= 0 to N -1 do
begin
A: RandomNum[I]:= Random(N -1);
If RandomFlag[RandomNum[I]] = True Then GoTo A;
RandomFlag[RandomNum[I]]:= True;
end;
// лучше посмотреть в отладке, работает совершенно но последнее
// число может выбирать (случайным образом) очень долго.
// У меня в реальной задаче выбор неповторяющихся осуществляется:
// выбрать M из N при M < N
end;


 
Vit@ly   (2002-10-15 15:09) [16]

Опечатка:
Вместо For I:= 0 to N -1 do
Следует For I:= 0 to N do


 
Kaban   (2002-10-15 15:21) [17]

Последний вариант с "GoTo A" вообще сильный, давно не встречал


 
pahan_s   (2002-10-15 17:16) [18]

На Delph-ях было впадлу, вот примерный код на паскале.
где a - диапазон сл.чисел
Одно условие : а должно быть в пределах 0..255
Если что можно слегка переделать на любой

uses Crt;
const
a=4;
type
t1=integer;
t2=integer;
var
rnd : array[1..5] of word;
flag : word;
i : integer;
ss : set of 1..a;
Randomnum : word;
begin
writeln("Begin");
Randomnum:=99;
Randomize;
flag:=Random(5);
rnd[flag]:=Randomnum;
ss:=[rnd[flag]];
for i:=1 to 5 do
begin
if i<>flag then
begin
rnd[i]:=Random(a);
while rnd[i] in ss do
begin
rnd[i]:=Random(a);
end;
ss:=ss+[rnd[i]];
end;
end;
for i:=1 to 5 do
writeln(rnd[i]);
end.


 
TTCustomDelphiMaster   (2002-10-15 18:17) [19]

pahan_s

Оригинальный у вас подход. Будет программа работать или зависнет решает случай, а именно
while rnd[i] in ss do
rnd[i]:=Random(a);


 
Peter Gluhiy   (2002-10-15 18:51) [20]

Vit@ly (15.10.02 11:55)
>RandomNum: Array [0..9] of Integer;
>N:= ???; // естественно любое целое
>For I:= 0 to N do RandomNum[I]:= 0;
N не любое целое, а от 0 до 9.

Чуть-чуть подправил:
procedure TForm1.Button1Click(Sender: TObject);
Var n,i,j: Integer;
RandomNum: Array of Integer;
Flag: boolean;
begin
n := ???; // естественно любое целое
SetLength(RandomNum, n);
for i:=0 to n-1 do RandomNum[i]:=0;
Randomize;
i := 0;
while i < n do
begin
RandomNum[i] := Random(n);
Flag := false;
For j := 0 to pred(i) do
if RandomNum[j] = RandomNum[i] then
begin
Flag := true; // если совпадает с одним из предыдущих
break;
end;
if not Flag then inc(i);
end;
end;


 
AL2002   (2002-10-15 19:08) [21]

А мне кажется, достаточно:
While (R1=R2 Or R1=R3 Or R1=R4 ... R2=R3 Or R2=R4 Or Flag<>"ЁПРСТ") подбирать значения для рандомовых чисел.


 
TTCustomDelphiMaster   (2002-10-15 19:15) [22]

Ну вот опять

Интересно вы вставите в свою программу такой код
while Random(N) = N/2 do // N-любое целое

Нет? Так почему же вы подсовываете его начинающим. Представляете как будет "радоваться" пользователь ожидая пока программа перемешает ответы на очередной билет, когда время теста ограниченно.


 
Peter Gluhiy   (2002-10-15 19:28) [23]

TTCustomDelphiMaster © (15.10.02 19:15)
При n := 1000 меньше секунды нужно подождать.


 
AL2002   (2002-10-15 19:46) [24]

>TTCustomDelphiMaster © (15.10.02 19:15)
Как раз к первому вопросу как ответ это подходит.


 
TTCustomDelphiMaster   (2002-10-15 19:54) [25]

А так?
while Random(N) = N/2 do
sleep(1000);

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


 
Peter Gluhiy   (2002-10-15 20:12) [26]

Согласен. Каюсь. Больше так не буду :)


 
pahan_s   (2002-10-16 08:32) [27]

TTCustomDelphiMaster


Но речь ведь идет о случайных числах.
Кстати вы запускали код?
Число так называемых "зависаний" падает с увеличением диапазона
с.ч.
Данный подход, с моей точки зрения, может слегка оригенален но наиболее приближен к универсальному и главное прост.


 
TTCustomDelphiMaster   (2002-10-17 21:23) [28]

pahan_s

Запускал ли я код? Да запускал, но перед этим пришлось освободить его от ошибок. Во первых по условию задачи число переменных равно а. Во вторых значение Randomnum не произвольное, а входит в диапазон 0.. a-1. В третих ошибка при вычилении flag:=Random(5). У вас flag может быть равен 0.
Это все мелочи, а главное то, что такой алгоритм не эффективен при увеличении a. Давайте проверим сколько операций выполняется при различных значениях a и сравним хотя бы с моим алгоритмом. За одну операцию давайте примем один проход в цикле. Алгоритм с конечным числом операций (АсКЧО) предложенный мной предполагает от a+1 до 2 a операций. В вашем алгоритме минимум a операций. Максимум неизвестен. Вот и посмотрим чему же равен этот максимум и среднее количество операций из 10000 опытов.


-----------------------------------
|a | 5 | 10 | 50 | 100 | 150 |
|sr |11,4|29,3|224,6|516,9|840,1|
|max | 47 | 110| 666 | 1510| 2391|
|min | 5 | 10 | 89 | 243 | 397 |
-----------------------------------
|MyMax| 10 | 20 | 100 | 200 | 300 |
-----------------------------------

В этой таблице sr, max, min - среднее, максимальное и минимальное количество операций в вашем алгоритме. MyMax - максимальное количество операций в алгоритме с конечным числом операций. Из таблици видно, что ваш алгоритм в среднем уступает АсКЧО, но при малых a в некоторых случаях бывает в 2 раза эффективнее. При больших значениях a даже минимальное число операций превышает максимальное число операций АсКЧО. Ваш подход оригинален (или неоригинален) своей неэффективностью, ограниченностью (максимальное значение a 255) и нисколько не приближен к универсальному. Но действительно прост. Его можно рекомендовать для a<=3, но никак не для a=5.

function getsum():integer;
const
a=150;
var
rnd : array[1..a] of word;
flag : word;
i: integer;
ss : set of 1..a;
Randomnum : word;
begin
Result := a;
Randomnum:=2;
flag:=Random(a)+1;
rnd[flag]:=Randomnum;
ss:=[rnd[flag]];
for i:=1 to a do
if i<>flag then
begin
rnd[i]:=Random(a);
while rnd[i] in ss do
begin
rnd[i]:=Random(a);
inc(Result);
end;
ss:=ss+[rnd[i]];
end;
end;

procedure TForm1.Button4Click(Sender: TObject);
const
Ni = 10000;
var
s: Double;
i, min, max, n: integer;
begin
s := 0;
max := low(integer);
min := high(integer);
Randomize;
for i := 1 to Ni do
begin
n := getsum();
if n > max then
max := n;
if n < min then
min := n;
s := s + n;
end;
showmessage("sred="+floattostr(s/Ni)+#13#10+
"s="+floattostr(s)+#13#10+
"min="+inttostr(min)+#13#10+
"max="+inttostr(max));
end;


 
pahan_s   (2002-10-18 09:07) [29]

TTCustomDelphiMaster

Да, действительно flag=0 я недоглядел, но это мелочи
К универсальности его можно привести заменив проверку на in set
на чтото типа проверки на попадание в цикле.
Да цикл может закончится за 5 шагов, а может не закончится вообще, но на то она и есть сл.величина и всю вашу теорию случай может поставить на нет.
Кстати а как вы собираетесь заполнять массив rn при диапазоне с.в. допустим 0<=c.в.<255 (или более) и тем более добиваться уникальности. Не кажется ли вам что тогда все предложенное будет сводиться к одному общему принципу. Иначе сл.величина теряет свой смысл (хотя мне кажется что понятия сл.чило и коимпьютер несовместимы)


 
F1   (2002-10-18 13:33) [30]

А что если вот так, только могут быть глюки, но идея работает
procedure TForm1.SpeedButton2Click(Sender: TObject);
Var
MasVspom,Mas:Array[0..5] of Integer;
i,RandomIndex:Integer;
begin
//Заполняем дополнительный массив
for i:=0 to 5 do
MasVspom[i]:=i;
//Будем выкидывать то, что выбрали и выбирать из остатка
for i:=6 downto 1 do
begin
//Выбираем случайный индекс
RandomIndex:=Random(i);
Mas[i]:=MasVspom[RandomIndex];
//меняем
MasVspom[RandomIndex]:=MasVspom[i];
end;
end;


 
pahan_s   (2002-10-18 14:27) [31]

>F1

А почему сл.чисел 6?
Где выполнение условия
...
Одна из этих переменных, в зависимости от флага (flag) должна принять значение RandomNum, причём только одна она.
...
Что считать результатом?


 
k   (2002-10-18 16:01) [32]

сколько мнений осталось добавать свое :)

почему бы вместо значений (RandomNum1, RandomNum2, RandomNum3, RandomNum4, RandomNum5) не использовать массив?
так пусть
Nums:array[1..4] of integer - массив, состоящий из 4-х разных чисел (всегда)
получим его

var i,j,n:integer;
DejaVu:boolean;

for i:=1 to 4 do Nums[i]:=-1; //если элемент = -1 тогда он пустой


for i:=1 to 4 do
begin
repeat
n := random(4); //получаем значение
DejaVu := false;
for j:=1 to i-1 do
DejaVu := DejaVu or (Nums[j]= n);// перебираем,
// встречалось ли это значение раньше
until not DejaVu;
Nums[i]:=n;
end;

теперь асталось распихать их по (RandomNum1, RandomNum2, RandomNum3, RandomNum4, RandomNum5)

case flag of
0:begin
RandomNum1:=RandomNum;
RandomNum2:=Nums[1];
RandomNum3:=Nums[2];
RandomNum4:=Nums[3];
RandomNum5:=Nums[4];
end;
и т.д.
end;//case


 
pahan_s   (2002-10-18 17:25) [33]

>K

А что будет при в большом цикле при i=1, по моему он зациклится.


 
TTCustomDelphiMaster   (2002-10-18 21:10) [34]


> pahan_s (18.10.02 09:07)
> Кстати а как вы собираетесь заполнять массив rn при диапазоне
> с.в. допустим 0<=c.в.<255 (или более) и тем более добиваться
> уникальности. Не кажется ли вам что тогда все предложенное
> будет сводиться к одному общему принципу. Иначе сл.величина
> теряет свой смысл


Насчет заполнения массива не беспокойтесь. Существует много способов от массива
const
Rn: array [0..255] of integer = (0, 1, 2, 3, и т.д.,255);
до динамического массива.

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

Так вот есть два абсолютно разных метода решения этой задачи.

Первый заполнение массива случайными числами, что и предложило большинство участников обсуждения. При этом нужно генерировать случайное число, проверять его наличие среди сгенерированных ранее и помещать в массив. Способы проверки бывают разные. Вы предложили один из самых быстрых (но с ограничением в 256 элементов). Другой - создать массив логических элементов, и при получении случайного числа включать элемент массива с соответствующим номером. И наконец самый неоптимальный проверять все предыдущие элементы массива. Недостаток первого метода - невозможность сгенерировать сразу случайное число, которого нет в массиве, поэтому приходится выполнять лишние операции, количество которых неизвестно.

Второй метод заключается в перемешивании последовательности неповторяющихся чисел используя генератор случайных чисел. Причем неважно какая последовательность имеется упорядоченная или нет, в результате должен получиться ряд случайных чисел.

Так что нет никакого общего принципа и с уникальностью вроде все в порядке.


 
pahan_s   (2002-10-21 09:51) [35]

>TTCustomDelphiMaster

Все правильно, но второй метод сводится к первому при создании последовательности неповторяющихся чисел, когда число искомых велечин 5, а с.ч. лежит в диапазоне >5



Страницы: 1 вся ветка

Форум: "Потрепаться";
Текущий архив: 2002.11.11;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.58 MB
Время: 0.008 c
3-33866
Blunder
2002-10-18 21:22
2002.11.11
conversion from string


14-34201
Yuraz
2002-10-22 12:34
2002.11.11
Можно ли загрузить архив этого форума в zip за месяц?


1-33992
Sergi
2002-10-29 18:04
2002.11.11
Макроподстановка


3-33883
123000
2002-10-21 17:53
2002.11.11
Установка алиасов


1-33926
DVM
2002-10-31 10:25
2002.11.11
Сохранение содержимого ListView в реестре





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский