1. 程式人生 > >64求1+2+3+...+n(發散思維能力 )

64求1+2+3+...+n(發散思維能力 )

題目描述:

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

 

解題思路:

1)利用&&的短路特性

2)  利用sizeof特性,使用公式n(n+1)/2

3)利用建構函式求解:

         先定義一個型別,然後建立n個該型別的例項,那麼這個型別的建構函式將被呼叫n次。將累加的程式碼放到建構函式中。

4)利用虛擬函式求解: 

 

測試用例:

1) 邊界值:(輸入0和1)

2) 功能測試(n=5,n=10)

 

程式碼:

1)&&的短路特性 複雜度:O(n)

1 1 class Solution {
2 2 public:
3 3     int Sum_Solution(int n) {
4 4         int ans = 0;
5 5         n && (ans = n + Sum_Solution(n - 1)); //&&即邏輯與,擁有短路特性。(&&左側為false則右側的表示式不執行)
6 6         return ans;
7 7     }
8 8 };
Code01

缺點:遞迴的層數不能太深<3000


 2)sizeof特性,使用公式n(n+1)/2

1 1 class Solution {
2 2 public:
3 3     int Sum_Solution(int n) {
4 4         bool a[n][n+1]; //不行:int(四位元組),short(2位元組)
5 5         //char a[n][n+1]; //可以:char(1位元組)
6 6         return sizeof(a)>>1; //右移等價於除以2
7 7     }
8 8 };
Code02

3)  利用建構函式

 1 class Unit{
 2     public:
 3         Unit(){++N;Sum+=N;}
 4         static void reset(){N=0;Sum=0;} //static
 5         static unsigned int GetSum(){return Sum;} //static
 6     private:
 7         static unsigned int N;
 8         static unsigned int Sum;
 9 };
10 
11 unsigned int Unit::N = 0; //一般在類外初始化(類內也不會報錯)
12 unsigned int Unit::Sum = 0; //類外不用在加static
13 
14 class Solution {
15 public:
16     int Sum_Solution(int n) {
17         Unit::reset();
18         Unit *p = new Unit[n];
19         int res = Unit::GetSum();
20         delete[] p;
21         p=nullptr;
22         return res; //return Unit::GetSum();
23     }
24 };
Code03

注意:

「1」區域性static物件在第一次使用前分配,在程式結束是銷燬。並不是在區域性作用域結束是銷燬。

「2」動態分配的物件的生存期與它們在哪裡建立是無關的,只有當顯式地被釋放時,這些物件才會銷燬。(即必須被顯示銷燬!!區域性作用域並不會自動銷燬

「3」靜態記憶體:用來保護區域性static物件、類static資料成員、以及定義在任何函式外的變數。編譯器建立,程式結束時銷燬(不受區域性作用域控制)。

          棧記憶體:用於儲存定義在函式內的非static物件。僅在定義的程式執行的時候才存在(區域性作用域)。

          自由空間(堆記憶體):儲存動態分配的物件。必須顯示銷燬。         

「4」new預設情況下是預設初始化,即內建物件或組合型物件的值是為定義的,而類型別物件將使用預設建構函式進行初始化:

    string *ps = new string; //初始化為空的字串

               int * pi = new int; //pi指向一個未初始化的int         可使用值初始化:int * pi = new int(); z值初始化為0。  也可以傳入引數:int * pi = new int(1024);

               或列表初始化 vector<int> *pv = new vector<int>{0,1,2,3,4,5,6,7,8,9};

「5」delete接受物件為指標型別,

         當其釋放一塊非new建立的記憶體,或者將相同的指標(指向同一塊記憶體的指標)釋放多次,其行為是未定義的。

「6」當程式用光了可用記憶體,new表示式會失敗,預設情況丟擲std::bad_alloc異常。

         阻止丟擲異常: int *p = new (nothrow) int; //如果失敗返回空指標。


4) 利用虛擬函式求解

 

 

 

基礎知識補充: