![]() |
|
|
|||||||
| Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
#1
|
|||
|
|||
|
Здравствуйте!
вот такой вопрос. на форме мемо и кнопка, при нажатие на кнопку, мемо заполнятеся пятью числами, по строчкам, которые не должны быть равны нули и между собой. вот, что я смог : Код:
procedure TForm1.Button1Click(Sender: TObject);
var
mass:array[1..5] of integer; //задал масив
i,j:integer;
s:string;
a,b:integer;
begin
memo1.Clear;
Randomize;
for i:=1 to 5 do
begin
a:=random(6);
mass[i]:=a; // заполнил рандомными числами
while mass[i]=0 do //сделал пересчёт, если появляется 0
begin
mass[i]:=random(6);
end;
end;
for j:=1 to 5 do //тут я пытаюсь пройтись по уже заполненому масиву
begin
while mass[j]=mass[j+1] do //пересчёт пока j-тый элемет масива равен j+1
begin
mass[j]:=random(6);
end;
memo1.Lines.Add(inttostr(mass[j])); // заполняем мемо
end;
end;у меня не получается пройтись по заполненому масиву, сравнив числа в нём между собой и повторную пересчитать. укажите пожайлуста мне на мои ошибки и что я не так понимаю !) п.с. извените, если оформел не по форме. Последний раз редактировалось эмф, 06.03.2009 в 20:26. |
|
#2
|
|||
|
|||
|
Я правильно понимаю, что тебе надо заполнить N числами ПОДРЯД, но в СЛУЧАЙНОМ ПОРЯДКЕ?
Тут такая фигня, что обычный метод генерации случайных чисел тут плохой помошник. Он может работать неопределенно долгое время, особенно при генерации последних чисел. Я бы предложил немного другой алгоритм. Есть массив 1..N, который надо заполнить числами 1..N в случайном порядке. в цикле от 1 до N мы генерим не сами числа, а их индексы в массиве. При этом, если ячейка уже занята, то не перегенерируем индекс, а сдвигаем его веред до первой свбодной ячейки с циклическим сдвигом (т.е. если после сгенерированного индекса нет ни одной свободной ячейки, то дальше начинаем искать место с начала массива). Итак: Код:
procedure GenerateList(N : Integer);
var
I, Idx : Integer;
AList : Array Of Integer;
begin
// Сначала делаем массив и инициализируем его нулями
SetLength(AList,N);
For I := Low(AList) To High(AList) Do
AList[i] := 0;
// Теперь начинаем заполнять массив
For I := 1 To N Do
Begin
Idx := Random(N);
If AList[Idx] = 0
Then AList[Idx] := I // ячейка и так пустая
Else // ячейка занята. ищем другое место
Begin
While AList[Idx] <> 0 Do
Begin
Inc(Idx);
If Idx > High(AList) Then Idx := Low(AList);
End;
AList[Idx] := I;
End;
End;
// Теперь выводим результат в мемо.
Memo1.Lines.Clear;
For I := Low(AList) To High(AList) Do
Memo1.Lines.Add(IntToStr(AList[i]);
end;На самом деле проверка на пустую ячейку не нужна, она добавлена для понятности алгоритма. Еще несколько замечаний: 1. Динамический массив всегда начинается с 0. 2. Random(N) возвращает случайное число от 0 до N-1. 3. При работе с массивами всегда лучше пользоваться функциями Low() и High(), возвращающими нижнюю и верхнюю границы массива. |
|
#3
|
|||
|
|||
|
задачу для себя ставил такую, чтобы мемо заполнялась по строчкам n числом чисел, тоесть - пять строчек, 5 чисел,но чтобы небыло 0 и совпадающих чисел, например:
опять же берём пять строчек, но в каждой строчке рандом из 30, и если число в првой строчке будет равно, дапустим, числу из четвёртой строчки, то пересчёт рандома, чтобы числа не были равны между собой. я попробывал ваш алгоритм, но выходит, что числа в строчках повторяются, и нули проскакивают) |
|
#4
|
|||
|
|||
|
пробовал алгоритм или код?
по моему коду ни нулей, ни повторяющихся чисел быть не должно. |
|
#5
|
||||
|
||||
|
Код:
procedure TForm1.Button1Click(Sender: TObject);
var
mass:array[1..5] of integer;
i,j:integer;
notchek: Boolean;
a:integer;
begin
memo1.Clear;
Randomize;
for i:=1 to 5 do
begin
notchek := true;
while notchek do
begin
a:=random(6);
if a <> 0 then
begin
notchek := false;
for j := 1 to i - 1 do
begin
notchek := (a = mass[j]);
if notchek then
break;
end;
end;
end;
mass[i] := a;
memo1.Lines.Add(inttostr(a));
end;
end; |
|
#6
|
|||
|
|||
|
2 s0Creator
Спасибо, работает! сейчас попробую осознать проиходящее) 2 lmikle извеняюсь, код! код попробывал) |
|
#7
|
|||
|
|||
|
Врете вы все. Только что проверил свой код. Там не хватает одной скобки и ссылки при адресации мемо на форму, а в остальном все работает как часы. Дает список из N чисел в произвольном порядке.
|
|
#8
|
||||
|
||||
|
Цитата:
(немного переделал твою и свою): Код:
// расстановка N чисел случайным порядком
procedure GenerateList(N : Integer; St: TStrings);
var
I, Idx, HIdx : Integer;
AList : Array Of Integer;
begin
St.Clear;
if N <= 0 then
Exit;
// Сначала делаем массив и инициализируем его нулями
SetLength(AList,N);
try
HIdx := N - 1;
For I := 0 To HIdx Do
AList[i] := 0;
// Теперь начинаем заполнять массив
For I := 1 To N Do
Begin
Idx := Random(N);
While AList[Idx] <> 0 Do
Begin
Inc(Idx);
If Idx > HIdx Then Idx := 0;
End;
AList[Idx] := I;
End;
// Теперь выводим результат.
For I := 0 To HIdx Do
St.Add(IntToStr(AList[i]));
finally
SetLength(AList, 0);
end;
end;
// заполнение K строк числами 1..N в случайном порядке
procedure FillList(K, N : Integer; St: TStrings);
var
mass:Array Of Integer;
i, j, HIdx:integer;
chek: Boolean;
a:integer;
begin
St.Clear;
if K <= 0 then
Exit;
if N < K then
raise Exception.Create('Диапазон [1..'+ IntToStr(N)+'] меньше количества строк ['+ IntToStr(K)+']');
SetLength(mass,K);
try
HIdx := K - 1;
for i := 0 to HIdx do
begin
repeat
chek := true;
a:=random(N) + 1;
for j := 0 to i - 1 do
begin
chek := not (a = mass[j]);
if not chek then
break;
end;
until chek;
mass[i] := a;
St.Add(inttostr(a));
end;
finally
SetLength(mass, 0);
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
FillList(5,30,Memo1.Lines);
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
GenerateList(5,Memo1.Lines);
end;и High(AList) = N - 1 |
|
#9
|
||||
|
||||
|
Причем процедура lmikle "GenerateList(N : Integer; St: TStrings);" хоть и является частным случаем моей "FillList(K, N : Integer; St: TStrings);"
(При K=N) работает в этом случае более эфективно, поэтому в мою можно добавить Код:
procedure FillList(K, N : Integer; St: TStrings);
var
....
begin
if K = N then
begin
GenerateList(N, St);
Exit;
end;
............ |