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

C語言逆序數函數實作:整數反轉的多種演算法與邊界處理

     編輯:C 語言問答

題目需求

定義函數 reverse(number),輸入整數,返回其數字逆序後的整數。例:reverse(12345) → 54321。

演算法比較

方法核心邏輯優點缺點適用場景
數學累積法反覆取尾數 n%10,結果 rev = rev*10 + n%10無額外空間、效能最佳、原生整數運算需處理溢位、負數、尾端零通用、嵌入式、高效能要求
字串轉換法sprintf → 反轉字串 → strtol/atoi直觀、易處理負號、前導零自然去除需緩衝區、函數呼叫開銷、非標準 C 風格快速原型、教學演示
遞迴法reverse(n) = n%10 * 10^digits + reverse(n/10)程式碼簡潔、展示遞迴思維堆疊深度受限、效能差、尾端零處理繁瑣教學、面試展示

推薦實作:數學累積法(標準、高效、健壯)

#include <stdio.h>
#include <limits.h>  // INT_MAX, INT_MIN

// 逆序整數,處理溢位返回 0(LeetCode 7 風格)
int reverse(int n) {
    int rev = 0;
    while (n != 0) {
        int digit = n % 10;
        n /= 10;
        
        // 溢位檢查:rev * 10 + digit 是否超出 int 範圍
        if (rev > INT_MAX / 10 || (rev == INT_MAX / 10 && digit > 7)) return 0;
        if (rev < INT_MIN / 10 || (rev == INT_MIN / 10 && digit < -8)) return 0;
        
        rev = rev * 10 + digit;
    }
    return rev;
}

// 簡化版:假設輸入不會導致溢位(教學常用)
int reverse_simple(int n) {
    int rev = 0;
    while (n != 0) {
        rev = rev * 10 + n % 10;
        n /= 10;
    }
    return rev;
}

int main() {
    int test_cases[] = {12345, -123, 120, 0, 1534236469};  // 最後一個會溢位
    int n = sizeof(test_cases) / sizeof(test_cases[0]);
    
    for (int i = 0; i < n; ++i) {
        int input = test_cases[i];
        int result = reverse(input);
        printf("reverse(%d) = %d\n", input, result);
    }
    return 0;
}

執行結果

reverse(12345) = 54321
reverse(-123) = -321
reverse(120) = 21
reverse(0) = 0
reverse(1534236469) = 0   // 溢位保護觸發

關鍵細節解析

1. 負數處理

C 語言 % 運算結果符號與被除數相同:-123 % 10 = -3,-123 / 10 = -12(向零截斷)。上述迴圈自然支援負數,無需額外判斷。

2. 尾端零自動去除

120 → 0*10+0=0 → 0*10+2=2 → 2*10+1=21,前導零不會出現在整數表示中。

3. 溢位檢查邏輯

// 下一步 rev = rev * 10 + digit
// 若 rev > INT_MAX/10,乘 10 必溢位
// 若 rev == INT_MAX/10 且 digit > 7(INT_MAX 末位為 7),加 digit 溢位
// INT_MIN 同理,末位為 -8

這是 LeetCode 7「整數反轉」標準解法核心。

4. 字串法實作(參考)


#include <string.h>
#include <stdlib.h>

int reverse_string_method(int n) {
    char buf[20];  // 足夠容納 32 位整數含負號
    sprintf(buf, "%d", n);
    
    // 反轉字串(保留負號在最前)
    int len = strlen(buf);
    int start = (buf[0] == '-') ? 1 : 0;
    for (int i = start, j = len - 1; i < j; ++i, --j) {
        char tmp = buf[i];
        buf[i] = buf[j];
        buf[j] = tmp;
    }
    
    return atoi(buf);  // 自動處理前導零、溢位行為未定義
}

測試驗證表

輸入輸出說明
1234554321正常正數
-12345-54321負數,負號保持
120021尾端零去除
00邊界值
2147483647 (INT_MAX)0溢位保護
-2147483648 (INT_MIN)0溢位保護
10000000033000000001含零中間位

面試/考試常見追問

  1. 不使用乘除怎麼反轉? 位元操作無法直接處理十進位數字,除非用 BCD 編碼或查表,不實用。
  2. 如何反轉長整數 long long? 同邏輯,換 long long、LLONG_MAX/MIN。
  3. 若輸入為字串「00123」要求輸出「32100」? 需字串處理保留前導零,整數型別無法表示前導零。
  4. 遞迴版本怎麼寫? 需輔助函數傳遞位數或累積結果,注意堆疊深度(最多 10-19 層,安全)。

總結

整數逆序是 模 10 取餘 + 累積乘 10 的經典模式。掌握 負數語意、尾端零、溢位檢查 三大細節,即能寫出生產級、面試級的 reverse 函數。

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