我试图将单词插入哈希表中。当我运行代码时,它应该给我一个每个单词的频率列表,但它只是给了我什么。
我确定这与我的打印功能或插入功能有关,可能更多是我的插入功能。我知道这不是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;
}
答案 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;