【发布时间】:2018-10-08 18:09:23
【问题描述】:
我正在做一项作业,要求我打印给定文本文件中出现频率最高的 10 个单词。我的代码正在打印文件中的单词,但它没有根据它们的频率对它们进行排序。
下面是我的代码。我使用哈希表来存储每个唯一单词及其频率。我目前正在使用我编写的 wordcmp 函数对单词进行排序,并在 main 的内置 qsort 函数中调用它。
如果有人能指导我纠正我的错误,我将非常感激。
我目前的输出:
前 10 个单词(共 10 个)是:
1 即时消息
1 是
再来一次
3 开心
2 你好
1 如何
1 让
1 个你
1 次尝试
1 这个
预期输出(我想要的):
排名前 10 的单词(共 10 个)是:
3 开心
2 你好
1 个你
1 次尝试
1 这个
1 让
1 即时消息
1 如何
1 是
再来一次
这是我的一些代码:
typedef struct word
{
char *s; /* the word */
int count; /* number of times word occurs */
struct word* next;
}word;
struct hashtable
{
word **table;
int tablesize;
int currentsize;
};
typedef struct hashtable hashtable;
int main(int argc, char *argv[])
{
int top_words = 10;
word *word = NULL;
hashtable *hash = ht_create(5000);
char *file_name;
char *file_word;
FILE *fp;
struct word *present = NULL;
fp = fopen (file_name, "r");
if (fp == NULL)
{
fprintf (stderr,"%s: No such file or directory\n", file_name);
fprintf(stderr,"The top %d words (out of 0) are:\n", top_words);
exit(-1);
}
continue_program:
while ((file_word = getWord(fp)))
{
word = add(hash, file_word, 1);
}
fclose(fp);
qsort((void*)hash->table, hash->currentsize, sizeof(word),(int (*)(const void *, const void *)) wordcmp);
if(top_words > total_unique_words)
top_words = total_unique_words;
printf("the top %d words (out of %d) are:\n", top_words, total_unique_words);
int iterations =0;
for(i =0; i <= hash->tablesize && iterations< top_words; i++)
{
present = hash->table[i];
if(present != NULL)
{
printf(" %4d %s\n", present->count, present->s);
present = present->next;
iterations++;
}
}
freetable(hash);
return 0;
}
int wordcmp (word *a, word *b)
{
if (a != NULL && b!= NULL) {
if (a->count < b->count)
{
return +1;
}
else if (a->count > b->count)
{
return -1;
}
else if (a->count == b->count)
{
/*return strcmp(b->s, a->s);*/
return 0;
}
}
return 0;
}
/* Create a new hashtable. */
struct hashtable *ht_create( int size )
{
int i;
if( size < 1 )
return NULL;
hashtable *table = (hashtable *) malloc(sizeof(hashtable));
table->table = (word **) malloc(sizeof(word *) * size);
if(table != NULL)
{
table->currentsize = 0;
table->tablesize = size;
}
for( i = 0; i < size; i++ )
{
table->table[i] = NULL;
}
return table;
}
/* Adds a new node to the hash table*/
word * add(hashtable *h, char *key, int freq)
{
int index = hashcode(key) % h->tablesize;
word *current = h->table[index];
/* Search for duplicate value */
while(current != NULL) {
if(contains(h, key) == 1){
current->count++;
return current;
}
current = current->next;
}
/* Create new node if no duplicate is found */
word *newnode = (struct word*)malloc(sizeof(struct word));
if(newnode!=NULL){
newnode->s =strdup(key);
newnode-> count = freq;
newnode-> next = NULL;
}
h->table[index] = newnode;
h->currentsize = h->currentsize + 1;
total_unique_words++;
return newnode;
}
【问题讨论】:
-
char* a= *(char * const *)((struct word *) obj2)->s;--> 为什么要将 obj2->s 转换为char * const *?它已经是char *,这是您要分配的类型。 -
get_all_entries的定义是什么? -
在
add()中,我怀疑newnode-> next = NULL;应该是newnode-> next =h->table[index];才不会失去LL。 -
通过使用带有链表链接的哈希表,而不是使用简单的
word **指针,从结构中删除next,并将其视为结构的动态数组。您不能qsort哈希表并期望得到任何有意义的排序顺序。这不是哈希表的工作方式。
标签: c struct hash hashtable qsort