БЕЛОРУССКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ
ИНФОРМАТИКИ И РАДИОЭЛЕКТРОНИКИ
Кафедра программного обеспечения информационных технологий
Факультет КСиС
Специальность ПОИТ
Индивидуальная практическая работа №1
по дисциплине «Структуры и алгоритмы обработки данных»
Выполнил студент: Бордон Е.С.
группа 991051
Зачетная книжка № 99105004
Минск 2020
Задание №1:
На основе динамических списков необходимо реализовать словарь. Реализовать выполнение операций поиска, вставки и удаления данных
словаря. В сочетании со списками для построения словарей требуется использовать открытое хеширование данных.
Программа реализована на языке Delphi в программной среде Lazarus.
Основная Хеш-функция, определенная на символьных строках:
function hashing (word : string) : integer;
var
hashCode, i : integer;
begin
hashCode := 0;
for i:=1 to word.Length do hashCode:=(hashCode+ord(word[i])) mod B;
hashing :=hashCode;
end;
Количество ячеек – аргумент В принят равным 5, для лучшего отображения работы программы:
Организация данных:
const B = 5; // количество ячеек
type
TPlink = ^link;
link = record
word : string; //само слово
next : TPlink; // ссылка на следующее слово
end;
type chain = record
head : TPlink;
check : integer; // проверка ячейки (0-пустая)
end;
var
h : array [0..B] of chain; // массив из ячеек
Процедура добавления слова:
procedure addHash(word : string);
var
curr : TPlink;
hashCode : integer;
begin
hashCode:=hashing (word);
if search(word)<>'' then begin
ShowMessage('Данное слово уже есть в списке!');
exit;
end;
if h[hashCode].check = 0
then begin
h[hashCode].check:= 1;
new(curr);
curr^.word:=word;
curr^.next:=nil;
h[hashCode].head:=curr;
end else begin
inc(h[hashCode].check,1); // Счетчик слов
new(curr);
curr^.word:=word;
curr^.next:=h[hashCode].head;
h[hashCode].head:=curr;
end;
end;
Рис.1 Схема добавления слова в список
Функция поиска слова:
function search(word : string) : string;
var
curr : TPlink;
hashCode : integer;
begin
hashCode:=hashing (word);
if h[hashCode].check = 0 then
begin
search:='';
exit;
end;
curr:=h[hashCode].head;
while curr<>nil do
begin
if curr^.word = word
then begin
search:=inttostr(hashCode);
exit;
end;
curr:=curr^.next;
end;
end;
Рис.2 Схема функции поиска слова
Процедура удаление слова:
procedure delhash(word : string);
var
prev, curr : TPlink;
hashCode : integer;
begin
if search(word)='' then
begin
ShowMessage('Данный элемент отсутствует в списке!');
exit;
end;
hashCode:=hashing (word);
curr:=h[hashCode].head;
prev:=nil;
while curr<>nil do
begin
if curr^.word = word
then begin
if prev = nil
then begin
h[hashCode].head:= curr^.next;
end else
prev^.next:=curr^.next;
ShowMessage('Элемент удален!');
h[hashCode].check:= h[hashCode].check - 1;
dispose(curr);
exit;
end;
prev:=curr;
curr:=curr^.next;
end;
end;
Рис.3 Схема процедуры удаления слова
Листинг всей программы приведён в конце отчета.
Скриншоты работы программы:
Рис.4 Скриншоты работы программы
Задание№2:
1. Используя стек, реализовать алгоритм преобразования алгебраического выражения из инфиксной формы записи в постфиксную форму представления.
2. Используя стек, реализовать алгоритм преобразования алгебраического выражения из инфиксной формы записи в префиксную форму представления.
Для обоих алгоритмов предусмотреть вхождение операций с различными приоритетами, а также наличие скобок в инфиксных выражениях.
Программа реализована на языке Delphi в программной среде Lazarus.
Процедура перевода из инфиксной формы в постфиксную:
Procedure Convert_expression (a:String;Var z:String); // Постфиксная форма из инфиксной
Var head:pt_1;
i:Integer;
w:Char;
Begin
head:=Nil;
z:='';
i:=1;
While i<=Length(a) Do
Begin
Case a[i] of
'0'..'9': z:=z+a[i];
'a'..'z': z:=z+a[i];
'A'..'Z': z:=z+a[i];
'(': WriteStack_1(head,a[i]);
')': Begin //Считываем из стека до символа «(»
ReadStack_1(head,w);
While w<>'(' Do
Begin z:=z+w; ReadStack_1(head,w); End;
End;
'+','-','*','/','^':
begin
If not Free_1(head) Then WriteStack_1(head,a[i])
else
begin
w:=head^.data;
While Free_1(head)and(Priority(head^.data)>= Priority(a[i]))
do
Begin ReadStack_1(head,w);z:=z+w; End;
WriteStack_1(head,a[i]) ;
end;
end;
End;
Inc(i);
End;
//Дополняем строку символами операций, запомненных в стеке
While Free_1(head) Do Begin ReadStack_1(head,w); z:=z+w; End;
End;
Рис.5 Схема процедуры перевода
Процедура перевода в префиксную форму из постфиксной:
Procedure Convert_expression_2 (a:String;Var z:String);
var
stat:integer;
i:integer;
s:string;
begin
z:='';
i:=1;
While i<=Length(a) Do begin
case a[i] of
'0'..'9': stat:=0;
'a'..'z': stat:=0;
'A'..'Z': stat:=0;
' ' : stat:=0;
'+','-','*','/','^': stat:=1;
end;
if stat = 1 then begin
s:= a[i] + a[i-2] + a[i-1];
if (s[2]= ' ') or (s[3] = ' ') then
z:= s[1] + s[2] + z + s[3]
else z:= z + s;
a:= StringReplace(a, a[i-2] + a[i-1] + a[i], ' ',
[rfReplaceAll, rfIgnoreCase]);
i:=0;
end;
inc(i);
end;
z := StringReplace(z ,' ','', [rfReplaceAll, rfIgnoreCase]);
end;
Рис.6 Схема процедуры перевода
Рис.7 Скриншоты работы программы
Листинг Задания 1:
unit Unit2;
{$mode objfpc}{$H+}
Interface
uses
Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, Grids, Menus;
{ TForm2 }
type
TForm2 = class(TForm)
Button1: TButton;
Button2: TButton;
Button3: TButton;
Button5: TButton;
Edit1: TEdit;
Edit3: TEdit;
Edit4: TEdit;
Label1: TLabel;
MainMenu1: TMainMenu;
MenuItem1: TMenuItem;
MenuItem2: TMenuItem;
StringGrid1: TStringGrid;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button5Click(Sender: TObject);
procedure MenuItem2Click(Sender: TObject);
private
public
end;
var
Form2: TForm2;
Implementation
const B = 5; // количество ячеек не больше значения
type
TPlink = ^link;
link = record
word : string; //само слово без ключа
next : TPlink;
end;
type chain = record
head : TPlink; // слово
check : integer; // проверка ячейки
end;
var
h : array [0..B] of chain; // массив из ячеек
{$R *.lfm}
function hashing (word : string) : integer; // Хеширование не больше B!
var
hashCode, i : integer;
begin
hashCode := 0;
for i:=1 to word.Length do hashCode:=(hashCode+ord(word[i])) mod B;
hashing :=hashCode;
end;
function search(word : string) : string; // Поиск по хешу через слово
var
curr : TPlink;
hashCode : integer;
begin
hashCode:=hashing (word);
if h[hashCode].check = 0 then
begin
search:='';
exit;
end;
curr:=h[hashCode].head;
while curr<>nil do
begin
if curr^.word = word
then begin
search:=inttostr(hashCode);
exit;
end;
curr:=curr^.next;
end;
end;
procedure addHash(word : string); //Добавить
var
curr : TPlink;
hashCode : integer;
begin
hashCode:=hashing (word);
if search(word)<>'' then begin
ShowMessage('Данное слово уже есть в списке!');
exit;
end;
if h[hashCode].check = 0
then begin
h[hashCode].check:= 1;
new(curr);
curr^.word:=word;
curr^.next:=nil;
h[hashCode].head:=curr;
end else begin
inc(h[hashCode].check,1); // если по хешу есть уже слово просто добавляем 1
new(curr);
curr^.word:=word;
curr^.next:=h[hashCode].head;
h[hashCode].head:=curr;
end;
end;
procedure delhash(word : string); // Удаление слова
var
prev, curr : TPlink;
hashCode : integer;
begin
if search(word)='' then
begin
ShowMessage('Данный элемент отсутствует в списке!');
exit;
end;
hashCode:=hashing (word);
curr:=h[hashCode].head;
prev:=nil;
while curr<>nil do
begin
if curr^.word = word
then begin
if prev = nil
then begin
h[hashCode].head:= curr^.next;
end else
prev^.next:=curr^.next;
ShowMessage('Элемент удален!');
h[hashCode].check:= h[hashCode].check - 1;
dispose(curr);
exit;
end;
prev:=curr;
curr:=curr^.next;
end;
end;
procedure TForm2.Button1Click(Sender: TObject); // добавить
var
word:string;
begin
if edit1.text='' then ShowMessage ('Ошибка ввода!');
word:= edit1.text;
addHash(word);
end;
procedure TForm2.Button2Click(Sender: TObject); // Удалить
var
word:string;
begin
if edit3.text='' then ShowMessage ('Ошибка ввода!');
word:= edit3.text;
delhash(word);
end;
procedure TForm2.Button3Click(Sender: TObject); // поиск
var
word:string;
begin
if edit4.text='' then ShowMessage ('Ошибка ввода!');
word:= search(edit4.text);
if word=''
then ShowMessage('Элемент не найден!')
else
ShowMessage('Найдено слово: ' + edit4.text + '. Хеш код: ' + word + '.');
end;
procedure TForm2.Button5Click(Sender: TObject); // Обновить табл
var
curr: TPlink; // текущий элемент списка
i,n:integer;
begin
//StringGrid1.clear;
n:=1;
for i:=0 to Length(h) do
if h[i].check > 0 then begin
curr:= h[i].head;
while curr<>nil do begin
if curr^.word <> '' then
n:=n+1;
StringGrid1.RowCount:=n;
StringGrid1.Cells [0,n-1]:= curr^.word;
StringGrid1.Cells [1,n-1]:= inttostr(i);
StringGrid1.Cells [2,n-1]:= inttostr(h[i].check);
curr:=curr^.next
end;
end;
if n=1 then begin
StringGrid1.RowCount:=n+1;
StringGrid1.Cells [0,n]:= '';
StringGrid1.Cells [1,n]:= '';
StringGrid1.Cells [2,n]:= '';
end;
end;
procedure TForm2.MenuItem2Click(Sender: TObject); // задание
begin
ShowMessage('На основе динамических списков необходимо реализовать словарь.' +
'Реализовать выполнение операций поиска, вставки и удаления данных' +
'словаря. В сочетании со списками для построения словарей требуется ис-' +
'пользовать открытое хеширование данных.');
end;
end.
Листинг Задания 2:
unit Unit3;
{$mode objfpc}{$H+}