1. 程式人生 > >不使用迴圈遞迴的方式求1~n的和

不使用迴圈遞迴的方式求1~n的和

今天在牛客網上看到一道面試題,感覺很有意思自己也思考了很長時間,希望可以分享下來,題目是這樣描述的:

1+2+3+...+n,要求不能使用乘除法、forwhileifelseswitch、case等關鍵字及條件判斷語句(A?B:C)。

剛開始的時候我想1+2+3+…+n不正好是等差數列嗎?直接使用等差數列的求和公式不就可以嗎?n*(n+1)/2,但是公式中依然有乘法啊,所以這個想法被pass掉。
後來我就想到了邏輯運算中的邏輯與&&操作,這個操作有一個特性就是短路特性,如果當前面的條件成立的時候後面的條件就不再執行了,如果我用前面一個條件代表遞迴結束,後面一個條件代表遞迴執行,不正好可以實現這個目的嗎?於是我寫出了下面的程式碼:

size_t Sum_Solution(size_t n)
{
    //當n為0的時候只執行前面的條件,結果為false
    //當n大於0的時候可以執行到後面的條件,實現遞迴計算,
    int sum=n;
    bool ret=(n > 0) && ((sum += Sum_Solution(n-1)) > 0);
    return sum;
}

當然了,還有其他的解決方法了。。。

方法一.利用建構函式的方法實現迴圈

如果我們一次建立n個物件,每次建立物件都會呼叫一次建構函式,而每呼叫一次建構函式迴圈變數就增加1,而sum也隨之遞增,這不就利用建構函式達到迴圈的效果了嗎?

//利用建構函式模擬迴圈
class Sum_Solution
{
public:
    Sum_Solution()  //建構函式控制迴圈的次數
    {
        ++_i;
        _sum += _i;
    }
    static void InitData()
    {
        _i=0;
        _sum=0;
    }
    static size_t GetSum()  //返回最終結果
    {
        return _sum;
    }
private:
    static size_t _i;
    static size_t _sum;
};
//使用靜態的變數可保證累加的效果
size_t Sum_Solution::_i=0; size_t Sum_Solution::_sum=0; void testSum_Solution() { int n=100; Sum_Solution::InitData();//呼叫初始化函式給變數_i,和_sum賦初值 Sum_Solution *tmp=new Sum_Solution[n]; delete[]tmp; size_t ret=Sum_Solution::GetSum(); cout<<ret<<endl; }

方法二.利用虛擬函式的方法模擬遞迴

所謂的遞迴就是要有實現遞迴的函式以及遞迴結束的條件,如果可以使得實現遞迴的函式和判斷遞迴結束的條件用兩個類實現就可以解決這個問題了。

//使用虛擬函式模擬遞迴實現
class A
{
public:
    virtual size_t GetSum(size_t n)  //遞迴結束的條件
    {
        return 0;
    }
};
A *arr[2];
class B:public A
{
public:
    virtual size_t GetSum(size_t n)  //遞迴的實現
    {
        return arr[!!n]->GetSum(n-1)+n;
    }
};
void testSolution()
{
    //n==0,呼叫A::GetSum(),當n != 0的時候呼叫B::GetSum()
    int n=100;
    A a;
    B b;
    arr[0]=&a;
    arr[1]=&b;
    size_t sum=arr[1]->GetSum(n); 
    cout<<sum<<endl;
}

方法三.使用函式指標的方式來解決

如果面試官不讓你使用C++的方法該怎仫辦?函式指標可以很好的解決這個問題。

//利用函式指標來實現
typedef size_t (*GetSum)(size_t);
size_t Finish(size_t n)
{
    return 0;
}
size_t Sum_Solution(size_t n)
{
    static GetSum arr[2]={Finish,Sum_Solution};
    return n+arr[!!n](n-1);
}

在這裡就分享結束啦~~~