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

巧思:不用迴圈與遞迴實現任意區間求和

     編輯:關於C語言

背景與挑戰

經典面試題:「不使用 for/while 迴圈,不使用遞迴,如何計算 1 到 100 的和?」甚至延伸為任意區間 [min, max] 求和。常規解法(高斯公式 n*(n+1)/2)雖然 O(1) 但屬於數學技巧,而非程式設計技巧。本文介紹一種利用 C++ 物件建構/解構機制 + 靜態成員 的「側寫」解法,展現語言特性的創造性運用。

核心原理

  1. 靜態資料成員 N、SUM 隸屬於類別而非物件,全域唯一,生命週期贯穿整個程式。
  2. 建構函數 在物件建立時自動執行:N++、SUM += N。
  3. 動態陣列 new ClassName[size] 會連續呼叫 size 次建構函數,再呼叫 size 次解構函數。
  4. 利用陣列大小 max - min + 1 控制建構次數,並先將靜態計數器 N 重置為 min - 1,即可累加 min ~ max。

完整程式碼 (C++ / 標準寫法修正)

#include <iostream>
using namespace std;

class Accumulator {
public:
    Accumulator();          // 建構函數
    static int getSum();    // 取得累加結果
private:
    static int N;           // 當前計數
    static int SUM;         // 累加和
};

// 靜態成員定義與初始化(必須在類別外部)
int Accumulator::N = 0;
int Accumulator::SUM = 0;

Accumulator::Accumulator() {
    N++;
    SUM += N;
}

int Accumulator::getSum() {
    return SUM;
}

int main() {
    int min, max;
    cout << "請輸入求和區間 [min, max] (min > 0, max >= min):\n";
    cout << "min: "; cin >> min;
    while (min <= 0) { cout << "min 必須 > 0,重新輸入: "; cin >> min; }
    cout << "max: "; cin >> max;
    while (max < min) { cout << "max 必須 >= min,重新輸入: "; cin >> max; }

    Accumulator::N = min - 1;                 // 關鍵:重置計數起點
    Accumulator *arr = new Accumulator[max - min + 1]; // 觸發 N 次建構
    cout << min << " ~ " << max << " 的和 = " << arr->getSum() << endl;
    delete[] arr;                             // 釋放記憶體(觸發解構,但不影響 SUM)
    return 0;
}

深度解析與延伸

為什麼可行?

  • new Accumulator[k] 在堆疊上分配 k 個物件,編譯器生成程式碼迴圈呼叫 k 次建構函數——這把「迴圈」隱藏在編譯器生成的程式碼中,符合「原始碼中無迴圈/遞迴」的限制。
  • 靜態成員 SUM 累加過程不依賴物件實例,故 delete[] 後數值保留。

替代方案:使用 STL 容器

同樣原理,vector v(max-min+1); 也會觸發建構函數,語法更現代、記憶體管理更安全。

其他「無迴圈無遞迴」思路

  • 模板遞迴 (Template Metaprogramming):編譯期計算,但需常數區間。
  • 標準算法:accumulate、iota + reduce (C++17) 內部含迴圈,但原始碼單行。
  • 訊號/槽、事件迴圈:過度設計,不實用。

總結與反思

此技巧屬於「語言律師」層面的展示,不建議用於生產環境(可讀性差、效能不可預期、濫用建構/解構副作用)。但它極佳地展示了:

  1. C++ 物件生命週期機制
  2. 靜態成員跨實例共享特性
  3. 動態陣列建構語意
  4. 跳出常規思維的側向思考能力

面試中若遇到此類題目,先給出高斯公式 O(1) 正解,再補充此技巧作為「額外展示語言深度」,效果最佳。

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