【发布时间】:2014-01-03 07:32:23
【问题描述】:
作为练习(我是学生),我正在 C 中实现一个基本的 string 到 int 哈希表。我(我认为)一切正常,除了 print table function。它开始工作,但 Windows 在打印出一个存储桶的三个条目后说 “hashtable.exe 已停止工作”,我知道其他的都是有效的,因为我可以在命令提示符下检索它们的值我有的东西。这是我的代码,任何建议都很有价值:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
const char ESC_STRING[] = "zzzz";
struct a_container {
char *string;
int value;
struct a_container *next;
};
typedef struct a_container Container;
struct c_list {
Container **arr;
int size;
int bits;
};
typedef struct c_list Table;
void print_entry(Container *c) {
printf("%s%s%d", c -> string, ", ", c -> value);
}
void print_table(Table *t) {
Container *e;
int i;
int length = t -> size;
printf("%d\n", length);
for(i = 0; i < length; i++) {
printf("%d\n", i);
if(t -> arr[i] == NULL) printf("%s\n", "Null bucket.");
for(e = t -> arr[i]; e != NULL && e -> string != NULL; e = e -> next) {
print_entry(e);
}
}
}
Container *make_cont() {
Container *new;
new = malloc(sizeof(Container));
if(new == NULL) return NULL;
new -> next = NULL;
return new;
}
Container *make_entry(char *key, int value) {
Container *n = make_cont();
n -> string = key;
n -> value = value;
return n;
}
Table *make_table(int size) {
Table *tab = NULL;
int i;
int j = 2 << (size - 1);
if(size < 1) return NULL;
tab = malloc(sizeof(Table));
tab -> arr = malloc(sizeof(Container) * j);
for(i = 0; i < size; i++) {
tab -> arr[i] = NULL;
}
tab -> size = j;
tab -> bits = size;
return tab;
}
void associate(Table *hashtable, char *key, int value) {
int index = hash_index(hashtable, key, hashtable -> bits);
Container *e = NULL;
Container *n = NULL;
if(hashtable -> arr[index] == NULL) {
e = make_entry(key, value);
hashtable -> arr[index] = e;
return;
}
else {
e = hashtable -> arr[index];
n = make_entry(key, value);
hashtable -> arr[index] = n;
n -> next = e;
}
}
int retrieve(Table *hashtable, char *look) {
int index = hash_index(hashtable, look, hashtable -> bits);
Container *e = NULL;
//if(hashtable -> arr[index] == NULL) exit(1);
e = hashtable -> arr[index];
while(e != NULL && e -> string != NULL && strcmp(look, e -> string) > 0) {
e = e -> next;
}
if(e == NULL || e -> string == NULL || strcmp(look, e -> string) != 0) {
exit(1);
} else {
return e -> value;
}
}
//djb2 algorithm by dan bernstein
//http://www.cse.yorku.ca/~oz/hash.html
unsigned long hash_code(char *key) {
unsigned long hash = 5381;
int c;
while(c = *key++) {
hash = ((hash << 5) + hash) + c;
}
return hash;
}
int hash_index(Table *hashtable, char *query, int bits) {
unsigned long hashCode = hash_code(query);
unsigned int fold = 0;
unsigned int h;
int trim = 2 << (bits - 1);
int mask = trim - 1;
for(h = hashCode; h != 0; h >>= bits) {
fold ^= h;
}
fold &= mask;
return fold;
}
int main() {
char *i;
Table *hashtable = make_table(3);
associate(hashtable, "Erica", 323);
associate(hashtable, "Kitty", 18);
associate(hashtable, "Dawg", 3);
associate(hashtable, "Dahhhhhhg", 43);
associate(hashtable, "Kat", 7);
//print_table(hashtable);
while(1) {
printf("%s", "Look something up: ");
scanf("%s", i);
if(strcmp(i, ESC_STRING) == 0) break;
printf("%d\n", retrieve(hashtable, i));
}
return 0;
}
【问题讨论】:
-
你为什么用
Container **arr而不是Container *arr? -
请学习调试 -- 使用调试器和/或诊断 printfs。 SO 不能替代它。