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) 利用虛擬函式求解
基礎知識補充: