19.5. Коллекции строк Турбо Паскаль В.В. Фаронов

Для создания и использования коллекции отсортированных строк в Turbo Vision используется объект TSrtingCollection. Этот объект является прямым потомком от TSortedCollection и отличается от него тем, что его метод Compare не является абстрактным - по умолчанию он осуществляет обычное для Турбо Паскаля лексикографическое сравнение двух строк. Таким образом, если Вам необходимо отсортировать коллекцию строк по алфавиту (точнее, в соответствии с внутренней кодировкой символов), Вы можете использовать экземпляр объекта TSortedCollection без какого-либо перекрытия его методов.
В следующей программе создается словарь слов, входящих в некоторый текстовый файл. По умолчанию используется файл с текстом программы, но Вы можете указать имя любого текстового файла в качестве параметра вызова программы.
Uses Objects;
var
f: file of Char; Function OpenFile(var Name: String): Boolean;
{Возвращает FALSE, если нельзя открыть файл}
begin
if ParamCount = 1 then
Name :=" ParamStr(1) {Первый параметр в строке вызова программы должен содержать имя файла,}
else , {если это не так, анализируется файл, содержащий текст программы}
Name := copy(ParamStr(0),1,
posC . ' ,ParamStr(0))) + 'PAS' ;
Assign(f, Name);
{$I-}
Reset(f);
{$I+}
OpenFile := IOResult=0
end; {OpenFile}
Function GetWord: String;
{Получает из файла очередное слово}
var
с: Char;
w: String;
Function Letter(var c: Char): Boolean;
{Возвращает TRUE, если символ - буква}
begin
с := UpCase (с);
{проверяем на строчную русскую букву:}
if с in ['а'..'п'] then . {а - русская буква}
с := chr(ord(c)-ord('а')+ord('А') ) {А - русская буква}
else if с in ['р'..'я'] then , {р - русская буква}
с := chr(ord(с)-ord('р')+ord('Р')) ; {Р - русская буква}
{Проверяем на заглавную букву:}
Letter := с in ['А'..'Z','А1..'Я']
end; {Letter}
begin {GetWord}
w : = ' ' ;
С := #0;
while not EOF(f) and not Letter(c) do
Read(f,c);
if not EOF(f) then while not EOF(f) and Letter(c) do
begin
w .:= w+c;
Read(f,c)
end ;
GetWord := w
end; {GetWord}
Procedure PrintList(List: PStringCollection);
{Выводит на экран список слов}
Procedure PrintWord(p: PString); far;
begin
Write(р^, ' ':20-Length(р^))
end; {PrintWord}
begin {PrintList}
WriteLn;
WriteLn;
List^.ForEach(@PrintWord);
WriteLn
end; {PrintList}
var
WordList: PStringCollection;
w: String;
begin {Основная программа}
if not OpenFile(w) then
WriteLn('Нельзя открыть файл '+w)
else
begin
WordList := New(PStringCollection, Init(200,10));
repeat
w := GetWord;
if (w <> ' ') and (MaxAvail > 255) then
WordList^.Insert(NewStr(w))
until w='';
PrintList(WordList)
end
end.
Отметим, что в операторе
if (w <> '') and (MaxAvail > 255) then
осуществляется контроль за доступной динамической памятью. В Turbo Vision есть и встроенные способы контроля кучи - см. п. 19.6.
Как и в любой другой отсортированной коллекции, в коллекции строк по умолчанию хранятся элементы с уникальными ключевыми полями. Чтобы подавить контроль за уникальностью строк, добавьте оператор
WordList^.Duplicates := True;
сразу за оператором создания коллекции
WordList := New(PStringCollection, Init(200,10));
и сделайте еще один прогон программы, - Вы увидите, как много раз встречается в файле одно и то же слово.
Метод TStringCollection.Compare следует перекрыть, если Вы хотите осуществить свой способ сортировки строк. Например, используя объект
type
PStrSor =^TStrSor;
TStrSor = object (TStringCollection)
Function Compare(k1, k2: Pointer): Integer; Virtual;
end;
Function TStrSor.Compare(k1, k2: Pointer): Integer;
var
s1: PString absolute k1;
s2: PString.absolute k2;
begin
if s1^< s2^ then
Compare := 1
else if s1^ = s2^ then
Compare := 0
else
Compare := -1
end;
вместо PStringCollection, Вы сможете вывести на экран список слов, отсортированных в обратном порядке.