Цель работы: изучить основные методы организации таблиц идентификаторов, получить представление о преимуществах и недостатках, присущих различным методам организации таблиц символов (идентификаторов).
Для выполнения лабораторной работы требуется написать программу, которая получает на входе набор идентификаторов, организует таблицу по заданному методу и позволяет осуществить многократный поиск идентификатора в этой таблице. Список идентификаторов считать заданным в виде текстового файла. Длина идентификаторов ограничена 32 символами.
|
Сумма кодов двух последних букв |
Метод цепочек и бинарного дерева |
Блок-схема алгоритма добавления нового идентификатора в ТИ
Блок-схема алгоритма поиска идентификатора в ТИ
Результат работы программы:
Листинг программы:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Grids;
type
TForm1 = class(TForm)
StringGrid1: TStringGrid;
StringGrid2: TStringGrid;
Memo1: TMemo;
Edit2: TEdit;
Edit3: TEdit;
Edit4: TEdit;
Edit5: TEdit;
Button1: TButton;
Button2: TButton;
OpenDialog1: TOpenDialog;
Button3: TButton;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Label4: TLabel;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure Button3Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
Words: TstringList;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
close
end;
procedure TForm1.Button2Click(Sender: TObject);
label M1;
var
F:TextFile;
S:String;
NRow, i,Code,Link, Kol, Com: Integer;
KolS,ComS:real;
begin
{Загрузка файла при помощи пользовательского диалога в поле Memo}
if OpenDialog1.Execute then Memo1.Lines.LoadFromFile(OpenDialog1.Filename)
else Exit;{Выход, если пользователь отказался выбрать файл}
AssignFile(F, OpenDialog1.FileName);
reset(f);{Открытие файла для чтения}
{Создание строкового списка из строк файла}
Words:=TStringList.Create;{Вызов конструктора класса}
Words.Sorted:=False;
Screen.Cursor:=crHourGlass;{Изменение типа курсора перед длительной работой}
{Извлечение строк из файла и занесение их в список}
while not EOF(F) do
begin
readln(F,S);
if S<>'' then Words.Add(S)
end;
Screen.Cursor:=crDefault;{Восстановление типа курсора по умолчанию}
CloseFile(F);
if Words.Count=0 then Exit;{Выход, если список пуст}
end;
procedure TForm1.FormCreate(Sender: TObject);
var
f,n,ad:integer;
begin
with StringGrid1 do
begin
cells[0,0]:='f';
cells[1,0]:='ad';
for n:= 1 to 255 do begin
cells[0,n]:='d'+InttoStr(n);
cells[1,n]:=''; end;
end;
StringGrid1.cells[0,0]:='Хф';
StringGrid1.cells[1,0]:='Адрес';
StringGrid2.cells[0,0]:='Адрес';
StringGrid2.cells[1,0]:='Ид';
StringGrid2.cells[2,0]:='левый';
StringGrid2.cells[3,0]:='Правый';
end;
procedure TForm1.Button3Click(Sender: TObject);
label M1;
var
S,SLInk,Word:String;
Address, NRow, HF,Code,Link, Kol, Com,LIN: Integer;
KolS,ComS:real;
begin
{Рисование ТИ}
Address:=1;{Указатель указывает на первую строку в ТИ}
Kol:=0;{Количество колизий}
Com:=0;{Количество сравнений}
{Собственно хэширование}
for i:=0 to Words.Count-1 do
begin
s:=Words[i];
LIN:=length(S);
HF:=Ord(S[LIN-1])+Ord(S[LIN]);{Вычисление значения хэш-функции}
if StringGrid1.Cells[1,HF]='' then
begin {ячейка с данным значением ХФ свобо}
Com:=Com+1;
StringGrid1.Cells[1,HF]:=Inttostr(Address);{заносим указатель в ХТ}
StringGrid2.Cells[0,Address]:=InttoStr(Address);{прорисовываем адрес в ТИ}
StringGrid2.Cells[1,Address]:=S;{Заносим запись в ТИ по значению указателя}
end
else {ячейка с данным заначением ХФ занята}
begin
Kol:=Kol+1;
Com:=Com+1;
SLink:=StringGrid1.Cells[1,HF];{считываем адрес из ХФ}
val(SLink,Link,Code);{переходим по ссылке}
M1: if S>StringGrid2.Cells[1,Link] then {добавляемый идентификатор находится правее старого}
begin
Com:=Com+1;
if StringGrid2.Cells[3,Link]='' then
begin{Правая ссылочная область пуста}
Com:=Com+1;
StringGrid2.Cells[3,Link]:=InttoStr(Address);
StringGrid2.Cells[0,Address]:=InttoStr(Address);
StringGrid2.Cells[1,Address]:=S
end
else
begin{Правая ссылочная область занята}
Com:=Com+1;
Kol:=Kol+1;
SLink:=StringGrid2.Cells[3,Link];{читаем из нее адрес}
val(SLink,Link,Code);{переходим по ссылке}
goto M1
end
end
else {ДИд находится левее старого}
begin
Com:=Com+1;
if StringGrid2.Cells[2,Link]='' then
begin {левая ссылочная область пуста}
Com:=Com+1;
StringGrid2.Cells[2,Link]:=InttoStr(Address);
StringGrid2.Cells[0,Address]:=InttoStr(Address);
StringGrid2.Cells[1,Address]:=S
end
else{левая ссылочная облась занята}
begin
Kol:=Kol+1;
Com:=Com+1;
SLink:=StringGrid2.Cells[2,Link];
val(SLink,Link,Code);
goto M1
end
end
end;
Address:=Address+1{переход указателя на следующую запись}
end;
Word:=InttoStr(Kol);
Edit2.Text:=Word;
word:=InttoSTR(Com);
Edit3.Text:=Word;
KolS:=Kol/Memo1.Lines.Count;
ComS:=Com/Memo1.Lines.Count;
Word:=FloattoStr(KolS);
Edit4.Text:=Word;
Word:=FloattoStr(ComS);
Edit5.Text:=Word;
end;
end.
Выводы по проделанной работе: изучены основные методы организации таблиц идентификаторов, преимущества и недостатка, присущие различным методам организации таблиц символов (идентификаторов).
Написана программа, которая получает на входе набор идентификаторов, организует таблицу и позволяет осуществить многократный
поиск идентификатора в этой таблице. Список идентификаторов считать заданным в виде текстового файла.