Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 06.03.2009, 20:13
эмф эмф вне форума
Прохожий
 
Регистрация: 06.03.2009
Сообщения: 3
Репутация: 10
По умолчанию подскажите с масивом

Здравствуйте!
вот такой вопрос.
на форме мемо и кнопка,
при нажатие на кнопку, мемо заполнятеся пятью числами, по строчкам, которые не должны быть равны нули и между собой.
вот, что я смог :
Код:
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  
Старый 06.03.2009, 20:35
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,034
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Я правильно понимаю, что тебе надо заполнить 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  
Старый 06.03.2009, 21:05
эмф эмф вне форума
Прохожий
 
Регистрация: 06.03.2009
Сообщения: 3
Репутация: 10
По умолчанию

задачу для себя ставил такую, чтобы мемо заполнялась по строчкам n числом чисел, тоесть - пять строчек, 5 чисел,но чтобы небыло 0 и совпадающих чисел, например:
опять же берём пять строчек, но в каждой строчке рандом из 30, и если число в првой строчке будет равно, дапустим, числу из четвёртой строчки, то пересчёт рандома, чтобы числа не были равны между собой.
я попробывал ваш алгоритм, но выходит, что числа в строчках повторяются, и нули проскакивают)
Ответить с цитированием
  #4  
Старый 06.03.2009, 23:22
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,034
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

пробовал алгоритм или код?
по моему коду ни нулей, ни повторяющихся чисел быть не должно.
Ответить с цитированием
  #5  
Старый 07.03.2009, 12:56
Аватар для s0Creator
s0Creator s0Creator вне форума
Местный
 
Регистрация: 20.02.2008
Адрес: Московская область
Сообщения: 420
Репутация: 884
По умолчанию

Код:
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  
Старый 07.03.2009, 20:32
эмф эмф вне форума
Прохожий
 
Регистрация: 06.03.2009
Сообщения: 3
Репутация: 10
По умолчанию

2 s0Creator
Спасибо, работает! сейчас попробую осознать проиходящее)

2 lmikle
извеняюсь, код! код попробывал)
Ответить с цитированием
  #7  
Старый 07.03.2009, 22:47
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,034
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Врете вы все. Только что проверил свой код. Там не хватает одной скобки и ссылки при адресации мемо на форму, а в остальном все работает как часы. Дает список из N чисел в произвольном порядке.
Ответить с цитированием
  #8  
Старый 08.03.2009, 14:46
Аватар для s0Creator
s0Creator s0Creator вне форума
Местный
 
Регистрация: 20.02.2008
Адрес: Московская область
Сообщения: 420
Репутация: 884
По умолчанию

Цитата:
Сообщение от lmikle
Врете вы все. Только что проверил свой код. Там не хватает одной скобки и ссылки при адресации мемо на форму, а в остальном все работает как часы. Дает список из N чисел в произвольном порядке.
lmikle не кипятись - работает твой код. Только он расставляет числа [1..N] в случайном порядке, а у меня заполняет K строк числами [1..N] в случайном порядке.
(немного переделал твою и свою):
Код:
// расстановка 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;
Убрал Low(AList) - здесь всегда = 0
и High(AList) = N - 1

Ответить с цитированием
  #9  
Старый 08.03.2009, 15:04
Аватар для s0Creator
s0Creator s0Creator вне форума
Местный
 
Регистрация: 20.02.2008
Адрес: Московская область
Сообщения: 420
Репутация: 884
По умолчанию

Причем процедура 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;
  ............
Кстати, на форуме случайно нет раздела где бы складывались такие вот процедурки - типа местной библиотеки?
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 19:54.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter