跳到內容

09|回文判斷

還沒完成C 或 C++ 皆可CPU 時間上限 1 秒

相關主題: C 基礎速查

C 或 C++ 皆可|CPU 時間上限 1 秒

「回文」是正著讀和倒著讀都一樣的字串,例如 level、noon、12321。

給你 T 個單字,判斷每一個是不是回文。比較時不分大小寫,所以 Level、NoOn 也算回文。

第一行是一個整數 T(1 ≤ T ≤ 100),代表有幾個單字。

接下來 T 行,每行一個單字:

  • 只包含英文字母(大寫或小寫)和數字 0 到 9,不含空白
  • 長度 1 到 100 個字元

輸出 T 行,依照輸入的順序,是回文就輸出 yes,不是就輸出 no。

輸入:

6
Level
abc
A
NoOn
12321
ab

輸出:

yes
no
yes
yes
yes
no

C:

  • C 的字串是 char 陣列,最後一個字元後面會放一個 '\0' 表示結束。所以長度 100 的單字需要 char s[101]
  • scanf("%100s", s):%s 讀一個單字(遇到空白或換行就停止),100 限制最多讀 100 個字元,避免寫出陣列範圍。陣列名稱本身就是位址,不用加 &
  • strlen(s)(<string.h>):字串長度,不包含 '\0'
  • tolower(c)(<ctype.h>):把大寫字母轉成小寫,其他字元不變。參數最好先轉成 unsigned char:tolower((unsigned char)s[i])

C++:

  • std::string(<string>)會自己管理長度和記憶體,不用擔心陣列太小
  • s.size() 取得長度,s[i] 取得第 i 個字元
  • std::tolower(<cctype>)
  • 可以用 std::string(s.rbegin(), s.rend()) 做出反轉後的字串
提示 1:怎麼判斷回文?

用兩個索引:i 從頭開始、j 從尾巴開始,兩邊往中間走。只要有一對字元(轉成小寫後)不一樣,就不是回文;兩個索引相遇時都還一樣,就是回文。

長度為 len 的字串,最後一個字元的索引是 len - 1。

提示 2:為什麼 char s[100] 會出事?

單字最長 100 個字元,scanf 存進去時,後面還要再放一個 '\0',總共需要 101 個 char。

用 char s[100] 遇到長度 100 的單字時,'\0' 會寫到陣列外面。這種錯誤平常可能看不出來,但檢查時第一階段的 Sanitizer 會報告 stack-buffer-overflow。

提示 3:不分大小寫怎麼比?

比較兩個字元之前,先把它們都轉成小寫:tolower(a) == tolower(b)。

tolower 對數字和小寫字母不會有任何改變,所以可以放心對每個字元都用。