2015-07-12 76 views
2

我无法实现我的哈希表插入函数。插入函数哈希表C

所以我实现了一些测试调用,我只是单独调用函数。对于实际使用,我在while循环中调用该函数。为了测试目的,我只运行循环4次。

我在下面发布一些输出。表格看起来很奇怪的原因是因为我的散列函数。它散列了A = 1,B = 2,C = 3等字。这个词在这个词中的位置是不相关的,因为我会考虑这个词的排列。此外,该字母的情况在这个问题中也是无关紧要的,所以a的值= A = 1的值。

对于字符串,abc = 1 + 2 + 3 = 6,bc = 2 + 3 = 5等

总的来说,散列函数没有问题。问题是插入功能。

我本地字典的前4个字是A,A,AA,AB's。

我的预期输出应该是(我得到了相同的输出,当我运行测试话费):

0: 
1: [W: A, Len:1] 
2: 
3: 
... 
18: 
19: 
20: [W: A's, Len:3] 
21: [W: AA's, Len:4] 
22: [W: AB's, Len:4] 

但是,当我叫一个循环中的作用,最后名单上无论是将覆盖其他项目。如果我运行循环100次,那么最后一项还取代了以前的(注意单词的长度如何不变,但只有一行字被替换):

0: 
1: [W: AB's, L:1] 
2: 
3: 
... 
18: 
19: 
20: [W: AB's, Len:3] 
21: [W: AB's, Len:4] 
22: [W: AB's, Len:4] 

下面是我的代码:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

int hash(char *word) 
{ 
    int h = 0; 

    while(*word != '\0') 
    { 
     if(*word >='A' && *word < 'A'+26) { 
     h=h+(*word -'A' + 1); 
     } 
     else if(*word >='a' && *word < 'a'+26) { 
     h=h+(*word -'a' + 1); 
     } 
     //else { // special characters 
     // return -1; 
     //} 

     word++; 
    } 

    return h; 
} 

typedef struct Entry { 
    char *word; 
    int len; 
    struct Entry *next; 
} Entry; 

#define TABLE_SIZE 1000 // random numbers for testing 

Entry *table[TABLE_SIZE] = { NULL }; // an array of elements 

void init() { 
    int i; 

    for (i = 0; i < TABLE_SIZE; i++) { 
     // initialize values 
     struct Entry *en = (struct Entry *)malloc(sizeof(struct Entry)); 

     en->word = ""; 
     en->len = 0; 
     en->next = table[i]; 
     table[i] = en; 
    } 
} 

//Insert element 
void insertElement(char *word, int len) { 
    int h = hash(word); 
    int i; 

    // because all words are different so there is no need to check for duplicates 
    struct Entry *en = (struct Entry *)malloc(sizeof(struct Entry)); 

    en->word = word; 
    en->len = len; 
    en->next = table[h]; 
    table[h] = en; 
} 

void cleanTable() 
{ 
    struct Entry *p, *q; 
    int i; 

    for(i=0; i<TABLE_SIZE; ++i) 
    { 
     for(p=table[i]; p!=NULL; p=q) 
     { 
     q = p->next; 
     free(p); 
     } 
    } // for each entry 
} 

int main() { 
    init(); // create hash table 

    // test calls produce correct output 
    //insertElement("A", (int)strlen("A")); 
    //insertElement("A's", (int)strlen("A's")); 
    //insertElement("AA's", (int)strlen("AA's")); 
    //insertElement("AB's", (int)strlen("AB's")); 

    int i; 
    i = 0; 

    FILE* dict = fopen("/usr/share/dict/words", "r"); //open the dictionary for read-only access 
    if(dict == NULL) { 
     return;      
    } 

    // Read each line of the file, and insert the word in hash table 
    char word[128];  
    while(i < 4 && fgets(word, sizeof(word), dict) != NULL) { 
     size_t len = strlen(word); 
     if (len > 0 && word[len - 1] == '\n') { 
     word[len - 1] = '\0'; // trim the \n 
     } 

     insertElement(word, (int)strlen(word)); 

     i++; 
    } 

    for (i=0; i < 50; i++) 
    { 
     printf("%d: ", i); 

     struct Entry *enTemp = table[i]; 

     while (enTemp->next != NULL) 
     { 
     printf("[W: %s, Len:%d] ", enTemp->word, enTemp->len); 
     enTemp = enTemp->next; 
     } 

     printf("\n"); 
    } 

    cleanTable(); 

    return 0; 
} 

回答

2

尝试重新分配在每个循环的记忆中这部分代码:

char* word = malloc(sizeof(char)*128);  
while(i < 4 && fgets(word, sizeof(word), dict) != NULL) { 
    size_t len = strlen(word); 
    if (len > 0 && word[len - 1] == '\n') { 
     word[len - 1] = '\0'; // trim the \n 
    } 
    insertElement(word, (int)strlen(word)); 
    word = malloc(sizeof(char)*128); 
    i++; 
} 

你忘了重新分配内存的每一个导致所有的指针点相同的点串

注:未测试

2

通知您insertElement得到一个指向一个字符串,该指针分配给当前进入,但它的主要功能,您通过参数(一个指针)指向堆栈分配的字符串,并且该字符串在每次读取一个单词后都会更改。您必须使用malloc以便每个指向它自己的内存区域