Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 12.07.2016, 22:03   #1
Janger
Форумчанин
 
Регистрация: 28.09.2011
Сообщений: 250
Смущение Помогите разобраться с рандомом

Я пишу код, пользователь вводит в Memo строки, нажимает на кнопку.
Программа, чётные строки убирает в один ListBox1, а нечётные убирает в другой ListBox2. Далее, строки в обоих ListBox-ах должны быть перемешаны (не по порядку идти).
Я написал код, вроде бы, всё более менее, НО у меня странный рандом получается, не могли бы мне с ним помочь?
Вот код на кнопке:
Код:
procedure TForm1.Button1Click(Sender: TObject);
var
  yes, no: TStringList;
  i,j: integer;
  w: string;
begin
  ListBox1.Clear;
  ListBox2.Clear;

  yes := TStringList.Create;
  no := TStringList.Create;

  for i:=0 to Memo1.Lines.Count-1 do
  begin
    if (i mod 2)=0 then
    begin
      yes.Add(Memo1.Lines[i]);
    end
    else
    begin
      no.Add(Memo1.Lines[i]);
    end;
  end;


  for i:=0 to yes.Count-1 do
  begin
    Randomize;
    j := Random(yes.Count-1);
    w := yes[j];
    ListBox1.Items.Add(w);
    yes.Delete(j);
  end;

  for i:=0 to no.Count-1 do
  begin
    Randomize;
    j := Random(no.Count-1);
    w := no[j];
    ListBox2.Items.Add(w);
    no.Delete(j);
  end;

end;
Для примера ввёл некие строки в Memo(приведу их нижу), так вот, последние строки в разных ListBox всегда одинаковые ....
111_1
000_1
111_2
000_2
111_3
000_3
111_4
000_4
111_5
000_5
111_6
000_6
111_7
000_7
111_8
000_8
111_9
000_9
111_10
000_10
p.s. фото тоже постараюсь прикрепить ... если фото не откроется, то можно пройти по ссылке (тут)
Janger вне форума Ответить с цитированием
Старый 12.07.2016, 22:44   #2
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

j := Random(yes.Count); ---> 0<=j<=yes.Count-1
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 12.07.2016, 22:46   #3
Janger
Форумчанин
 
Регистрация: 28.09.2011
Сообщений: 250
По умолчанию

Так, я вроде бы догадался, что надо исправить
Код:
j := Random(yes.Count-1);
на
Код:
j := Random(yes.Count);
НО!
При любом перерасчёте, имеются такие строки, которые повторяются в разных listBox.
Janger вне форума Ответить с цитированием
Старый 12.07.2016, 22:49   #4
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Randomize зачем в цикл? Его нужно только раз выполнить. И можно просто в OnCreate формы
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 12.07.2016, 22:57   #5
Janger
Форумчанин
 
Регистрация: 28.09.2011
Сообщений: 250
По умолчанию

Цитата:
Сообщение от Аватар Посмотреть сообщение
Randomize зачем в цикл? Его нужно только раз выполнить. И можно просто в OnCreate формы
Почему то думал, что именно эта процедура генерирует новые числа
Janger вне форума Ответить с цитированием
Старый 13.07.2016, 00:04   #6
type_Oleg
Старожил
 
Аватар для type_Oleg
 
Регистрация: 02.03.2008
Сообщений: 2,499
По умолчанию

Цитата:
Сообщение от Аватар Посмотреть сообщение
Randomize зачем в цикл? Его нужно только раз выполнить. И можно просто в OnCreate формы
Да, или вообще вот так:
Код:
initialization
 Randomize;
end.
- в самом конце модуля формы.
type_Oleg вне форума Ответить с цитированием
Старый 13.07.2016, 09:42   #7
min@y™
Цифровой кот
Старожил
 
Аватар для min@y™
 
Регистрация: 29.08.2014
Сообщений: 7,629
По умолчанию

Чот хрень какая-то получается...


Можно поиграться.
Расскажу я вам, дружочки, как выращивать грибочки: нужно в поле утром рано сдвинуть два куска урана...

Последний раз редактировалось min@y™; 13.07.2016 в 09:57.
min@y™ вне форума Ответить с цитированием
Старый 22.07.2016, 09:55   #8
Daemvil
Пользователь
 
Регистрация: 23.12.2009
Сообщений: 56
По умолчанию

Цитата:
Сообщение от Janger Посмотреть сообщение
При любом перерасчёте, имеются такие строки, которые повторяются в разных listBox.
Делай Randomize один раз за нажатие на кнопку (вначале обработчика кнопки), плюс учти, что надо писать Random(no.Count);, т.к. он возвращает случайное число от 0 до написанного в параметре минус 1, и будет тебе счастье. Магия с неизменным элементом творится при постоянном вызове randomize.
Вот, например, код с перемешиванием индексов(В простом случае, думаю, все уже стало ясно):
Код:
var
  yes, no: TStringList;
  i,j: integer;
  w: string;
  indexes: array of integer;
  randInd,b: integer;
begin
    Randomize;
  ListBox1.Clear;
  ListBox2.Clear;

  yes := TStringList.Create;
  no := TStringList.Create;

  setlength(indexes, Memo1.Lines.Count div 2);

  for i:=0 to Memo1.Lines.Count-1 do
  begin
    if (i mod 2)=0 then
    begin
      yes.Add(Memo1.Lines[i]);
    end
    else
    begin
      no.Add(Memo1.Lines[i]);
    end;
  end;


  for i := 0 to length(indexes)-1 do //заполняем массив индексов
      indexes[i]:=i;
  for i := 0 to length(indexes)-1 do //перемешиваем массив индексов
  begin
      randInd:=random(length(indexes));
      b:=indexes[randInd];
      indexes[randInd]:=indexes[i];
      indexes[i]:=b;
  end;

  for i:=0 to yes.Count-1 do
  begin
    j := indexes[i];
    w := yes[j];
    ListBox1.Items.Add(w);
 //   yes.Delete(j); удалять элементы уже не нужно
  end;

  for i := 0 to length(indexes)-1 do //для чистоты эксперимента еще раз перемешиваем массив индексов для другого листа
  begin
      randInd:=random(length(indexes));
      b:=indexes[randInd];
      indexes[randInd]:=indexes[i];
      indexes[i]:=b;
  end;

  for i:=0 to no.Count-1 do
  begin
    j := indexes[i];
    w := no[j];
    ListBox2.Items.Add(w);
  //  no.Delete(j);
  end;
// и не забываем очищать память созданных в обработчике объектов
no.free;
yes.free; 
end;

end.
А для проверки четности красивей будет использовать функцию odd(x) (возвращает true, если нечетное)
Nostra Sunt

Последний раз редактировалось Daemvil; 22.07.2016 в 10:38.
Daemvil вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Проблема с РАНДОМОМ glazik Общие вопросы Delphi 3 22.02.2012 01:13
Вывод нужных цветов рандомом -=M{a}LoY=- Общие вопросы Delphi 4 09.12.2010 10:54
Проблема с рандомом С++ Lazio Помощь студентам 4 17.09.2010 23:45
заполнение матрицы рандомом Law1589 Общие вопросы C/C++ 5 17.11.2009 23:04