Const
lenstr=40;
Type
st1=string[lenstr];
elmnt=record
st:st1; {Наименование раздела из неболее чем 40 символов}
ik:word;{количество записей}
nn:word; {номер раздела}
end;
Tpzap=^zap; {элемент строки таблицы – это элемент списка}
zap=record
el:elmnt;
pnext:Tpzap;
end;
ff=file of elmnt; {сохраняемые в файле данные}
Tabl=^tst;
tst= array [0..0] of Tpzap;{индексы элементов- это ключи хеш-функции.Количество индексов-ключей можно выбрать любое. В данном решении возьмем количество ключей, равное 10}
OTabl=object
tbl:Tabl;{Объект- таблица включает в себя табличные переменные}
T,P,Q,PQ:Tpzap;{Элементы для формирования списков в строках таблицы}
iEl:elmnt;
f:ff;
constructor init(var Ok:boolean);
destructor done(var Ok:boolean);
procedure new_el_tb(nEl:elmnt);{запись элемента в хеш-таблицу}
procedure vvod_tb;{ввод таблицы}
procedure dopoln;{поиск пустых разделов таблицы}
procedure read_f;{читать из файла}
procedure save_f;{записать элементы таблицы в файл}
procedure show_tb;{вывести таблицу}
end;
var init_Ok:boolean;
Implementation
uses crt,utils;
constructor Otabl.init(var Ok:boolean);
var i:word;
Begin
getmem(Tbl,10*sizeof(Tpzap));{}
{резервируем память для сохранения вектора указателей на строки с описанием разделов}
for i:=0 to 9 do
Tbl^[i]:=nil;
{Указатели делаем пустыми, чтобы работать только с имеющимися в данном тексте длинами слов}
Ok:=true;
end;
procedure Otabl.new_el_tb(nEl:elmnt);
var m:word;
stop:boolean;
Begin
m:=nEl.nn mod 10;
T:=Tbl^[m];{ключ найден в соотвествии с номером раздела}
if (T=nil) then
Begin
new(p);
P^.el:=nEl;
P^.pnext:=nil;{этот оператор работает только для создания первого элемента списка типа стека}
Tbl^[m]:=P;
End else
Begin
new(PQ);
PQ^.el:=nEl;
PQ^.pnext:=Tbl^[m];
Tbl^[m]:=PQ;
end;
end;{Конец метода включения нового элемента в таблицу }
procedure OTabl.vvod_tb;
Var
stop:boolean;
L,iL:byte;
s:st1;
d,code:word;
ch:char;
Begin
assign(f,'tab.dat');
rewrite(f);
Repeat
window(40,12,79,18); clrscr;
textcolor(yellow);
gotoxy(1,1); {stop:=false;}
writeln(' Введите данные картотеки');
write(' Раздел номер ');
readln(iEl.nn);
write(' Количество записей в разделе ');
readln(iEl.ik);
write(' Название раздела ');
readln(iEl.st);
write(f,iEl);
new_el_tb(iEl);
writeln(' Есть еще данные?');
readln(ch);
until ch='n';
window(1,1,80,24);
end;
procedure OTabl.dopoln;
var i:word;
n:boolean;
Begin
window(1,1,80,24);
clrscr;n:=true;
writeln(' Пустые разделы: ':40);
writeln(' Номер раздела':20,' Название раздела':40);
for i:=0 to 9 do
Begin
P:=Tbl^[i];
while P<>nil do
Begin
if (P^.el.ik=0) then
Begin
write(i:10);
writeln('| ',P^.el.nn:10,' |',P^.el.st:20,' |');
n:=false;
end;
P:=P^.pnext;
end;
end;
readln;