在C中使用哈希表的符号表实现

时间:2014-04-02 16:31:14

标签: c arrays pointers linked-list

我正在尝试实现一个简单的符号表,该表根据哈希值将字符串存储在哈希表中。我程序中的哈希表是一个指向链表的指针数组。我们有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下???

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)

这怎么不立即崩溃? linehashtable均未初始化。

您需要将字符串的副本放入每个散列节点,可能使用strdup。目前,所有节点都指向与line相同的字符串缓冲区,因此当您将新字符串读入line时,所有节点都会看到它。这就是您必须为每个节点复制字符串的原因。我想知道缓冲区的最终位置,因为你从未初始化line ...

另外,current是什么?它是循环的本地,并且看起来是不必要的。您应该将新节点链接到存储桶的头部,这样您就不需要检查存储桶是否为空。

插入也不会检查字符串是否已存在,因此您将插入重复项。