我正在尝试实现一个简单的符号表,该表根据哈希值将字符串存储在哈希表中。我程序中的哈希表是一个指向链表的指针数组。我们有6个链接列表对应每个哈希值。
问题在于,虽然程序运行,但它会在每次迭代中用新字符串替换旧字符串。
我的代码是..
struct node{
char *string;
struct node *next;
};
struct node *hashtable[6];
int calchash(char *arr);
main()
{
char *line, a='n';
int val, i;
do{
printf("Enter string:\n");
scanf("%s", line);
struct node *current;
struct node *q= (struct node*)malloc(sizeof(struct node));
q->string = line;
q->next = NULL;
val= calchash(line);
if(hashtable[val] == NULL)
{
hashtable[val] = q;
current =q;}
else{
current->next = q;
current = q;
}
printf("Node created\n");
for(i=0; i<6; i++)
{ printf("Hash value %d :\n", i);
if(hashtable[i]==NULL)
{printf("No STRINGS!\n\n");}
else
{struct node *t = hashtable[i];
while(t != NULL)
{printf("%s \n", t->string);
t = t->next;}
printf("\n\n");
}
}
printf("CONTINUE(y/n):\n");
scanf(" %c", &a);
}while(a!='n');
}
int calchash(char *arr)
{int i=0, ascii;
int sum=0;
while(arr[i] != '\0')
{ascii = arr[i];
if(ascii>=48 && ascii<=57)
{
sum+= 2*ascii;}
else
{sum=sum+ ascii;}
i++;
}
return ((sum*17+5)%6);
}
输出是: 输入字符串: az9
创建节点
哈希值0: 没有STRINGS!
哈希值1: 没有STRINGS!
哈希值2: az9
哈希值3: 没有STRINGS!
哈希值4: 没有STRINGS!
哈希值5: 没有STRINGS!
CONTINUE(Y / N): ÿ
输入字符串: Az9
创建节点
哈希值0: 没有STRINGS!
哈希值1: 没有STRINGS!
哈希值2: Az9
哈希值3: 没有STRINGS!
哈希值4: Az9
哈希值5: 没有STRINGS!
CONTINUE(Y / N): Ñ
有人可以告诉我需要进行哪些更改,以便将之前的az9字符串保留在哈希值2下???
答案 0 :(得分:1)
if(hashtable[val] == NULL) {
hashtable[val] = q;
current =q;
} else {
current->next = q;
current = q;
}
应替换为:
q->next = hashtable[val];
hashtable[val] = q;
// no need for current
另外,通过任何未初始化的指针写入是UB,请先分配足够的空间。任何事情都可能发生......
答案 1 :(得分:1)
这怎么不立即崩溃? line
和hashtable
均未初始化。
您需要将字符串的副本放入每个散列节点,可能使用strdup
。目前,所有节点都指向与line
相同的字符串缓冲区,因此当您将新字符串读入line
时,所有节点都会看到它。这就是您必须为每个节点复制字符串的原因。我想知道缓冲区的最终位置,因为你从未初始化line
...
另外,current
是什么?它是循环的本地,并且看起来是不必要的。您应该将新节点链接到存储桶的头部,这样您就不需要检查存储桶是否为空。
插入也不会检查字符串是否已存在,因此您将插入重复项。