【劍指offer】實現1+2+3+..+n,要求不使用乘除法、迴圈、判斷條件
這道題目的實質是考察程式設計師的發散思維能力,發散思維能夠反映出應聘者知識面的寬度,以及對程式設計相關技術理解的深度。
拿到這道題時,首先考慮最簡便的方法當然是利用等差數列求和公式(n+1)n/2,想要得出結果,無外乎迴圈和遞迴兩種,但是題目限制了迴圈,判斷條件都不能使用,使用迴圈時就必須使用迴圈判斷條件,,與條件不符;使用遞迴時,少不了if條件,這就需要考慮其他的一些路徑。
針對這道題目,這裡介紹·四種解法,接下來進行逐一介紹:
第一種:利用建構函式求解
實現的方法是將累加相關程式碼放進建構函式裡,通過構造n個物件實現累加的過程
程式碼如下:
#include<iostream> #include<stack> using namespace std; class Temp { public: Temp(){ ++N; sum += N; } static void reset() { N = 0; sum = 0; } static int get_sum(){ return sum; } private: static int N; static int sum; }; int Temp::N = 0; int Temp::sum = 0; int AddOne2N(int n) { Temp::reset(); Temp *a = new Temp[n]; delete[] a; a = NULL; return Temp::get_sum(); }
方法二、利用虛擬函式求解
主要思想是:利用遞迴,但是不能使用if判斷,這裡就必須用一個東西來替代這個if判斷,這裡我們定義兩個函式,一個函式充當遞迴函式的角色,另一個函式處理終止遞迴的情況,我們需要做的就是在這兩個函式中二選一,利用bool變數是我們能想到的第一個辦法,非零的轉換成true,零轉換成false,這裡對零使用兩次非運算就可實現。
程式碼如下:
class A; A* array[2]; class A { public: virtual int sum(int n) { return 0; } }; class B :public A { public: virtual int sum(int n) { return array[!!n]->sum(n - 1) + n; } }; int AddOne2N2(int n) { A a; B b; array[0] = &a; array[1] = &b; int value = array[1]->sum(n); return value; }
方法三、利用函式指標進行計算
在c語言中,沒有虛擬函式機制,此時可以使用函式指標來模擬實現,其中的主要思想和虛擬函式類似,而且使用函式更加直觀一點,程式碼如下:
typedef int (*fun)(int);
int solotion3_tmp(int n)
{
return 0;
}
int AddOne2N3(int n)
{
static fun f[2] = { solotion3_tmp, AddOne2N3 };
return f[!!n](n-1) + n;
}
方法四、使用模板型別求解
程式碼如下:
template<int n> struct Sum_Solotion { enum Value{N = Sum_Solotion<n-1>::N+n}; }; template<> struct Sum_Solotion<1> { enum Value{N = 1}; };
Sum_Solotion<100>::N就是1+2+3+...+n的結果,利用編譯器直接生成以100為引數的程式碼,要想生成以100為引數的程式碼,就需要以99為引數的型別,這樣一直遞迴下去,一直遞迴到以1為引數的型別,這時以1為引數的型別不用編譯器生成,已經顯式給出可以直接使用,遞迴編譯到此結束,這裡的缺點就是模板引數n是靜態的一個數,不能動態給出,只能是一個確定的數值。這就是這種方法的一個缺陷。
到此為止,四種方法均已介紹完畢。
完整程式碼如下:
#include<iostream>
#include<stack>
using namespace std;
class Temp
{
public:
Temp(){ ++N; sum += N; }
static void reset()
{
N = 0;
sum = 0;
}
static int get_sum(){ return sum; }
private:
static int N;
static int sum;
};
int Temp::N = 0;
int Temp::sum = 0;
int AddOne2N(int n)
{
Temp::reset();
Temp *a = new Temp[n];
delete[] a;
a = NULL;
return Temp::get_sum();
}
class A;
A* array[2];
class A
{
public:
virtual int sum(int n)
{
return 0;
}
};
class B :public A
{
public:
virtual int sum(int n)
{
return array[!!n]->sum(n - 1) + n;
}
};
int AddOne2N2(int n)
{
A a;
B b;
array[0] = &a;
array[1] = &b;
int value = array[1]->sum(n);
return value;
}
typedef int (*fun)(int);
int solotion3_tmp(int n)
{
return 0;
}
int AddOne2N3(int n)
{
static fun f[2] = { solotion3_tmp, AddOne2N3 };
return f[!!n](n-1) + n;
}
template<int n>
struct Sum_Solotion
{
enum Value{N = Sum_Solotion<n-1>::N+n};
};
template<>
struct Sum_Solotion<1>
{
enum Value{N = 1};
};
int main()
{
int n = 0;
//cout << "please input the number you want" << endl;
//cin >> n;
cout << "the final number is:>>";
//cout << AddOne2N(n) << endl;
//cout << AddOne2N2(n) << endl;
//cout << AddOne2N3(n) << endl;
cout << Sum_Solotion<1>::N << endl;
system("pause");
return 0;
}