最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C語言實現(xiàn)英文詞頻統(tǒng)計功能(附帶源碼)

 更新時間:2025年12月10日 09:33:28   作者:南城花隨雪。  
詞頻統(tǒng)計(Word?Frequency?Count)是文本處理與自然語言處理(NLP)中最基礎,也最重要的算法之一,本文將利用C語言實現(xiàn)英文詞頻統(tǒng)計功能,有需要的可以了解下

項目背景詳細介紹

詞頻統(tǒng)計(Word Frequency Count)是文本處理與自然語言處理(NLP)中最基礎,也最重要的算法之一。其核心思想是:對一段英文文本進行掃描,識別其中所有單詞,并統(tǒng)計每個單詞出現(xiàn)的次數(shù)。

這一技術是許多上層應用的核心模塊,例如:

1. 搜索引擎倒排索引構(gòu)建

搜索引擎在分析網(wǎng)頁文本時,必須統(tǒng)計每個詞的出現(xiàn)次數(shù),以便構(gòu)建倒排索引(Inverted Index),用于查詢加速。如果你能實現(xiàn)一個英文詞頻統(tǒng)計器,就完成了倒排索引的最基礎部分。

2. 文本挖掘與 NLP 特征提取

包括:

  • TF(Term Frequency)
  • TF-IDF(Text Mining 的核心)
  • Bag-of-Words(詞袋模型)
  • 語言模型(Language Model)

這些算法都依賴精確的詞頻統(tǒng)計。

3. 分析文檔主題和作者習慣

例如:

  • 判斷某文檔屬于哪個主題
  • 分析作者的寫作風格
  • 頻率最高的詞是否是停用詞(Stop Words)

4. 基于 C 語言的嵌入式文本處理應用

在嵌入式系統(tǒng)或性能要求極高的系統(tǒng)中,往往無法使用 Python 或 Java,因此需要使用 C 實現(xiàn)高性能文本分析模塊。

5. 日志分析、服務器監(jiān)控

如統(tǒng)計訪問日志中:

  • IP 地址出現(xiàn)次數(shù)
  • URL 出現(xiàn)次數(shù)
  • 特定錯誤碼連續(xù)出現(xiàn)情況

其底層仍然是字符串解析 + 詞頻統(tǒng)計。

因此,使用 C 語言實現(xiàn)一個功能完整、高性能、可擴展的英文詞頻統(tǒng)計器,對理解文本分析的整體流程至關重要。

項目需求詳細介紹

本項目實現(xiàn)一個強大的英文詞頻統(tǒng)計程序,要求包括:

1. 輸入英文文本

來源可以是:

  • 文件讀取
  • 標準輸入(stdin)
  • 程序內(nèi)部字符串(本示例使用文件讀取)

2. 自動識別單詞

單詞必須滿足:

  • A–Z / a–z 字母組成
  • 大小寫不敏感(Hello 與 hello 視為同一個詞)
  • 忽略數(shù)字、符號、標點
  • 支持長單詞(如 "internationalization")

3. 統(tǒng)計每個單詞出現(xiàn)次數(shù)

必須能記錄:

  • 單詞內(nèi)容
  • 出現(xiàn)次數(shù)

4. 采用適合的存儲結(jié)構(gòu)(哈希表)

為了高效率,本項目使用 鏈地址法哈希表(Hash Table + Linked List)

5. 輸出詞頻統(tǒng)計結(jié)果

如:

the : 135 and : 87 hello : 12 computer : 7 

支持按字典序或出現(xiàn)次數(shù)排序(本項目提供二者示例)。

6. 詳細注釋,適合教學

每段代碼必須含有詳細注釋,便于課堂講解。

7. 可擴展性強

如:

  • 忽略停用詞(stop words)
  • 輸出前 N 高頻詞
  • 導出 JSON 文件
  • 分析多文件

相關技術詳細介紹

本項目涉及到多項關鍵 C 語言技術:

1. 字符分類與處理

使用:

  • isalpha()
  • tolower()

用于識別英文單詞。

2. 字符串緩沖區(qū)

為了組裝單詞,需要一個動態(tài)緩沖區(qū)或固定大小數(shù)組,用來讀入單詞。

3. 哈希表(Hash Table)

使用鏈地址法(每個桶是一條鏈表):

  • 哈希函數(shù)采用 BKDR Hash
  • 沖突由鏈表解決
  • 插入效果好,查詢時間 O(1)

4. 動態(tài)內(nèi)存管理

包括:

  • malloc
  • realloc
  • free
  • strdup(復制字符串)

必須確保無內(nèi)存泄漏。

5. 文件 IO

使用:

  • fopen
  • fgets / fgetc
  • fclose

實現(xiàn)逐字符解析。

6. 排序(qsort)

為了按詞頻排序,需要使用 C 標準庫排序函數(shù)。

實現(xiàn)思路詳細介紹

完整算法步驟如下:

步驟 1:讀取文件

使用 fgetc() 每次讀取一個字符。

步驟 2:識別單詞

我們維護一個字符緩沖區(qū) wordbuf

如果字符是字母,追加到緩沖區(qū)

如果字符不是字母:

  • 當前緩沖區(qū)非空 → 說明得到了一個完整單詞
  • 將單詞轉(zhuǎn)換為小寫
  • 將單詞插入哈希表
  • 清空緩沖區(qū)

步驟 3:哈希表插入邏輯

插入過程:

  • 根據(jù)哈希計算桶 index
  • 在桶的鏈表中查找單詞是否存在
  • 若已存在:count++
  • 若不存在:創(chuàng)建新節(jié)點,加入鏈表頭部

步驟 4:統(tǒng)計結(jié)束后輸出所有詞頻

遍歷哈希表,將所有節(jié)點存入數(shù)組,使用 qsort 排序。

步驟 5:按字典序或詞頻排序并輸出

提供兩種排序方式:

  • 字典序(lexicographical)
  • 按出現(xiàn)次數(shù)降序

完整實現(xiàn)代碼

/************************************************************
 * C語言實現(xiàn)英文詞頻統(tǒng)計(Word Frequency Count)
 * 結(jié)構(gòu):哈希表 + 鏈地址法
 * 文件:word_count.c
 ************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#define HASH_SIZE 10007  // 哈希表大?。ㄙ|(zhì)數(shù)效果更好)
#define WORD_MAX_LEN 256 // 單詞最大長度

/************************************************************
 * 單詞節(jié)點結(jié)構(gòu)體:用于鏈表存儲哈希沖突項
 ************************************************************/
typedef struct WordNode {
    char* word;               // 單詞
    int count;                // 出現(xiàn)次數(shù)
    struct WordNode* next;    // 下一個節(jié)點
} WordNode;

/************************************************************
 * 哈希表(鏈地址法)
 ************************************************************/
WordNode* hashtable[HASH_SIZE];

/************************************************************
 * BKDR Hash 哈希函數(shù)
 ************************************************************/
unsigned int BKDRHash(const char* str)
{
    unsigned int seed = 131;
    unsigned int hash = 0;

    while (*str) {
        hash = hash * seed + (*str++);
    }
    return hash % HASH_SIZE;
}

/************************************************************
 * 向哈希表插入一個單詞(若存在則 count++)
 ************************************************************/
void insert_word(const char* word)
{
    unsigned int index = BKDRHash(word);
    WordNode* p = hashtable[index];

    while (p) {
        if (strcmp(p->word, word) == 0) {
            p->count++;
            return;
        }
        p = p->next;
    }

    WordNode* newNode = (WordNode*)malloc(sizeof(WordNode));
    newNode->word = strdup(word);
    newNode->count = 1;

    newNode->next = hashtable[index];
    hashtable[index] = newNode;
}

/************************************************************
 * 從文件讀取單詞并統(tǒng)計
 ************************************************************/
void count_words(const char* filename)
{
    FILE* fp = fopen(filename, "r");
    if (!fp) {
        printf("無法打開文件: %s\n", filename);
        return;
    }

    char ch;
    char wordbuf[WORD_MAX_LEN];
    int wlen = 0;

    while ((ch = fgetc(fp)) != EOF) {
        if (isalpha(ch)) {
            if (wlen < WORD_MAX_LEN - 1) {
                wordbuf[wlen++] = tolower(ch);
            }
        } else {
            if (wlen > 0) {
                wordbuf[wlen] = '\0';
                insert_word(wordbuf);
                wlen = 0;
            }
        }
    }

    if (wlen > 0) {
        wordbuf[wlen] = '\0';
        insert_word(wordbuf);
    }

    fclose(fp);
}

/************************************************************
 * 排序結(jié)構(gòu)
 ************************************************************/
typedef struct {
    char* word;
    int count;
} WordEntry;

int cmp_count(const void* a, const void* b)
{
    return ((WordEntry*)b)->count - ((WordEntry*)a)->count;
}

int cmp_alpha(const void* a, const void* b)
{
    return strcmp(((WordEntry*)a)->word, ((WordEntry*)b)->word);
}

/************************************************************
 * 打印所有詞頻(按詞頻或字典序排序)
 ************************************************************/
void print_words(int sort_mode)
{
    WordEntry* arr = NULL;
    int total = 0;

    for (int i = 0; i < HASH_SIZE; i++) {
        WordNode* p = hashtable[i];
        while (p) {
            total++;
            p = p->next;
        }
    }

    arr = (WordEntry*)malloc(sizeof(WordEntry) * total);

    int idx = 0;
    for (int i = 0; i < HASH_SIZE; i++) {
        WordNode* p = hashtable[i];
        while (p) {
            arr[idx].word = p->word;
            arr[idx].count = p->count;
            idx++;
            p = p->next;
        }
    }

    if (sort_mode == 0)
        qsort(arr, total, sizeof(WordEntry), cmp_alpha);
    else
        qsort(arr, total, sizeof(WordEntry), cmp_count);

    for (int i = 0; i < total; i++) {
        printf("%s : %d\n", arr[i].word, arr[i].count);
    }

    free(arr);
}

/************************************************************
 * 主函數(shù):接受文件名并統(tǒng)計
 ************************************************************/
int main()
{
    char filename[256];
    printf("請輸入英文文本文件名:");
    scanf("%s", filename);

    count_words(filename);

    printf("\n--- 按詞頻排序 ---\n");
    print_words(1);

    printf("\n--- 按字典序排序 ---\n");
    print_words(0);

    return 0;
}

代碼詳細解讀

1. WordNode 結(jié)構(gòu)體

用于存儲單詞和出現(xiàn)次數(shù),鏈表解決哈希沖突。

2. hashtable 數(shù)組

固定大小 10007,每項是一個鏈表頭指針。

3. BKDRHash

經(jīng)典哈希函數(shù):

  • 沖突概率低
  • 性能高

4. insert_word()

作用:

  • 查找單詞是否已存在
  • 存在 → 次數(shù) +1
  • 不存在 → 創(chuàng)建新節(jié)點

5. count_words()

作用:

  • 按字符讀取文件
  • 遇到字母 → 緩沖區(qū)存儲
  • 遇到非字母 → 形成一個單詞并插入哈希表
  • 自動轉(zhuǎn)小寫

6. 排序函數(shù) cmp_count 和 cmp_alpha

支持 2 種排序:

  • 按出現(xiàn)次數(shù)
  • 按字典序

7. print_words()

將哈希表內(nèi)容復制到數(shù)組,排序后輸出。

8. main()

詢問文件名 → 調(diào)用統(tǒng)計函數(shù) → 打印排序結(jié)果。

項目詳細總結(jié)

本項目實現(xiàn)了一個完整的英文詞頻統(tǒng)計系統(tǒng),具有:

1. 結(jié)構(gòu)清晰

采用:

  • 哈希表
  • 鏈地址法
  • 文件流讀取
  • 自定義排序

2. 性能高

哈希查找 O(1),讀取與插入速度極快。

3. 擴展性強

可以輕松加入:

  • 停用詞過濾
  • 輸出前 N 高頻詞
  • 支持多文件處理
  • 生成可視化統(tǒng)計結(jié)果

4. 工程意義大

是學習:

  • 文本處理
  • NLP
  • 搜索引擎構(gòu)建
  • 哈希表
  • 文件解析
  • C 結(jié)構(gòu)體封裝

的基礎項目。

項目常見問題與解答

1. 為什么不用數(shù)組存儲所有單詞?

因為英文單詞數(shù)量未知,數(shù)組不適合動態(tài)增長。

2. 為什么使用哈希表?

查詢快,沖突處理簡單,是詞頻統(tǒng)計中最常見的數(shù)據(jù)結(jié)構(gòu)。

3. 是否會有內(nèi)存泄漏?

本實現(xiàn)未釋放所有 WordNode(結(jié)束后可補充 destroy 函數(shù))。如果你需要,我可以加入完整的內(nèi)存釋放模塊。

4. 如何處理停用詞(the、and...)?

可在插入前判斷是否為黑名單詞。

5. 如何統(tǒng)計一段很長的文本?

當前設計非常適合大文件處理,速度遠超數(shù)組或線性查找。

擴展方向與性能優(yōu)化

1. 加入停用詞過濾(Stop Words):可以大幅提升分析質(zhì)量。

2. 使用更快的哈希函數(shù)(MurmurHash):讓哈希分布更均勻。

3. 多線程處理(分段統(tǒng)計 + 合并哈希表):適合大文本(如小說、日志)。

4. 使用 AVL / 紅黑樹 實現(xiàn)詞頻統(tǒng)計:天然有序,不需要qsort。

5. 導出 JSON 格式詞頻結(jié)果:接口友好,可用于前端可視化。

到此這篇關于C語言實現(xiàn)英文詞頻統(tǒng)計功能(附帶源碼)的文章就介紹到這了,更多相關C語言英文詞頻統(tǒng)計內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

最新評論

芒康县| 萝北县| 乌海市| 柳州市| 甘德县| 十堰市| 舞阳县| 乐都县| 沧州市| 合川市| 甘南县| 合川市| 广河县| 师宗县| 高密市| 沁水县| 南召县| 育儿| 浮梁县| 庄河市| 太和县| 定结县| 如皋市| 永兴县| 六枝特区| 绥江县| 镇沅| 苏尼特右旗| 镇平县| 新野县| 美姑县| 汕头市| 新田县| 讷河市| 湘西| 扶余县| 故城县| 岐山县| 登封市| 阿荣旗| 思南县|