Я пишу хеш-таблицу с линейным зондированием, но моя программа имеет ошибку. Моя задача - записать количество вхождений каждого слова в текст. Например, мой файл содержит следующие слова:Хэш-таблица с линейным зондированием
lol lol lol a c d
Выход является:
(Но d
не должно быть 2!) Это происходит, когда SIZE_OF_TABLE 10. И когда SIZE_OF_TABLE является 2 программа не работает. Правда результат должен быть:
lol = 3, a = 1, c = 1, d = 1.
Мой код:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#define MAX 10
#define SIZE_OF_TABLE 10
#define MAX_STRING 256
#define THAT_OCCUP 0
struct HT{
int amount;
int occup;//occupancy
char string[MAX_STRING];
};
unsigned int long hash(const char *str);
struct HT* init(int size);
struct HT* reHT(struct HT* table,int* size,char* word, int* occup);
struct HT* put(struct HT* table,char* word, int* size,int* occup);
int take(struct HT* table,char* word, int* size);
unsigned int long hash(const char *str) // hash function
{
int long hash = 5381;
int c = 0;
while (c == *str++)
hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
return hash;
}
struct HT* init(int size) // create a hash table
{
struct HT* table = (struct HT*)calloc(sizeof(struct HT*),size);
int i = 0;
if (size < 1)
return NULL;
if(NULL == table)
return NULL;
for (i = 0; i < size; ++i)
{
table[i].amount = 0;
table[i].occup = 1;
}
return table;
}
struct HT* reHT(struct HT* table,int* size,char* word, int* occup) //rehash
{
assert(table);
assert(word);
assert(size);
assert(occup);
table = (struct HT*)calloc(sizeof(struct HT*),(*size)*MAX);
int i = 0;
while (i < (*size)/MAX)
{
table = put(table, table[i].string, size, occup);
i++;
}
return table;
}
struct HT* put(struct HT* table,char* word, int* size,int* occup)
{
assert(table);
assert(word);
assert(size);
assert(occup);
int i = 0;
i = hash(word) % (*size);
if ((*occup) > ((*size)/2))
table = reHT(table, size, word, occup);
if(1 == table[i].occup) // if free put it
{
strcpy(table[i].string,word);
table[i].amount++;
table[i].occup = -1;
(*occup)++;
}
else if (-1 == table[i].occup && strstr(table[i].string,word)) // if place isnt free and it is a similar world just increase amount
table[i].amount++;
else if (-1 == table[i].occup && !strstr(table[i].string,word)) // if place isnt free and it the words arent similar then use linear probing
{
i++;
while(1)
{
i = (i + 1) % (*size);
if(table[i].occup == 1)
{
strcpy(table[i].string,word);
table[i].amount++;
table[i].occup = -1;
(*occup)++;
break;
}
else if (-1 == table[i].occup && strstr(table[i].string,word))
{
table[i].amount++;
break;
}
}
i = 0; // go to start and do the same thing
while(1)
{
if(1 == table[i].occup)
{
strcpy(table[i].string,word);
table[i].amount++;
table[i].occup = -1;
(*occup)++;
break;
}
else if (strstr(table[i].string,word) && table[i].occup == -1)
{
table[i].amount++;
break;
}
i++;
}
}
return table;
}
int take(struct HT* table,char* word, int* size) // take amount
{
assert(size);
assert(word);
assert(table);
int i = 0;
i = hash(word) % (*size);
while(i < (*size))
{
if(strstr(table[i].string, word))
return table[i].amount;
i++;
}
i = 0;
while(i < (*size))
{
if(strstr(table[i].string, word))
return table[i].amount;
i++;
}
return 0;
}
int main(int argc, char *argv[])
{
FILE* file = fopen("text.txt","r");
struct HT* table = NULL;
char string[256] = {0};
int size = SIZE_OF_TABLE;
int occup = THAT_OCCUP;
if (NULL == file)
return -1;
table = init(size); //create hash
if (NULL == table)
return - 1;
while(1 == fscanf(file, "%s", string)) // put words to hash table
{
table = put(table,string,&size,&occup);
}
printf("HASH_TABLE IS READY!!!!11111\n");
printf("Enter WORDS!!!1111\n");
while(1)
{
scanf("%s",string);
if(strstr(string,"END")) // if you want to stop just enter "END"
break;
printf(" KOLI4ESTVO!! = %d\n", take(table, string, &size));
}
free(table);
return 0;
}
Итак ... [отлаживать ваш код] (http://ericlippert.com/2014/03/05/how-to-debug-small-programs/)? – WhozCraig