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

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

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 29.05.2014, 21:41   #1
Bucknall
 
Регистрация: 29.05.2014
Сообщений: 8
По умолчанию рандомизированное удаление строк из Memo

Здравствуйте.
Delphi 7.
Есть Memo, содержащий строки, например

нулевая
первая
вторая
третья
четвертая
пятая
шестая
седьмая

сначала определяем случайную строку из memo1:
x:=random(memo1.lines.count)

затем считываем строку memo1.lines[x]

когда количество обращений к одной определённой строке memo1 достигнет, например, 5 - строка из memo1 удаляется. И так в цикле очищается весь memo1

Как это реализовать? я пытался так:

Код:
procedure TForm1.Button1Click(Sender: TObject);
var ar, ar1: array of integer; i, x: integer;
begin
  randomize;
  memo1.Text := '';
  memo1.Lines.Add('нулевая');
  memo1.Lines.Add('первая');
  memo1.Lines.Add('вторая');
  memo1.Lines.Add('третья');
  memo1.Lines.Add('четвёртая');
  memo1.Lines.Add('пятая');
  memo1.Lines.Add('шестая');
  memo1.Lines.Add('седьмая');

  setlength(ar, Memo1.Lines.Count);
  setlength(ar1, Memo1.Lines.Count);

  while Memo1.Lines.Count > 1 do
  begin
    x := random(length(ar));
    inc(ar[x]);
    memo2.Lines.Add(inttostr(ar[x]) + '-е обращение к строке "' + memo1.Lines[x] + '"');
    if ar[x] >= 5 then
    begin
      ar1 := ar;
      memo2.Lines.Add('----' + memo1.Lines[x] + ' ушла на ' + inttostr(ar[x]) + '-м обращении' + '----');
      for i := length(ar) - 1  downto x do
      begin
        if i > 0 then ar[i - 1] := ar1[i];
      end;
      setlength(ar, length(ar) - 1);
      setlength(ar1, length(ar) - 1);
      Memo1.Lines.Delete(x);
    end;
  end;

  memo2.Lines.Add(inttostr(ar[0]));

  ar := nil;
  ar1 := nil;
end;
вопросы
1. куда смотреть для рационализации алгоритма? Уверен, что использование 2-х массивов изящным решением не назовешь (Кстати, не обязательно очищать Memo со строками, можно чтобы рэндом[x] к уже считанным из него n-раз строчкам просто больше не обращался). Использовать множество? Или - массив плюс буферную переменную..?
2. что не так в этом алг-ме, что во втором memo иногда проскакивают странные цифры?
3. при Memo1.Lines.Count>0 - чтобы очистить memo1 совсем - ошибка "Range check error". Как исправить?

Спасибо
Вложения
Тип файла: zip array_propolka.zip (201.7 Кб, 9 просмотров)

Последний раз редактировалось Bucknall; 29.05.2014 в 21:42. Причина: удалил свои же комменты из кода
Bucknall вне форума Ответить с цитированием
Старый 30.05.2014, 00:11   #2
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

такой вариант решения устроит?

Код:
procedure TForm1.Button2Click(Sender: TObject);
var i,x,cnt  : integer;
  TS : TStringList;
begin
  Randomize;

  TS := TStringList.Create;
  for i := 0 to Memo1.Lines.Count - 1 do
     TS.AddObject(memo1.Lines[i], Pointer(0) );

  while TS.Count>0 do begin
     x:=random(TS.Count);
     cnt := Integer(TS.Objects[x])+1;
     memo2.Lines.Append(TS.Strings[x]+ ' ('+IntToStr(cnt)+')' );
     if cnt >= 5 then begin {если есть пять обращений - удаляем объект из списка}
        Memo2.Lines.Append(' --- выкинули строку: '+TS.Strings[x]);
        TS.Delete(x);
     end
     else
        TS.Objects[x] := Pointer( cnt ); {увеличим счётчик}
  end;
  FreeAndNil(TS);
end;

(при выводе строки в Memo2 я в скобках вывожу какое это обращение. разумеется, это можно убрать...)
Serge_Bliznykov вне форума Ответить с цитированием
Старый 30.05.2014, 00:38   #3
Bucknall
 
Регистрация: 29.05.2014
Сообщений: 8
По умолчанию

Да, замечательно, спасибо
я к этому времени уже соорудил что-то наподобие

Код:
procedure TForm1.Button3Click(Sender: TObject);
var ar: array of integer; buf, i, x: integer;
begin
   SetLength(ar, memo1.Lines.Count);
  while length(ar) > 0 do
  begin
    x := random(memo1.Lines.Count);
    if ar[x] < 5 then
    begin inc(ar[x]);
      memo2.Lines.Add(inttostr(ar[x]) + '-е обращение к строке "' + memo1.Lines[x] + '"');
    end
    else
    begin
      memo2.Lines.Add('----' + memo1.Lines[x] + ' ушла на ' + inttostr(ar[x]) + '-м обращении' + '----');
      for i := length(ar) - 2 downto x do
      begin
        buf := ar[i];
        ar[i] := ar[length(ar) - 1];
        ar[length(ar) - 1] := buf;
      end;
      SetLength(ar, length(ar) - 1);
      memo1.Lines.Delete(x);
    end;
  end;
  ar := nil;
end;
но Ваш код выглядит (да и работает, вроде) лучше ) Благодарю!)

Последний раз редактировалось Bucknall; 30.05.2014 в 00:43.
Bucknall вне форума Ответить с цитированием
Ответ


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

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

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Memo. Удаление строк Rakim4ik Общие вопросы Delphi 2 11.01.2014 15:10
Удаление строк в Memo qpuTuJlb Помощь студентам 6 01.06.2012 17:17
Удаление строк в memo roxy7 Компоненты Delphi 2 16.03.2012 23:07
Удаление строк в Memo Marsel737 Общие вопросы Delphi 8 03.01.2010 10:42
Удаление строк из Memo Leksda Общие вопросы Delphi 6 20.03.2009 15:31