首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C 語言初學者常見錯誤與重構實戰(九):統計字母出現次數

     編輯:關於C語言

題目需求

輸入 T 組測資(0),每組一個小寫字母字串(長度 <1010)。輸出每組出現次數最多的字母;若有多個同為最高,輸出字典序最小者。

原始代碼問題分析

  • 函數聲明位置混亂:maxchar 定義在 main 前,又在 main 前重複聲明。
  • 變數作用域過大:s[1010]、c[26] 定義在 main 頂端,實際只在迴圈內使用。
  • 輸入驗證缺失:未檢查 T 範圍,未限制 scanf("%s") 寬度(緩衝區溢位風險)。
  • 魔術數字:硬編碼 97、26、1010,可讀性差。
  • 效能隱憂:for(i=0;i 每次迴圈呼叫 strlen,應改為 x[i]!='\0'。
  • 演算法冗餘:找最大值時同時用 max 與 j,實際只需記錄索引 j。

重構版本(符合 C99,模組化、可讀、安全)

/* 字母統計 - 重構版
 * 作者:薛非  出處:https://www.cnblogs.com/pmer/
 */
#include <stdio.h>

#define S_LEN 1009
#define MAX_LEN (S_LEN + 1)
#define STR(x) #x
#define XSTR(x) STR(x)

char find_major(char *s);
void count_letters(int freq[], char *s);
unsigned index_of_max(int freq[], unsigned n);

int main(void) {
    int T;
    puts("行數?");
    if (scanf("%d", &T) != 1) return 1;
    if (!(0 < T && T < 25)) return 1;

    while (T-- > 0) {
        char str[MAX_LEN];
        scanf("%" XSTR(S_LEN) "s", str); // 防溢位
        printf("%c\n", find_major(str));
    }
    return 0;
}

char find_major(char *s) {
    int freq['z' - 'a' + 1] = {0};
    count_letters(freq, s);
    return 'a' + index_of_max(freq, sizeof freq / sizeof freq[0]);
}

void count_letters(int freq[], char *s) {
    while (*s != '\0') freq[*s++ - 'a']++;
}

unsigned index_of_max(int a[], unsigned n) {
    unsigned max_idx = 0;
    for (unsigned i = 1; i < n; ++i)
        if (a[max_idx] < a[i]) max_idx = i;
    return max_idx;
}

重構亮點

  1. 常數宏化:S_LEN、MAX_LEN、'z'-'a'+1 消除魔術數字。
  2. 單一職責:統計、找最大值、主流程分離,易測試、易維護。
  3. 安全輸入:scanf("%1009s") 防緩衝區溢位。
  4. 避免重複計算:while(*s) 取代 strlen。
  5. 字典序保證:index_of_max 遇相等不更新索引,自然保留最小字母。

常見錯誤清單(自查用)

錯誤類型原始寫法正確寫法
緩衝區溢位scanf("%s", s)scanf("%1009s", s)
魔術數字x[i]-97x[i]-'a'
strlen 誤用ix[i]!='\0'
變數過多max, j 並用僅用 max_idx
函數聲明重複定義前又聲明僅在定義前聲明或置於頭檔

延伸練習

  • 修改為支援大小寫不敏感統計。
  • 改用 fgets 讀取整行(含空白),並過濾非字母字元。
  • 將字母頻率統計封裝為通用函式庫(letter_freq.h/.c)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved