Урок Delphi 12StringList Delphi - работа со списком строк |
Уроки Delphi
1. Первая программа
2. Использование компонентов
3. События Delphi
4. Типы данных Delphi
5. Создание своих типов данных
6. Выражения и операторы
7. Работа с файлами в Delphi
8. Дополнительные формы
9. Подпрограммы в Delphi
10. Исключительные ситуации
11. Взаимодействие приложения с пользователем
12. Указатели в Delphi
13. Обзор компонентов
14. Работа со строками
15. Создание интерфейса
16. Графика в Delphi
17. Многопоточность в Delphi
18. Динамическое создание
компонентов Поиск по сайту Это важно:
Метод Application.ProcessMessages;
Это полезно:
Параметр Sender в обработчиках событий;
Бояться не надо |
Список строк Delphi TStringList - это структура данных, напоминающая компонент ListBox, но не визуальная, а просто хранящая в памяти и имеющая свойства и методы для работы со строками типа TString.
Как видим, список типа TStringList обладает ценным свойством, которым вряд ли обладает какой-либо другой объект в Delphi, а именно возможностью обнаруживать дубликаты строк. Как узнать, что строка уже содержится в списке? Вот алгоритм:
StrList.Duplicates:=dupIgnore для обработки дубликатов использовать значение dupError, это вызовет исключительную ситуацию при попытке добавить дубликат. Соответственно, при добавлении оригинальной строки программа идёт дальше, а при попытке добавления дубликата переходит к операторам секции except/end.Эти методы работают в случае если список отсортирован. Однако есть задачи, где сортировка не нужна, а находить значение в списке всё равно необходимо. В этом случае нужно пользоваться функцией IndexOf. Рассмотрим примерЕсть таблица, содержащая список студентов с указанием их роста и веса. Нужно выделить группу студентов, чей рост или вес встречаются наиболее часто.Алгоритм решения задачи будет такой. Создадим три списка строк. В цикле будем просматривать таблицу и добавлять в первый список строк значение анализируемого параметра, если его ещё в списке нет. Во второй список будем сохранять фамилии студентов, обладающих данным ростом или весом, а в третьем - в соответствующей строке подсчитывать сколько раз это значение уже встретилось. Вот что должно получиться:
Переходя к новой строке в исходной таблице, мы анализируем нужный параметр, рост или вес - ищем в первом списке. Если такого значения у нас пока нет, мы в каждый список добавляем по строке, в первый записываем значение параметра, во второй - фамилию, а в третий - пишем единичку. А если такое значение параметра уже есть, то в соответствующую строку второго списка добавляем через запятую очередную фамилию, а в третьем значение в этой строке увеличиваем на 1. Естественно, списки строк не должны сортировать вводимые значения, иначе данные перепутаются! Дойдя до конца таблицы, нам останется в третьем списке найти строку с максимальным числом, и вывести как результат содержимое этой строки второго списка. Получилась такая программка: ![]() А вот процедура подсчёта:
procedure TForm1.Button1Click(Sender: TObject); Сортировка в StringList'еС помощью StringList можно реализовать интересный вариант сортировки чисел. Хотя StringList сортирует строки, он также будет сортировать и записанные в него в виде строк числа. Естественно, напрямую отсортировать числа таким образом не получится, так как строка, например, '100' будет меньше, чем строка '20', что для чисел 100 и 20, естественно, неверно. Однако достаточно выровнять длину строк добавлением к целой части слева, а к дробной справа пробелов' ' , чтобы сортировка сработала верно. Программисты, создавшие класс TStringList, наделили его очень быстрым алгоритмом сортировки (к тому же реализованным, видимо, с использованием низкоуровневого программирования), чем мы просто не можем не воспользоваться. По сравнению с сортировкой пузырьком, которая 100 000 чисел сортирует за 32 с половиной секунды на моём компе (или 24 сек улучшенный алгоритм), сортировка в StringList'е длится всего 530 мсек! Вот процедура для целых чисел:
procedure StringListForSort;
Здесь Grid - обычная таблица типа TStringGrid, предварительно заполненная целыми числами. Продолжительность сортировки возвращается в заголовке Формы.
Обзор алгоритмов сортировкиСортировка в StringList'е лишь в два раза медленнее так называемой "быстрой" сортировки. Для сравнения, рассмотрим и некоторые другие алгоритмы сортировки.Сортировка пузырьком - самый естественный, он же самый медленный алгоритм сортировки. Массив чисел просматривается от начала до конца до тех пор, пока любые два рядом стоящих числа не будут расположены по возрастанию. Сортировка вставками - ещё один простой способ сортировки. Массив чисел сортируется с начала, и каждое последующее число вставляется в уже отсортированную часть массива на предназначенное ему место. Быстрая сортировка - очень эффективный алгоритм, и известна как в среднем самая быстрая из универсальных алгоритмов сортировки. Быстрая сортировка сравнивает все элементы массива с одним, выбранным практически наугад, элементом (опорным элементом) и тем самым делит массив на две части - в одну попадают числа меньшие опорного, а в другую - большие опорного. читать далее... Работа со строками
В начало урока
Создание интерфейса Вопросы и комментарии (14) Решение задач в Delphi
FaridaAnguAlieva, добавлено 18.03.10, 10:41:41
Добрый день! Спасибо, очень помогло! Хороший форум, буду читать дальше, надеюсь подскажите что не так делаю. Буду держать в курсе читателей. Сергей, добавлено 7.04.10, 13:19:56 Уважаемый Автор. Для определения наличия дубликата строки при ее добавлении попробовал написать такое
var Strlist: TStringList;
Но исключения не происходило. Внимательно почитав справку выяснил, что dupError и dupIgnore работают только с сортированными списками, так что добавив строку кода Strlist.Sorted := true;
после создания списка получил обработку исключения! Автор, добавлено 8.04.10, 08:19:16 Сергей! Большое спасибо за добрые слова в адрес сайта, а главное, за помощь! Ваше замечание справедливо, добавлю в текст фразу, что список должен быть сортирован. Хочу заметить, что в вашем варианте в секции except/end конструкция является избыточной. Достаточно просто написать ShowMessage('Duplicate');
Михаил, добавлено 20.04.11, 20:03:23 Благодарю Вас добрый человек за такой полезный материал. После работы со строками у меня возникло 2 вопроса. 1. Как правильно удалить из TStringList например 5 последних строк при помощи Вuttonclick. 2. Как потом удалить дупликаты - здесь поясню - функция StrList.Duplicates:=dupIgnore; игнорирует добавление дубликатов, но если её вызвать к готовому списку, то дупликаты, которые есть в списке уже - не удаляются. Ответьте пожалуйста. Михаил, добавлено 20.04.11, 20:23:42 Правильно ли я понял, для проверки последней строки надо написать if StrList[StrList.Count-1]='текст' then.... если надо проверить, что находиться в конце списка. Автор, добавлено 20.04.11, 20:52:45 1. Удаление последней строки: SL.Delete( SL.Count-1); Делаем 5 раз, и вуаля - нет последних пяти строк. 2. Нужно создать ещё один StringList, наделить его свойствами удаления дубликатов, в цикле добавить все строки из первого, а затем, при необходимости, переписать строки из второго в первый, предварительно его очистив. Автор, добавлено 20.04.11, 20:53:28 Да, проверка последней строки правильная. Михаил, добавлено 21.04.11, 14:37:36 Уважаемый Автор благодарю Вас за ответ и хочу показать Вам, что у меня вышло trapeznaya.ucoz.ru/load/test_vitamin/2-1-0-41. Автор, добавлено 21.04.11, 16:29:32 Спасибо, программу скачал, попробовал. Интересная и полезная программа! Оставил комментарий на сайте. Хочу с улыбкой добавить вот что: как говорится, притча во языцех, слово усвояемость ))). Правильно: усва-ивае-мость. Михаил, добавлено 22.04.11, 18:46:46 Благодарю, исправимс Удав анаконда, добавлено 19.05.11, 17:26:45 цитата "Как узнать, что строка уже содержится в списке? Вот алгоритм:..." А чо, поиск IndexOf нельзя использовать??? k:=StrList.IndexOf(newst); if k=-1 then showmessage('Нету тута '+newst) else showmessage('Есть! Под номером '+inttostr(k)); Автор, добавлено 19.05.11, 17:42:26 Ну да, ну да... Всё правильно. Это уже третий способ! А чем больше... ну, тем лучше! ))) Максимильян, добавлено 12.12.11, 22:07:22 Здравствуйте! Сортировка в StringList'е лишь в два раза медленнее так называемой "быстрой" сортировки. А что если строчку Taim:=GetTickCount; перенести поближе к S.Sort; ведь пример измеряет скорость сортировки а не скорость работы всего алгоритма! Автор, добавлено 12.12.11, 23:50:37 Вот перенесли бы, измерили и написали! |
|