首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C 語言統計英文文本字母出現頻率並查詢前三高頻字母

     編輯:程式設計綜合問答

需求分析

  • 讀取 story.txt 英文文本
  • 統計 26 個英文字母 (不分大小寫) 出現次數
  • 互動查詢:輸入字母顯示次數,輸入 # 結束
  • 輸出出現頻率最高的前三個字母及其次數

完整解決方案

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

#define ALPHABET_SIZE 26
#define FILENAME "story.txt"

int main() {
    // 1. 初始化計數陣列
    int alpha[ALPHABET_SIZE] = {0};
    FILE *fp;
    int ch;

    // 2. 開啟檔案並統計
    if ((fp = fopen(FILENAME, "r")) == NULL) {
        perror("無法開啟檔案");
        return EXIT_FAILURE;
    }

    while ((ch = fgetc(fp)) != EOF) {
        ch = tolower(ch);  // 統一轉小寫
        if (ch >= 'a' && ch <= 'z') {
            alpha[ch - 'a']++;
        }
    }
    fclose(fp);

    // 3. 找出前三高頻字母
    int selected[ALPHABET_SIZE] = {0};  // 標記已選
    int topIdx[3] = {-1, -1, -1};       // 儲存前三索引

    for (int rank = 0; rank < 3; rank++) {
        int maxCount = -1;
        for (int i = 0; i < ALPHABET_SIZE; i++) {
            if (!selected[i] && alpha[i] > maxCount) {
                maxCount = alpha[i];
                topIdx[rank] = i;
            }
        }
        if (topIdx[rank] != -1) selected[topIdx[rank]] = 1;
    }

    // 4. 輸出前三高頻
    printf("出現頻率最高的三個字母:\n");
    for (int i = 0; i < 3; i++) {
        if (topIdx[i] != -1) {
            printf("%d. '%c' : %d 次\n", i+1, 'a' + topIdx[i], alpha[topIdx[i]]);
        }
    }
    printf("\n");

    // 5. 互動查詢
    printf("請輸入要查詢的字母 (輸入 # 結束):\n");
    while ((ch = getchar()) != '#') {
        if (ch == '\n') continue;  // 跳過換行
        ch = tolower(ch);
        if (ch >= 'a' && ch <= 'z') {
            printf("'%c' 出現 %d 次\n", ch, alpha[ch - 'a']);
        } else {
            printf("請輸入英文字母!\n");
        }
        // 清除輸入緩衝區剩餘字元
        while ((ch = getchar()) != '\n' && ch != EOF);
    }

    return EXIT_SUCCESS;
}

關鍵技術點解析

1. 字母索引映射

// 'a' -> 0, 'b' -> 1, ..., 'z' -> 25
int index = ch - 'a';  // 利用 ASCII 碼連續特性

2. 大小寫統一處理

ch = tolower(ch);  //  提供,安全處理非字母字元

3. 前三高頻選取演算法

使用「選取標記法」避免排序整個陣列:

for (int rank = 0; rank < 3; rank++) {
    int maxCount = -1, maxIdx = -1;
    for (int i = 0; i < 26; i++) {
        if (!selected[i] && alpha[i] > maxCount) {
            maxCount = alpha[i];
            maxIdx = i;
        }
    }
    selected[maxIdx] = 1;  // 標記已選
    topIdx[rank] = maxIdx;
}

時間複雜度:O(3 * 26) = O(1),極高效。

4. 輸入緩衝區處理

while ((ch = getchar()) != '\n' && ch != EOF);  // 清除殘留換行符

避免 scanf 或 getchar 讀取到上一輪殘留的換行符。

測試範例

story.txt 內容:
"Hello World! This is a simple test story."

執行結果:
出現頻率最高的三個字母:
1. 's' : 5 次
2. 't' : 5 次
3. 'l' : 3 次

請輸入要查詢的字母 (輸入 # 結束):
s
's' 出現 5 次
z
'z' 出現 0 次
#

進階擴充建議

功能實現方式
支援 UTF-8 中文統計使用 wchar_t、setlocale、哈希表
忽略標點符號isalpha(ch) 判斷
單詞頻率統計strtok 分詞 + 哈希表
大檔案流式處理固定大小緩衝區 + 狀態機
圖形化輸出ASCII 條形圖或導出 CSV 給 Excel

常見錯誤避坑

  1. 忘記 tolower:導致大小寫分開統計
  2. 陣列大小錯誤:alpha[25] 只能存 25 個,需 [26]
  3. 檔案未關閉:資源洩漏,務必 fclose(fp)
  4. 輸入緩衝區殘留:導致查詢迴圈跳過或讀到換行符
  5. 同頻率處理:題目未指定,上述代碼取索引較小者優先

總結

本程式展示了 C 語言處理文本統計的經典模式:檔案 I/O → 字元分類 → 計數陣列 → 選取演算法 → 互動查詢。掌握此模式可輕鬆擴展至單詞統計、詞頻分析、文本挖掘等進階應用。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved