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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 25.09.2011, 18:31   #1
bulldog5293
Форумчанин
 
Регистрация: 13.05.2010
Сообщений: 670
По умолчанию Поиск и удаление в stringlist'e

Как правильно удалить строку из tstriglist'a в которой нет определённого слова и оставить строку со словом которое нужно? Такой подход не работает
Код:
for i:= 0 to c.Count - 1 do
        begin
         while not Pos('слово', c[i]) <>0 do
        begin
          c.Delete (i);
        end;
         j:= Pos('слово', c[i]);
         S1:= Copy(c[i]);
          showmessage(S1);
          end;
bulldog5293 вне форума Ответить с цитированием
Старый 25.09.2011, 18:48   #2
Silver_S
Форумчанин
 
Регистрация: 14.03.2011
Сообщений: 104
По умолчанию

Код:
for i := c.Count - 1 downto 0 do
Silver_S вне форума Ответить с цитированием
Старый 25.09.2011, 19:14   #3
JUDAS
фонатик DELPHI
Форумчанин
 
Аватар для JUDAS
 
Регистрация: 14.01.2008
Сообщений: 714
По умолчанию

Код:
i:=0;
while i<StringList.Count do
begin
  if Pos('нужное слово',StringList.Strings[i])=0 then 
  begin
    StringList.Delete(i);
    continue;
  end;
  inc(i);
end;
95% сбоев и ошибок приложений, находится в полу метрах от монитора
JUDAS вне форума Ответить с цитированием
Старый 25.09.2011, 20:47   #4
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

ну можно и так.
но, мне кажется, что вариант, предложенный Silver_S более простой и понятный (я сам так же всегда поступаю): когда надо перебрать элементы и часть из них удалить, двигаться нужно от конца списка к его началу:
Код:
for i:= c.Count - 1 downto 0 do
  if Pos('слово', c[i])=0 do
          c.Delete(i);
Serge_Bliznykov вне форума Ответить с цитированием
Старый 25.09.2011, 20:53   #5
bulldog5293
Форумчанин
 
Регистрация: 13.05.2010
Сообщений: 670
По умолчанию

JUDAS спасибо, работает
bulldog5293 вне форума Ответить с цитированием
Старый 25.09.2011, 21:00   #6
JUDAS
фонатик DELPHI
Форумчанин
 
Аватар для JUDAS
 
Регистрация: 14.01.2008
Сообщений: 714
По умолчанию

Цитата:
когда надо перебрать элементы и часть из них удалить, двигаться нужно от конца списка к его началу:
да не вопрос откуда двигатся, вопрос про то, что при удалении элемента I счётчик в Вашем цикле, уменьшится на один и процедура c.Count будет пересчитіваться ровно столько раз сколко строк удаляется.
Для списка в 10-20 строк оно как бы прокатывает, а для списка в 10000-20000 строк удаление 2-3 строк будет происходить минутами.
95% сбоев и ошибок приложений, находится в полу метрах от монитора
JUDAS вне форума Ответить с цитированием
Старый 25.09.2011, 21:34   #7
Silver_S
Форумчанин
 
Регистрация: 14.03.2011
Сообщений: 104
По умолчанию

Цитата:
Сообщение от JUDAS Посмотреть сообщение
да не вопрос откуда двигатся, вопрос про то, что при удалении элемента I счётчик в Вашем цикле, уменьшится на один и процедура c.Count будет пересчитіваться ровно столько раз сколко строк удаляется.
Для списка в 10-20 строк оно как бы прокатывает, а для списка в 10000-20000 строк удаление 2-3 строк будет происходить минутами.
Не понял вас... Вы что, считаете, что код "i := c.Count" выполняется при каждом проходе по циклу, а в вашем варианте количество вызовов c.Count будет меньше???

Последний раз редактировалось Silver_S; 25.09.2011 в 21:59.
Silver_S вне форума Ответить с цитированием
Старый 25.09.2011, 21:55   #8
SNUPY
Форумчанин
 
Регистрация: 15.02.2008
Сообщений: 621
По умолчанию

Ну чтож... давайте тогда это сделаем в абсолютно кашерном исполнении =)):
Код:
procedure ClearStringList(ss:ss :TStringList; s: string);
var
  shift, i, count :Cardinal;
  log :Boolean;
begin
  shift := 0;
  i :=0;
  count := ss.Count;
  log := false;
  while i <= count-1 do
  begin
    if Pos(s,ss[i])=0 then
    begin
      inc(shift);
      log := True;
    end
    else
    begin
      if log then
        ss[i-shift] := ss[i];
    end;
    inc(i);
  end;

  for i:=count-1 downto count-shift-1 do
    ss.Delete(i);
end;
Помог? Ну так нажми на весы!
SNUPY вне форума Ответить с цитированием
Старый 25.09.2011, 21:59   #9
JUDAS
фонатик DELPHI
Форумчанин
 
Аватар для JUDAS
 
Регистрация: 14.01.2008
Сообщений: 714
По умолчанию

Цитата:
c.Count будет меньше?
практика показывает что да ) по крайней мере на 7-м делфи
95% сбоев и ошибок приложений, находится в полу метрах от монитора
JUDAS вне форума Ответить с цитированием
Старый 25.09.2011, 22:18   #10
SNUPY
Форумчанин
 
Регистрация: 15.02.2008
Сообщений: 621
Радость

Цитата:
Сообщение от JUDAS Посмотреть сообщение
практика показывает что да ) по крайней мере на 7-м делфи
Эмм...
Поддерживаю Silver_S: для цикла For лишь в начале вычисляются значения начала и конца. А в вашем случаи while i<StringList.Count do вычисляется полностью каждый раз при проходе цикла.
Помог? Ну так нажми на весы!

Последний раз редактировалось SNUPY; 25.09.2011 в 22:26.
SNUPY вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Поиск и удаление MISSING SilverSmallFish Microsoft Office Excel 4 28.06.2010 14:53
Поиск и удаление из TStrings Shouldercannon Общие вопросы Delphi 9 27.05.2010 19:47
Поиск и удаление битых путей Shouldercannon Общие вопросы Delphi 13 15.11.2009 17:37
поиск мин., удаление эл-ов массива Dmitrич Общие вопросы C/C++ 2 01.06.2009 13:31
Поиск и удаление столбцов mchip Microsoft Office Excel 4 17.05.2009 18:48