Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Для новичков > удалить из списка не дубликаты


Автор: Dmitry1987 5.12.2013, 09:43
Есть отсортированный список (TStringList) значений:

1
1
2
3
3
4
5

Задача: оставить в списке только цепочки значений (т.е. удалить не дубликаты). Как максимально быстро это сделать (за один проход)?

Автор: Illusion Dolphin 5.12.2013, 10:28
Одиночное значение это когда пред элемент и след элемент не равны текущему.

Автор: БелАмор 5.12.2013, 10:55
Цитата(Dmitry1987 @  5.12.2013,  10:43 Найти цитируемый пост)
Задача: оставить в списке только цепочки значений (т.е. удалить не дубликаты). 

Если я правильно понял, нужно удалить значения, встречающиеся только один раз?
Т.е. в вашем примере таким образом?

1
1
2  // удалить
3
3
4  // удалить
5  // удалить

Тогда алгоритм может выглядеть примерно так:

Код

Процедура с параметром типа TStrings (чтобы можно было передавать ссылку на любого наследника TStrings)
  Объявления:
    Строка
    Счётчик(повторяющихся значений)
    Индекс
  Код:
    Счётчик=0
    Цикл по элементам от конца к началу
      Если это первый проход
        Присвоить Строке ТекущийЭлемент
        Увеличить Счётчик
      Иначе
        Если ТекущийЭлемент совпадает со значением Строки
          Увеличить Счётчик
        Иначе
          Если Счётчик=1
            Удалить ПредыдущийЭлемент (Индекс+1)
          Присвоить ТекущийЭлемент Строке
          Счётчик=1
 

Автор: БелАмор 5.12.2013, 15:01
Кстати, в приведённом мной алгоритме не обрабатывается уникальный элемент в начале списка (например, в приведённом примере добавить один "0" в начало).
Исправленный вариант:

Код

Процедура с параметром типа TStrings
  Объявления:
    Строка
    Счётчик
    Индекс
  Код:
    Счётчик = 0
    Цикл по элементам от конца к началу
      Если это первый проход (Счётчик = 0)
        Строка = ТекущийЭлемент
        Счётчик = 1
        Следующая итерация (Continue)

      Если ТекущийЭлемент = Строка
        Увеличить Счётчик
      Иначе
        Если Счётчик = 1
          Удалить ПредыдущийЭлемент (Индекс+1)
        Строка = ТекущийЭлемент
        Счётчик = 1

      Если это последний проход (Индекс = 0)
        Если Счётчик = 1
          Удалить ТекущийЭлемент  


Автор: fastergus2dog 3.1.2014, 01:17
За один проход никак. Все равно нужно использовать цыкл который будет делать переборку данных.

Автор: northener 5.1.2014, 01:36
Цитата(fastergus2dog @  3.1.2014,  01:17 Найти цитируемый пост)
За один проход никак. Все равно нужно использовать цыкл который будет делать переборку данных.

С чего бы это? Топик невнимательно прочитали? Для отсортированного списка достаточно одного прохода.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)