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

C語言統計輸入行單詞數:狀態機法與數組指針法兩種實現完解

     編輯:關於C語言

單詞計數:從鍵盤輸入到字符串處理的兩種經典范式

統計一行文本中單詞個數(單詞定義為由空格分隔的字符序列)是 C 語言處理字符流、狀態機思想的入門經典。本文提供流式字符處理法與緩存數組處理法兩種完整實現,並分析邊界條件、擴展性與工程應用場景。

一、 核心邏輯:有限狀態機(FSM)

掃描字符流,維護一個狀態變量 in_word(0=在空格/分隔符,1=在單詞內):

  • 讀到非空格且 in_word==0 → 進入單詞,count++,in_word=1。
  • 讀到空格 → in_word=0。
  • 其他情況(單詞內非空格)→ 狀態不變,繼續掃描。

二、 方法一:流式處理(無需存儲全行)

#include 

int main() {
    int ch;             // 必須用 int 接收 getchar(),以容納 EOF
    int count = 0;
    int in_word = 0;    // 0: 當前在分隔符區,1: 當前在單詞內
    
    while ((ch = getchar()) != '\n' && ch != EOF) { // 讀到換行或文件結束停止
        if (ch == ' ') {
            in_word = 0;          // 遇到空格,標記為分隔符狀態
        } else if (!in_word) {    // 非空格且之前不在單詞中
            in_word = 1;          // 進入單詞狀態
            count++;              // 單詞計數 +1
        }
        // else: 非空格且 in_word==1,單詞內部,不計數
    }
    
    printf("單詞數: %d\n", count);
    return 0;
}

優點:O(1) 空間,可處理任意長輸入行(受限於輸入緩衝區),適合管道/重定向輸入。
適用場景:流式日誌分析、嵌入式系統內存受限環境。

三、 方法二:緩存數組法(先讀整行再處理)

#include 
#include 

int count_words(const char *text, int len) {
    int count = 0;
    int in_word = 0;
    for (int i = 0; i < len; i++) {
        if (text[i] == ' ') {
            in_word = 0;
        } else if (!in_word) {
            in_word = 1;
            count++;
        }
    }
    return count;
}

int main() {
    char line[1024]; // 固定緩衝區,足夠大多數場景
    int idx = 0;
    int ch;
    
    // 讀取一行(含空格),排除換行符
    while ((ch = getchar()) != '\n' && ch != EOF && idx < 1023) {
        line[idx++] = ch;
    }
    line[idx] = '\0'; // 手動添加結束符
    
    printf("單詞數: %d\n", count_words(line, strlen(line)));
    return 0;
}

優點:代碼結構清晰,分離「輸入」與「處理」,便於單元測試 count_words 函數,支持對同一行多次分析。
缺點:固定緩衝區可能截斷超長行(可用動態擴展 realloc 解決)。

四、 邊界條件與測試用例

輸入預期輸出說明
"" (空行)0無字符
" " (多空格)0全分隔符
"hello"1單詞無尾隨空格
"hello world"2單空格分隔
" hello world "2首尾及多重空格
"a b c"3單字符單詞
"it's a test"3撇號屬於單詞內部(非空格)

五、 進階擴展:通用分隔符集

若單詞分隔符不僅是空格,還包括 \t, \n, ,, ., ; 等:

int is_delim(char c) {
    return c == ' ' || c == '\t' || c == '\n' || c == ',' || c == '.';
}

// 在 FSM 中替換判斷條件
if (is_delim(ch)) in_word = 0;
else if (!in_word) { in_word = 1; count++; }

六、 總結對比

維度流式字符法緩存數組法
空間複雜度O(1)O(N) (行長度)
最大行長限制無(受限於系統輸入緩衝)有(緩衝區大小)
代碼模塊化較低(IO與邏輯耦合)高(可提取純函數)
適用場景流處理、內存受限、管道輸入交互式程序、需多次掃描、教學演示
擴展性需修改主循環只需修改 count_words

核心收穫:單詞計數本質是字符流上的二狀態自動機。掌握狀態變量設計、邊界觸發計數(進入單詞瞬間而非離開)、輸入讀取邊界(EOF/\n/緩衝區滿),即可舉一反三解決「統計行數」「提取第 k 個單詞」「分割字符串」等同類問題。工程中推薦緩存數組法 + 純函數,利於測試與維護;系統級/流式場景用流式字符法。

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