求1 2 n,要求不能使用乘除法

2021-06-22 15:17:04 字數 3354 閱讀 1156

題目:求1+2+…+n,要求不能使用乘除法、for、while、if、else、switch、case等關鍵字以及條件判斷語句(a?b:c)。

分析:這道題沒有多少實際意義,因為在軟體開發中不會有這麼**的限制。但這道題卻能有效地考查發散思維能力,而發散思維能力能反映出對程式設計相關技術理解的深刻程度。

通常求1+2+…+n除了用公式n(n+1)/2之外,無外乎迴圈和遞迴兩種思路。由於已經明確限制for和while的使用,迴圈已經不能再用了。同樣,遞迴函式也需要用if語句或者條件判斷語句來判斷是繼續遞迴下去還是終止遞迴,但現在題目已經不允許使用這兩種語句了。

我們仍然圍繞迴圈做文章。迴圈只是讓相同的**執行n遍而已,我們完全可以不用for和while達到這個效果。比如定義乙個類,我們new一含有n個這種型別元素的陣列,那麼該類的建構函式將確定會被呼叫n次。我們可以將需要執行的**放到建構函式裡。如下**正是基於這個思路:

class

temp

static

void reset()

static

int getsum()

private

:static

int n;

static

int sum;

};int

temp::n = 0;

inttemp::sum = 0;

intsolution1_sum(int n)

我們同樣也可以圍繞遞迴做文章。既然不能判斷是不是應該終止遞迴,我們不妨定義兩個函式。乙個函式充當遞迴函式的角色,另乙個函式處理終止遞迴的情況,我們需要做的就是在兩個函式裡二選一。從二選一我們很自然的想到布林變數,比如ture(1)的時候呼叫第乙個函式,false(0)的時候呼叫第二個函式。那現在的問題是如和把數值變數n轉換成布林值。如果對n連續做兩次反運算,即!!n,那麼非零的n轉換為true,0轉換為false。有了上述分析,我們再來看下面的**:

class

a;a* array[2];

classa};

class

b: public a

};int

solution2_sum(int n)

這種方法是用虛函式來實現函式的選擇。當n不為零時,執行函式

b::sum

;當n為0時,執行

a::sum

。我們也可以直接用函式指標陣列,這樣可能還更直接一些:

typedef

int (*fun)(int);

intsolution3_f1(int i) 

intsolution3_f2(int i)

; return i+f[!!i](i-1);}

另外我們還可以讓編譯器幫我們來完成類似於遞迴的運算,比如如下**:

template

struct solution4_sum;};

template

<> struct solution4_sum<1>;};

solution4_sum<100>::n

就是1+2+...+100的結果。當編譯器看到

solution4_sum<100>

時,就是為模板類

solution4_sum

以引數100生成該型別的**。但以100為引數的型別需要得到以99為引數的型別,因為

solution4_sum<100>::n=solution4_sum<99>::n+100

。這個過程會遞迴一直到引數為1的型別,由於該型別已經顯式定義,編譯器無需生成,遞迴編譯到此結束。由於這個過程是在編譯過程中完成的,因此要求輸入n必須是在編譯期間就能確定,不能動態輸入。這是該方法最大的缺點。而且編譯器對遞迴編譯**的遞迴深度是有限制的,也就是要求n不能太大。

網上幾種方法彙總

#include 

using

namespace

std;  

//要求不能使用 乘 除 法、for、while、if、else、switch、case等關鍵字以及條件判斷語句(a?b:c)

//題目:求1+2+…+n,

//****************方法1**********************//

//用構類的造函式來實現

/*class sum

};int sum::m = 1;

int sum::m_sum = 0;

int main()

*///******************方法2**************//

//巧用遞迴和邏輯運算子  && 操作

/*int sum(int n,int &m)

int main()

*///*****************方法3*************//

//利用模板元程式設計實現

//這種方法沒有聽說過 先mark一下

/*template 

class c_num;};

template< >

class c_num<1>;};

int main()

*///******************方法4**************

////通過兩個函式模擬遞迴呼叫的過程

/*--------------------------------  

---------------------------------*/  

//typedef int (*pf_fun) (int nvalue);

//pf_fun pafun[2];//函式指標

/*int (*pafun[2])(int nvalue) ;//把上面的兩行 改為下面的一行 其實就是定義了乙個函式指標 用上面的自定義型別更直觀

//  typedef函式指標用法

int getsum1(int nvalue)

int getsum2(int nvalue)

int getvalue2(int nvalue)

int main()

*///************方法5************//

//虛函式的特性來處理這樣的問題

//makr

/*---------------------------

modified by yuucyf.2011.05.06

----------------------------*/

class

c_num;  

c_num* panum[2];  

class

c_num  

};  

class

c_numex: 

public

c_num  

};  

intgetvalue2(

intnval)  

intmain()  

求1 2 n 很多限制條件

題目 求1 2 n,要求不能使用乘除法 for while if else switch case等關鍵字以及條件判斷語句 a?b c 分析 這道題沒有多少實際意義,因為在軟體開發中不會有這麼 的限制。但這道題卻能有效地考查發散思維能力,而發散思維能力能反映出對程式設計相關技術理解的深刻程度。通常求...

微軟100題 求1 2 n

題目 求1 2 n,要求不能使用乘除法 for while if else switch case等關鍵字以及條件判斷語句 a?b c package test 題目 求1 2 n,要求不能使用乘除法,for,while,if,else,switch,case,條件判斷語句 a?b c author...

第12 題(特殊方法求1 2 n)

第12 題 題目 求1 2 n,要求不能使用乘除法 for while if else switch case 等關鍵字以及條件判斷語句 a?b c 幾種思路 namespace ms100p 12 void display int add increasebyone 0 int add count...