You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言统计文本文件高频词:无法按频率排序问题求助

Fixing qsort for Word Frequency Sorting in 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 takes const 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/realloc failures—ignoring these can lead to crashes.
  • Use strdup (or malloc + 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:17:10