Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Уроки в Delphi.doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
987.14 Кб
Скачать

Рассмотрим пример

Есть таблица, содержащая список студентов с указанием их роста и веса. Нужно выделить группу студентов, чей рост или вес встречаются наиболее часто. Алгоритм решения задачи будет такой. Создадим три списка строк. В цикле будем просматривать таблицу и добавлять в первый список строк значение анализируемого параметра, если его ещё в списке нет. Во второй список будем сохранять фамилии студентов, обладающих данным ростом или весом, а в третьем - в соответствующей строке подсчитывать сколько раз это значение уже встретилось. Вот что должно получиться:

Исходная таблица

Первый список

Второй список

Третий список

Фамилия

Рост

Вес

Иванов

179

80

Петров

180

82

Сидоров

179

78

Ковалёв

175

78

Анализ по росту 179 180 175

Иванов, Сидоров Петров Ковалёв

2 1 1

Переходя к новой строке в исходной таблице, мы анализируем нужный параметр, рост или вес - ищем в первом списке. Если такого значения у нас пока нет, мы в каждый список добавляем по строке, в первый записываем значение параметра, во второй - фамилию, а в третий - пишем единичку. А если такое значение параметра уже есть, то в соответствующую строку второго списка добавляем через запятую очередную фамилию, а в третьем значение в этой строке увеличиваем на 1. Естественно, списки строк не должны сортировать вводимые значения, иначе данные перепутаются! Дойдя до конца таблицы, нам останется в третьем списке найти строку с максимальным числом, и вывести как результат содержимое этой строки второго списка. Получилась такая программка:

вот процедура подсчёта: procedure TForm1.Button1Click(Sender: TObject); var i, k: Integer; begin Caption:=''; List1.Clear; List2.Clear; List3.Clear; Param:=ComboBox1.ItemIndex+1; for i:=1 to StringGrid1.RowCount-1 do begin k:=List1.IndexOf(StringGrid1.Cells[Param, i]); if k=-1 then begin List1.Add(StringGrid1.Cells[Param, i]); List2.Add(StringGrid1.Cells[0, i]); List3.Add('1'); end else begin List2[k]:=List2[k]+', '+StringGrid1.Cells[0, i]; List3[k]:=IntToStr(StrToInt(List3[k])+1); end; end; k:=0; for i:=0 to List3.Count-1 do if StrToInt(List3[i])>k then k:=StrToInt(List3[i]); for i:=0 to List2.Count-1 do if StrToInt(List3[i])=k then Caption:=Caption+List2[i]+': '+List1[i]+'; '; end;

Сортировка в StringList'е

С помощью StringList можно реализовать интересный вариант сортировки чисел. Хотя StringList сортирует строки, он также будет сортировать и записанные в него в виде строк числа. Естественно, напрямую отсортировать числа таким образом не получится, так как строка, например, '100' будет меньше, чем строка '20', что для чисел 100 и 20, естественно, неверно. Однако достаточно выровнять длину строк добавлением к целой части слева, а к дробной справа пробелов ' ', чтобы сортировка сработала верно. Программисты, создавшие класс TStringList, наделили его очень быстрым алгоритмом сортировки (к тому же реализованным, видимо, с использованием низкоуровневого программирования), чем мы просто не можем не воспользоваться. По сравнению с сортировкой пузырьком, которая 100 000 чисел сортирует за 32 с половиной секунды на моём компе (или 24 сек улучшенный алгоритм), сортировка в StringList'е длится всего 530 мсек! Вот процедура для целых чисел: procedure StringListForSort; var S: TStringList; i, max: Integer; Taim: Int64; begin Taim:=GetTickCount; max:=0; S:=TStringList.Create; for i:=1 to Form1.Grid.RowCount-1 do begin if Length(Form1.Grid.Cells[1, i])>max then max:=Length(Form1.Grid.Cells[1, i]); S.Add(Form1.Grid.Cells[1, i]); end; for i:=0 to S.Count-1 do while Length(S[i])<>max do S[i]:=' '+S[i]; S.Sort; Form1.Caption:='Продолжительность сортировки '+IntToStr(GetTickCount-Taim)+' мсек'; for i:=1 to Form1.Grid.RowCount-1 do Form1.Grid.Cells[1, i]:=Trim(S[i-1]); S.Free; end; Здесь Grid - обычная таблица типа TStringGrid, предварительно заполненная целыми числами. Продолжительность сортировки возвращается в заголовке Формы.