【问题标题】:Symbol table implementation using hash table in C使用 C 中的哈希表实现符号表
【发布时间】:2014-04-02 16:31:14
【问题描述】:

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

哈希值 1 : 没有字符串!

哈希值 2 : az9

哈希值 3 : 没有字符串!

哈希值 4 : 没有字符串!

哈希值 5 : 没有字符串!

继续(是/否): 是的

输入字符串: 阿兹9

节点创建

哈希值 0 : 没有字符串!

哈希值 1 : 没有字符串!

哈希值 2 : 阿兹9

哈希值 3 : 没有字符串!

哈希值 4 : 阿兹9

哈希值 5 : 没有字符串!

继续(是/否): n

有人可以告诉我需要进行哪些更改才能将之前的 az9 字符串保留在哈希值 2 下???

【问题讨论】:

  • 请正确格式化。
  • 你知道多余的强制转换是不好的形式,而且往往会扼杀编译器吗?永远不要转换malloc() 的返回值。尝试在启用所有警告的情况下进行编译,并正确修复警告如何?
  • 这是在什么平台上运行的?

标签: c arrays pointers linked-list


【解决方案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,请先分配足够的空间。任何事情都可能发生......

【讨论】:

    【解决方案2】:

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

    您需要复制字符串以进入每个哈希节点,可能使用strdup。目前,所有节点都指向与line 相同的字符串缓冲区,因此当您将新字符串读入line 时,所有节点都会看到它。这就是为什么您必须为每个节点复制字符串的原因。我想知道缓冲区在哪里结束,因为您从未初始化 line...

    另外,current 是什么?它在循环中是本地的,似乎没有必要。您应该将新节点链接到存储桶的头部,因此您无需检查存储桶是否为空。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-02-13
      • 2011-01-30
      • 2012-05-27
      • 2017-03-20
      • 1970-01-01
      • 2011-09-05
      • 2012-10-30
      相关资源
      最近更新 更多