Скачиваний:
23
Добавлен:
02.05.2014
Размер:
182.78 Кб
Скачать

Уфимский Государственный Авиационный

Технический Университет

кафедра АПРиС

Лабораторная работа №1

Работа с таблицей символов

Выполнил: студент гр. Т28-421

Проверила: Пузырникова Е.А.

Уфа 2006

Задание

Разработать программу, реализующую комбинированный способ организации таблицы идентификаторов. Для организации таблицы используется простейшая хэш-функция, указанная в варианте задания, а при возникновении коллизий используется дополнительный метод размещения идентификаторов в памяти. Если в качестве этого метода используется дерево или список, то они должны быть связаны с элементом главной хэш-таблицы.

В каждом варианте требуется, чтобы программа сообщала среднее число коллизий и среднее количество сравнений, выполненных для поиска идентификатора.

Тип хэш-функции (таблицы)

Способ разрешения коллизий

9.

Сумма кодов первой и последней букв

Упорядоченный список с логарифмическим поиском

 

Текст программы

#include <iostream.h>

#include <fstream.h>

#include <math.h>

const int maxAddr=367;

class Table

{

public:

Table(int initTable);

~Table();

void removeRec(int addr);

void createRec(int addr, char ident[40], char prop[20]);

char* GetRecId(int addr);

char* GetRecProp(int addr);

bool GetRecEF(int addr);

void PrintRec(int addr);

int GetRecLink(int addr);

void FillRecLink(int addr, int link);

int HashTab[maxAddr];

private:

bool EmptyFlag[maxAddr];

char Ident[maxAddr][40];

char Property[maxAddr][20];

int Links[maxAddr];

};

Table::Table(int initTable)

{

for (int i=0; i<initTable; i++)

{

EmptyFlag[i]=true;

for(int j=0; j<40; j++) Ident[i][j]=NULL;

for( j=0; j<40; j++) Property[i][j]=NULL;

for(int e=0; e<367; e++) Links[e]=400;

for( e=0; e<367; e++) HashTab[e]=500;

}

}

Table::~Table()

{

}

bool Table::GetRecEF(int addr)

{

return EmptyFlag[addr];

}

char* Table::GetRecId(int addr)

{

return Ident[addr];

}

char* Table::GetRecProp(int addr)

{

return Property[addr];

}

int Table::GetRecLink(int addr)

{

return Links[addr];

}

void Table::FillRecLink(int addr, int link)

{

Links[addr]=link;

}

void Table::createRec(int addr, char ident[40], char prop[20])

{

for (int k=0; k<40; k++) Ident[addr][k]=ident[k];

for (int j=0; j<20; j++) Property[addr][j]=prop[j];

EmptyFlag[addr]=false;

};

void Table::removeRec(int addr)

{

EmptyFlag[addr]=true;

for (int k=0; k<40; k++) Ident[addr][k]=NULL;

for (int j=0; j<20; j++) Property[addr][j]=NULL;

}

void Table::PrintRec(int addr)

{

cout<<"| "<<addr<<"| ";

for(int i=0; i<40; i++) cout<<Ident[addr][i]; cout<<"|";

for(i=0; i<20; i++) cout<<Property[addr][i]; cout<<"|";

}

bool ElExist(char id_fromFile[40], Table T1);

bool ElExist(char id_fromFile[40], Table T1)

{

int fHashF, fa, t=0,fAddr, fnAddr, Nm=367, f_last=0, fCountAttempt=0, Compar=0;

for (int e=0; e<40; e++)

{ //подсчет количества символов в идентивикаторе

if (int(id_fromFile[e])!=NULL) f_last++;

};

fHashF=int(id_fromFile[0])+int(id_fromFile[f_last-2])+int(id_fromFile[f_last-1]);

if(T1.HashTab[fHashF]==500) cout<<" There is no such dentifier! "<<endl;

else

{

fa=T1.HashTab[fHashF];

while( int(id_fromFile[t]) >= int(T1.GetRecId(fa)[t]))

{

m1: if(int(id_fromFile[t]) == int(T1.GetRecId(fa)[t]))

{

t++;

if(t==f_last)

{

cout<<" This ID successfully found! Its addr: "<<fa

<<"\n There were(was) "<<Compar<<" comparision(s)."<<endl;

return true; break;

};

continue;

}

else

{

fa=T1.GetRecLink(fa); Compar++;

if(fa==400) {cout<<" There is no such dentifier! "<<endl; return false;}

else goto m1;

}

t=0;

}

while( int(id_fromFile[t]) <= int(T1.GetRecId(fa)[t]))

{

m2: if(int(id_fromFile[t]) == int(T1.GetRecId(fa)[t]))

{

t++;

if(t==f_last)

{

cout<<" This ID successfully found! Its addr: "<<fa<<endl;

return true; break;

};

continue;

}

else

{

fa=T1.GetRecLink(fa); Compar++;

if(fa==400) {cout<<" There is no such dentifier! "<<endl; return false;}

else goto m2;

};

t=0;

}

}

}

void main()

{

while(true){

const int arraySize1=40, arraySize2=41, mA=367;

Table TableID(mA);

char FileName[40];

cout<<"Enter file name, which must be written: ";

cin>>FileName;

char ID[arraySize1][arraySize2]={NULL};

int d=0, e=0;

ifstream ReadFromFile(FileName);

cout<<" Content of file "<<FileName<<endl;

char ch; int QuantOfID=0;

while (ReadFromFile.get(ch))

{

if (ch!=' ')

{

ID[d][e]=ch;

e++;

}

else {d++; e=0; QuantOfID++;};

};

ReadFromFile.close();

for (d=0; d<=QuantOfID; d++)

{

cout<<"ID["<<d<<"]";

for (e=0; e<arraySize2; e++)

{

cout<<ID[d][e];

}

cout<<"\n";

}

cout<<" Table of IDs, which was built by rehash:"<<endl;

d=0; int last=0, sch=0, oldHashF=0, a=0, b=0, pointer=0; const Nm=367;

int HashF, CountColl=0, el=0, y=0, AverColl;

char NullStr[20][20]={NULL}; //инициализация пустой строки для подстановки вмеcто Property

char Reh[1][12]={NULL,NULL,'r','e','h','a','s','h','!'};

bool Coll[200]; for (e=0;e<200;e++) Coll[e]=false;

while (sch<=QuantOfID)

{

//if (ElExist(ID[d], TableID, Verific)==false)

// {

for ( e=0; e<40; e++)

{ //подсчет количества символов в идентивикаторе

if (int(ID[d][e])!=0) last++;

};

HashF=int(ID[d][0])+int(ID[d][last-2])+int(ID[d][last-1]);

if(TableID.HashTab[HashF]==500 ) {a=pointer; TableID.HashTab[HashF]=a;}

else a=TableID.HashTab[HashF];

TableID.HashTab[HashF]=a;

int i=a; b=0;

if (TableID.GetRecEF(a) == true)

{

TableID.createRec(a, ID[d], NullStr[1]);

while (TableID.GetRecEF(pointer)==false)

{

pointer++; //ищем след. свободную ячейку

};

}

else

{

while (TableID.GetRecEF(pointer)==false)

{

pointer++; //ищем след. свободную ячейку

};

while(TableID.GetRecLink(i)!=400)

{

i=TableID.GetRecLink(i); //если ссылка есть, то переходим по ней,т.е.определяем последн.

};

CountColl++;

Coll[a]=true;

do{

TableID.createRec(pointer, TableID.GetRecId(i), NullStr[1]);

TableID.removeRec(i);

TableID.FillRecLink(i,pointer);

while(TableID.GetRecLink(b)!=i)

{

b++;

if(b==367) break;

};

if(b==367) break;

pointer=i;

i=b; b=0;

}

while(b!=500);

TableID.createRec(i, ID[d], NullStr[1]);

/*TableID.PrintRec(i);*/ pointer=0;

while (TableID.GetRecEF(pointer)==false)

{

pointer++;

};

}

sch++; d++; last=0; //a++;

}

for (e=0; e<=QuantOfID; e++)

{

TableID.PrintRec(e);

if(TableID.GetRecLink(e)==400) cout<<" "<<endl;

else cout<<TableID.GetRecLink(e)<<endl;

}

for (e=0; e<200; e++) { if (Coll[e]==true) el++;}

AverColl=CountColl/el;

cout<<" Average quantity of collisions is "<<AverColl<<endl;

cout<<"\nEnter ID, which you can find: ";

char FindElem[40]={' '};

cin>>FindElem;

ElExist(FindElem, TableID);

cout<<"If you want to restart program press 1\n else press another key"<<endl;

cin>>e; if(e==1) continue; else break;

}

}

Блок-схема алгоритма добавления элемента

Блок-схема алгоритма поиска

Результаты выполнения программы

Вывод

В результате работы программы на экран выводится содержимое файла, из которого осуществляется чтение, затем содержимое таблицы идентификаторов, заполнение которой осуществлялось по методу, заданному в варианте задания. Также на экран выводится среднее число коллизий, возникших в результате заполнения таблицы. После поиска выводится число сравнений, произошедших при выполнении данной функции.