插入哈希表

时间:2012-08-29 01:26:48

标签: c hashtable

我试图将单词插入哈希表中。当我运行代码时,它应该给我一个每个单词的频率列表,但它只是给了我什么。

我确定这与我的打印功能或插入功能有关,可能更多是我的插入功能。我知道这不是mylib.h,但我不知道我哪里出错了。

它不会在我的表格中插入任何内容或打印它。我不确定发生了什么。

hashtable.c:

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

    struct htablerec {
       char **key;
       int *frequencies;
       int num_keys;
       int capacity;
    };

    void *emalloc(size_t s) {
       void *result = malloc(s);
       if (NULL == result) {
          fprintf(stderr, "Memory allocation failed!\n");
          exit(EXIT_FAILURE);
       }
       return result;
    }

    htable htable_new(int capacity) {
       int i;
       htable h = emalloc(sizeof * h);
       h->capacity = capacity;
       h->num_keys = 0;
       h->frequencies = emalloc(h->capacity * sizeof h->frequencies[0]);
       h->key = emalloc(h->capacity * sizeof h->key[0]);
       for (i = 0; i < h->capacity; i++) {
          h->frequencies[i] = 0;
          h->key[i] = NULL;
       }
       return h;
    }

    void htable_free(htable h) {
       free(h->frequencies);
       free(h->key);
       free(h);
    }

    static unsigned int htable_word_to_int(char *word) {
       unsigned int result = 0;
       while (*word != '\0') {
          result = (*word++ + 31 * result);
       }
       return result;
    }

    int htable_insert(htable h, char *str) {
       int i;
       /*convert string to integer*/
       unsigned int index = htable_word_to_int(str);
       /*calculate index to insert into hash table*/
       int remainder = index%h->capacity;
       /*once calculated position in the hash table, 3 possibilities occur*/
       /*no string in this positon, copy string to that position, increment number of keys, return 1*/
       if (h->key[remainder] == NULL) {
          h->frequencies[remainder] = 1;
          h->num_keys++;
          return 1;
       }
       /*the exact same string is at the position, increment frequency at that position, return frequency*/
       if (strcmp(str, h->key[remainder]) == 0) {
          h->frequencies[remainder]++;
          return h->frequencies[remainder];
       }/*a string is at that position, but it isnt the rightone, keep moving along the array
       until you find either an open space or the string you are looking for*/
       if (h->key[remainder] != NULL && strcmp(str, h->key[remainder]) != 0) {
       /*you may need to wrap back around to the beginning of the table, so each time you add
       to the position you should also mod by the table capacity.*/
          for (i = 0; i <= h->capacity; i++) {
             if (h->key[remainder] != NULL && h->capacity ==  i) {
                i = 0;
                }
                /*no string in this positon, copy string to that position, increment number of keys*/
                if (h->key[remainder] == NULL) {
                h->frequencies[remainder] = 1;
                h->num_keys++;
             }
             /*if you find the string you were looking for, increment the frequecny at the position
             and return the frequency*/
             if (strcmp(str, h->key[remainder]) == 0) {
                h->frequencies[remainder]++;
                return h->frequencies[remainder];
             }
          }   
       }
       /*if you have kept looking for an open space but there isnt one, the hash table must be full so return 0*/
       return 0;
    }

    void htable_print(htable h, FILE *stream) {
       int i;
       for(i = 0; i < h->capacity; i++) {
          if(h->key[i] != NULL) {
             fprintf(stream, "%d%s\n", h->frequencies[i], h->key[i]);
          }
       }
    }

htable.h:

#ifndef HTABLE_H_
#define HTABLE_H_

#include <stdio.h>

typedef struct htablerec *htable;

extern void htable_free(htable h);
extern int htable_insert(htable h, char *str);
extern htable htable_new(int capacity);
extern void htable_print(htable h, FILE *stream);
extern int htable_search(htable h, char *str);

#endif

mylib.c:

#include <stdio.h>
#include <stdlib.h>
#include "mylib.h"
#include "htable.h"

int main(void) {
   htable h = htable_new(18143);
   char word[256];

   while (getword(word, sizeof word, stdin) !=EOF) {
      htable_insert(h, word);
   }

   htable_print(h, stdout);
   htable_free(h);

   return EXIT_SUCCESS;
}

mylib.h:

#include <assert.h>
#include <ctype.h>
#include <stdio.h>

int getword(char *s, int limit, FILE *stream) {
   int c;
   char *w = s;
   assert(limit > 0 && s != NULL && stream != NULL);

   /*skip to the start fo the word */
   while (!isalnum(c = getc(stream)) && EOF != c)
      ;
   if(EOF == c) {
      return EOF;
   } else if (--limit > 0) { /*reduce limit by 1 to allow for the \0 */
      *w++ = tolower(c);
   }

   while(--limit > 0) {
      if(isalnum(c = getc(stream))) {
         *w++ = tolower(c);
      } else if ('\'' == c) {
         limit++;
      } else {
            break;
         }
      }
      *w = '\0';
      return w - s;
   }

2 个答案:

答案 0 :(得分:1)

您永远不会将h->key[remainder]设置为htable_insert中的任何内容,因此当您致电h->key[i]时,所有NULL的{​​{1}}仍为i。< / p>

答案 1 :(得分:1)

/*no string in this positon, copy string to that position, increment number of keys, return 1*/
if (h->key[remainder] == NULL) {
   h->frequencies[remainder] = 1;
   h->num_keys++;
   return 1;
}
...
/*no string in this positon, copy string to that position, increment number of keys*/
if (h->key[remainder] == NULL) {
    h->frequencies[remainder] = 1;
    h->num_keys++;
}

你永远不会复制字符串。尝试类似......

char *key = emalloc(strlen(str) + 1);
strcpy(str, key);
h->key[remainder] = key;