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

C語言遞迴實作字串反轉:reverse_string 完整解析

     編輯:關於C

題目需求

撰寫函式 `void reverse_string(char *string)`,使用遞迴將字串原地反轉,不得使用 C 標準庫字串函式(如 `strlen`, `strrev`)。

演算法思路

  1. 先自寫 `my_strlen` 計算字串長度。
  2. 遞迴函式處理「首尾交換 + 縮小問題規模」:
    • 基底案例:長度 ≤ 1 直接返回。
    • 遞迴步驟:交換第一個與最後一個字元,將最後一字元暫存為 `\0`,遞迴處理 `str+1` 子字串,返回後恢復最後一字元。

完整程式碼

#include 
#include 

// 自訂字串長度
int my_strlen(const char *str) {
    assert(str);
    int count = 0;
    while (*str++) count++;
    return count;
}

// 遞迴反轉
void reverse_string(char *str) {
    assert(str);
    int len = my_strlen(str);
    if (len <= 1) return; // 基底案例

    char temp = str[0];
    str[0] = str[len - 1];
    str[len - 1] = '\0';          // 暫時截斷,縮小問題
    reverse_string(str + 1);      // 遞迴處理中間子字串
    str[len - 1] = temp;          // 還原尾部字元
}

int main() {
    char arr[] = "abcdef";
    printf("原字串: %s\n", arr);
    reverse_string(arr);
    printf("反轉後: %s\n", arr); // 輸出: fedcba
    return 0;
}

遞迴執行流程追蹤(以 "abc" 為例)

reverse("abc")
  len=3, temp='a', str="\0bc" -> reverse("bc")
    len=2, temp='b', str="\0c" -> reverse("c")
      len=1 -> return
    str[1]='b' -> "cb"
  str[2]='a' -> "cba"

關鍵細節解析

  1. 暫時截斷字串:`str[len-1] = '\0'` 使遞迴呼叫 `str+1` 看到的有效長度減 2,模擬「去頭去尾」。
  2. 恢復尾部字元:遞迴返回後 `str[len-1] = temp` 將原本的首字元放到尾部,完成交換。
  3. 基底條件:`len <= 1` 涵蓋空字串與單字元,避免無限遞迴。
  4. assert 防禦:檢查指標非 NULL,符合防禦性程式設計。

迭代版本對比(更高效)

void reverse_iterative(char *str) {
    assert(str);
    char *left = str;
    char *right = str + my_strlen(str) - 1;
    while (left < right) {
        char tmp = *left;
        *left++ = *right;
        *right-- = tmp;
    }
}

迭代版 O(n) 時間、O(1) 空間,無函式呼叫開銷,實務上推薦使用。

常見錯誤與除錯

  • 忘記恢復 `\0` 導致字串截斷。
  • 索引計算錯誤(`len-1` vs `len`)。
  • 未處理空字串或 `NULL` 指標。
  • 使用 `strlen` 違反題目限制。

總結

遞迴反轉字串是經典教學範例,展示「分治」思想:將大問題分解為「交換首尾 + 解決中間子問題」。雖然實務上迭代更佳,但理解遞迴版本有助於建立遞迴思維,並掌握字串指標操作的精髓。

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