Коллекции строк

Для создания и использования коллекции отсортированных строк в 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, Вы сможете вывести на экран список слов, отсортированных в обратном порядке.