C/C++
Задание: хеш-таблица с мультипликативной хеширующей функцией (метод умножения) и решением коллизий внутренними (срастающимися) цепочками.
вот, что у меня получилось
Код:
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#define table_items 17 // число элементов таблицы
#define M 32 // размер таблицы
typedef struct
{
char* k;
char* p;
} tab_elem;
tab_elem table[M];
tab_elem tabtemp = table[0];
int Get_index(char* str)
{
int result = 0;
int x = 0;
while (str[x] != '\0')
{
result += (int) str[x]; // Переводим из char в int
x++;
}
result = (31 * (result))>>(16-6); // h = (A * K) >> (w - m)
//return (int) keyword;
return (int) result;
}
void make_table (char* items[table_items]) //создание таблицы
{
int Index;
int i, j, h, b=0;
tab_elem *pointer; // Указатель на элемент
for (i=0; i<M; i++) //Очищаем таблицу
{
table[i].k=""; //В поле ключа помещаем признак незанятости
table[i].p=NULL; //указатели на null
}
for (i=0; i<table_items; i++) //заполнение таблицы
{
h = Get_index(items[i]); // Вызов генератора ключа
if (table[h].k=="") // пустота элемента
{
table[h].k=items[i];
}
else
{
b++; //считаем коллизии
if (table[h].p == NULL) // ищем пустую таблицу
{
j=h;
do
{
j++;
}while (table[j].k != ""); //первый пустой ключ
table[j].k = items[i];
table[h].p=(char*)&table[j]; // указатель с текущей таблицы на первую пустую найденную
}
else
{
pointer = (tab_elem*)table[h].p;
while (pointer->p != NULL) // поиск первого пустого указателя
{
pointer=(tab_elem*)pointer->p;
}
j=h;
do
{
j++;
}while (table[j].k!=""); //первый пустой ключ
table[j].k = items[i];
pointer->p = (char*)&table[j]; // указатель с текущей таблицы на первую пустую найденную
}
}
}
std::cout<<"coll="<<b<<"\n";
printf("---HASH_TABLE---\n\n"); //печатаем таблицу
for (i=0; i<M; i++)
{
printf("%i: %s\n", &tabtemp - &table[i], table[i].k);
}
}
void Check_Hash_Table(char* u_key)
{
int u_h;
tab_elem *pointer;
printf("\nFIND \"%s\"\n", u_key);
u_h = Get_index(u_key);
if (table[u_h].k==u_key) // поиск по ключу
{
printf("%i: %s\n", &tabtemp - &table[u_h] , u_key);
}
else
{
if (table[u_h].p==NULL) // поиск по указателю
{
printf("None\n");
}
else
{
pointer = (tab_elem*)table[u_h].p;
while (pointer->p!=NULL)
{
if (pointer->k==u_key)
{
printf("%i: %s\n", &tabtemp - pointer,u_key);
}
pointer = (tab_elem*)pointer->p;
}
printf("None\n");
}
}
}
int main()
{
char* items[table_items] =
{
"START","BYTE","WORD","RESB",
"RESW","END","CMP","MOV","NOT",
"ADD","XOR","OR","TEST","DIV","MUL",
"PUSH","POP"
};
make_table(items);
Check_Hash_Table("ADD");
Check_Hash_Table("OR");
Check_Hash_Table("JNE");
Check_Hash_Table("START");
Check_Hash_Table("BYTE");
Check_Hash_Table("CMP");
system("pause");
}
Но число коллизий слишком большое. Я и с числами в result = (31 * (result))>>(16-6); извращался, и размер таблицы менял, не помогает. Кто знает, что делать, помогите пожалуйста.