程式設計師面試一百題-08-求1+2+...+n
阿新 • • 發佈:2018-12-16
1-題目
:
求1+2+…+n,要求不能使用乘除法、for、while、if、else、switch、case等關鍵字以及條件判斷語句(A?B:C)。
2-思路
:
這道題沒有多少實際意義
,因為在軟體開發過程中沒有這麼多限制,但是可以很好的發散思維
。通常除了用公式n(n+1)/2之外,無外乎迴圈和遞迴兩種思路。
由於已經明確限制for和while的使用,迴圈已經不能再用了。同樣,遞迴函式也需要用if語句或者條件判斷語句來判斷是繼續遞迴下去還是終止遞迴,但現在題目已經不允許使用這兩種語句了。
2.1-
仍然圍繞迴圈
做文章。迴圈只是讓相同的程式碼執行n遍而已,我們完全可以不用for和while達到這個效果。比如定義一個類,我們new一含有n個這種型別元素的陣列,那麼該類的建構函式
2.2-
同樣也可以圍繞遞迴
做文章。既然不能判斷是不是應該終止遞迴,我們不妨定義兩個函式。一個函式充當遞迴函式的角色,另一個函式處理終止遞迴的情況,我們需要做的就是在兩個函式裡二選一。從二選一我們很自然的想到布林變數,比如true時呼叫第一個函式,false時呼叫第二個函式
。那現在的問題是如和把數值變數n轉換成布林值,如果對n連續做兩次反運算,即!!n
,那麼非零的n轉換為true,0轉換為false。
3-程式碼
:
3.1-思路1程式碼
:
class C1 { private: static int n; static int sum; public: //建構函式 C1() { ++n; sum += n; } //重置函式 static void Reset() { n = 0; sum = 0; } //獲取和 static int GetSum() { return sum; } }; int C1::n = 0; int C1::sum = 0; int SolutionSum1(int n) { C1::Reset(); C1 *a = new C1[n]; delete[] a; a = 0; return C1::GetSum(); }
3.2-思路2程式碼
:
//A->Sum函式的作用:當n=0時,停止遞迴 class A { public: virtual int Sum(int n) { return 0; } }; //B->Sum函式的作用:當n!=0時,繼續遞迴 class B : public A { public: virtual int Sum(int n) { return Arr[!!n]->Sum(n - 1) + n; } }; //用虛擬函式來實現函式的選擇(虛擬函式可以實現多型性) //當n不為零時,執行函式B::Sum;當n為0時,執行A::Sum int SolutionSum2(int n) { A a; B b; //定義一個A類的陣列 A *Arr[2]; Arr[0] = &a; Arr[1] = &b; //假設n不為0 int res = Arr[1]->Sum(n); return res; }