C语言统计文本文件高频词:无法按频率排序问题求助
Hey there! Let's work through why your qsort setup isn't sorting your word frequencies correctly. This is a super common pitfall when working with hash tables and sorting in C, so let's break down the key issues and how to fix them.
Common Mistakes to Check
First, let's cover the most frequent reasons your sorting might fail:
Incorrect Comparison Function Signature/Logic
qsort expects a comparison function that takesconst void*parameters, and returns an integer based on the desired order. A lot of folks mess up the type casting or accidentally sort in ascending order (lowest frequency first) instead of descending.Trying to Sort the Hash Table Directly
Hash tables store data in non-contiguous buckets (usually linked lists), which qsort can't handle. You need to first copy your word-frequency pairs into a dynamic array before sorting.Ignoring Tiebreakers (Optional but Useful)
If two words have the same frequency, sorting them alphabetically keeps results consistent—your current function might not handle this case.
Step-by-Step Fix
1. Define a Struct for Word-Frequency Pairs
First, create a clear structure to hold each word and its count—this makes sorting much easier:
#include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct { char* word; int frequency; } WordCount;
2. Write the Correct Comparison Function
This function will sort by frequency descending (highest first), and alphabetically ascending for ties:
int wordcmp(const void* a, const void* b) { // Cast void pointers to our struct type const WordCount* wcA = (const WordCount*)a; const WordCount* wcB = (const WordCount*)b; // First sort by frequency (descending) if (wcA->frequency != wcB->frequency) { // Return negative if wcA should come before wcB (higher frequency) return wcB->frequency - wcA->frequency; } // If frequencies are equal, sort alphabetically (ascending) return strcmp(wcA->word, wcB->word); }
Note: If you return
wcA->frequency - wcB->frequency, you'll get ascending order (lowest frequency first)—this is probably why your current code is sorting backwards!
3. Convert Hash Table Entries to an Array
Since qsort can't sort hash table buckets directly, we need to collect all entries into a dynamic array:
// Assume you have a hash table defined with nodes like: // typedef struct HashNode { char* word; int frequency; struct HashNode* next; } HashNode; // HashNode* hashTable[HASH_TABLE_SIZE]; WordCount* wordArray = NULL; int arraySize = 0; int capacity = 10; // Start with a small initial capacity // Initialize the array wordArray = malloc(capacity * sizeof(WordCount)); if (wordArray == NULL) { perror("malloc failed"); exit(EXIT_FAILURE); } // Traverse the hash table to fill the array for (int i = 0; i < HASH_TABLE_SIZE; i++) { HashNode* current = hashTable[i]; while (current != NULL) { // Resize array if we've reached capacity if (arraySize >= capacity) { capacity *= 2; wordArray = realloc(wordArray, capacity * sizeof(WordCount)); if (wordArray == NULL) { perror("realloc failed"); exit(EXIT_FAILURE); } } // Copy the word (use strdup to avoid pointer invalidation later) wordArray[arraySize].word = strdup(current->word); wordArray[arraySize].frequency = current->frequency; arraySize++; current = current->next; } }
4. Sort the Array and Output Top 10
Now we can use qsort on our array, then print the top results:
// Sort the array qsort(wordArray, arraySize, sizeof(WordCount), wordcmp); // Print the top 10 words (or all if there are fewer than 10) printf("Top 10 Most Frequent Words:\n"); int topCount = (arraySize < 10) ? arraySize : 10; for (int i = 0; i < topCount; i++) { printf("%-15s %d\n", wordArray[i].word, wordArray[i].frequency); // Free the duplicated word to avoid memory leaks free(wordArray[i].word); } // Free the array itself free(wordArray);
Key Notes to Avoid Issues
- Always check for
malloc/reallocfailures—ignoring these can lead to crashes. - Use
strdup(ormalloc+strcpy) to copy words from the hash table into the array. If you just assign the pointer, freeing the hash table later will invalidate your array's data. - Make sure you've included all necessary headers:
<stdlib.h>for qsort/malloc,<string.h>for strcmp/strdup,<stdio.h>for printing.
Give this setup a shot—if you still run into problems, share your specific wordcmp function and how you're handling the hash table-to-array conversion, and I can help you pinpoint the exact issue!
内容的提问来源于stack exchange,提问作者Amy Wilson

