我第一次使用哈希表,我想我对它们的工作原理有了基本的了解。我正在使用哈希表来检查文件中是否存在单词。该程序接收一个“字典”文件和一个单词检查文件。当我有一本小字典时,该程序运行良好,但当我使用非常大的字典时,单词会被覆盖。我希望能对原因有所了解。这是我的代码:
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <pthread.h>
#include <tgmath.h>
#include <ctype.h>
#include "hashtable_constants.h"
#define HASH_SIZE 500
#define MAX_WORD_SIZE 50
struct hashTable {
int collisions;
char** words;
};
struct hashTable hashTables[HASH_SIZE];
int hashKey(char * str)
{
int key = 0;
for(int j = 0; j <= 51; j++)
{
if(str[j] == '\0')
break;
key += (int)str[j];
}
key = key % HASH_SIZE;
return key;
}
int main(int argc, char** argv)
{
if(argc > 3)
{
fprintf(stderr, "Too many arguments!\n");
return -1;
}
else if(argc < 3)
{
fprintf(stderr, "Not enough arguments!\n");
return -1;
}
FILE *dictionary = fopen(argv[1], "r");
FILE *wordCheck = fopen(argv[2], "r");
if(dictionary == NULL || wordCheck == NULL ) //ensure input file exists
{
fprintf(stderr, "Error accessing input files\n");
return -1;
}
for(int i = 0; i < HASH_SIZE; i++)
{
hashTables[i].collisions = 0;
hashTables[i].words = malloc(HASH_SIZE * MAX_WORD_SIZE);
}
struct stat fileStat1;
struct stat fileStat2;
stat(argv[1], &fileStat1);
stat(argv[2], &fileStat2);
char* dictBuffer = (char*)malloc(fileStat1.st_size + 1);
char* wordCheckBuff = (char*)malloc(fileStat2.st_size + 1);
if (dictBuffer == NULL || wordCheckBuff == NULL)
{
fprintf (stderr, "Memory error");
return -1;
}
fread(dictBuffer, 1, (int)fileStat1.st_size, dictionary);
fread(wordCheckBuff, 1, (int)fileStat2.st_size, wordCheck);
char* word = malloc(MAX_WORD_SIZE + 1);
int count = 0;
for(int i = 0; i < (int)fileStat1.st_size; i++)
{
char c = dictBuffer[i];
if(isspace(c))
{
word[count] = '\0';
char* wordToAdd = word;
int key = hashKey(wordToAdd);
int collisionIndex = hashTables[key].collisions;
hashTables[key].words[collisionIndex] = wordToAdd;
hashTables[key].collisions++;
count = 0;
free(word);
word = malloc(MAX_WORD_SIZE + 1);
//printf("Added: %s to hashtable at key: %d\n",word,key);
}
else
{
word[count] = c;
count++;
}
}
count = 0;
for(int i = 0; i < (int)fileStat2.st_size; i++)
{
char c = wordCheckBuff[i];
if(isspace(c))
{
word[count] = '\0';
char* wordToCheck = word;
int key = hashKey(wordToCheck);
int collisionIndex = hashTables[key].collisions;
int foundWord = 0;
for(int j = 0; j < collisionIndex; j++)
{
if(hashTables[key].words[j] == wordToCheck)
{
printf("%s == %s\n",hashTables[key].words[j], wordToCheck);
foundWord = 1;
break;
}
}
if(foundWord == 0)
printf("Not a word: %s\n", wordToCheck);
/*else
printf("Key: %d -- Is a word: %s\n",key, word);*/
free(word);
word = malloc(MAX_WORD_SIZE + 1);
count = 0;
}
else
{
word[count] = c;
count++;
}
}
for(int i = 0; i < HASH_SIZE; i++)
free(hashTables[i].words);
free(word);
fclose(dictionary);
fclose(wordCheck);
printf("done\n");
return 0;
}