Форум: "Потрепаться";
Текущий архив: 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