2012-08-29 5 views
0

J'essaie d'insérer des mots dans une table de hachage. Quand je lance le code, c'est censé me donner une liste de la fréquence de chaque mot, mais ça ne me donne rien.Insertion dans une table de hachage

Je suis sûr que c'est soit avec ma fonction d'impression, ou ma fonction d'insertion, probablement plus ma fonction d'insertion. Je sais que ce n'est pas mylib.h, mais je ne sais pas trop où je vais mal.

Il n'insère rien dans ma table ou ne l'imprime pas. Je ne suis pas vraiment sûr de ce qui se passe.

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; 
} 

malib.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; 
    } 
+0

Si vous n'êtes pas sûr de ce qui se passe, lancez votre débogueur et de mettre un point d'arrêt dans la fonction 'htable_insert' et étape par la fonction à la fois une ligne de code. – markgz

Répondre

1

Vous ne définissez jamais h->key[remainder] à rien dans htable_insert, alors h->key[i] est toujours NULL pour tous i lorsque vous appelez htable_print.

+0

donc quand je définis int reste = index% h-> capacité; je dois mettre h-> clé [reste] à reste? vous pensez que cela résoudrait mon problème? – courtney

+0

Basé sur le reste du code, il semble que chaque fois que vous appelez h-> num_keys ++, vous devez également définir h-> key [reste] sur la chaîne que vous ajoutez. (Il semble vraiment que la chose que vous appelez reste est la clé de la hashmap, et vous avez utilisé h-> key [i] comme si elle stockait la valeur dans la hashmap.) – David

+0

Je suis désolé, vous êtes sorte de me confondre. le reste est supposé travailler sur la position dont nous allons finir dans la table de hachage, le i est un compteur qui contourne la table de hachage, et reboucle au début si nous atteignons la fin de la table de hachage . Je ne suis pas vraiment sûr de ce que vous essayez de dire. – courtney

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++; 
} 

Vous ne copier la chaîne. Essayez quelque chose comme ...

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

Omg, moi non plus! Je vous remercie. – courtney

Questions connexes