1+2+...+nの異なる解法を探求しますか?
テーマ:1+2+…+nを求めて、乗除法、for、while、if、else、switch、caseなどのキーワードと条件判断文(A?B:C)を使うことができないことを要求します.
構想:通常1+2+...+nを求めるのは公式n(n+1)/2を使う以外に、循環と再帰の2つの構想にほかならない.
1、&&のショート特性を利用して、再帰を使う
2、クラスの構造関数+静的変数の妙用
ループは同じコードをn回実行させるだけで、forとwhileを使わずにこの効果を達成することができます.たとえばクラスを定義し、newがn個のこのタイプの要素を含む配列を定義すると、クラスの構造関数はn回呼び出されると決定します.実行するコードをコンストラクション関数に入れることができます.
3、虚関数の妙用
私たちも再帰をめぐって文章を作ることができます.再帰を終了すべきかどうか判断できない以上、2つの関数を定義してみましょう.1つの関数は再帰関数の役割を果たし、もう1つの関数は再帰を終了する場合を処理し、私たちがしなければならないのは2つの関数の中で1つを選択することです.2つの選択肢から、ture(1)のときに最初の関数を呼び出し、false(0)のときに2番目の関数を呼び出すなど、ブール変数を自然に思い浮かべます.では、現在の問題は、数値変数nをブール値に変換することです.nに対して連続して2回の反演算をすれば、すなわち!!n,では非ゼロのnはtrueに変換され,0はfalseに変換される.上記の分析では、次のコードを見てみましょう.
この方法は虚関数を用いて関数の選択を実現する.nがゼロでない場合、実行関数B::Sum;nが0の場合、A::Sumを実行します.4、関数ポインタの使い勝手
3つ目の方法は、関数ポインタ配列を直接使用することもできます.これにより、より直接的になる可能性があります.
構想:通常1+2+...+nを求めるのは公式n(n+1)/2を使う以外に、循環と再帰の2つの構想にほかならない.
1、&&のショート特性を利用して、再帰を使う
int add_fun(int n)
{
int sum=0;
n && (sum=add_fun(n-1));
return sum+n;
}
2、クラスの構造関数+静的変数の妙用
ループは同じコードをn回実行させるだけで、forとwhileを使わずにこの効果を達成することができます.たとえばクラスを定義し、newがn個のこのタイプの要素を含む配列を定義すると、クラスの構造関数はn回呼び出されると決定します.実行するコードをコンストラクション関数に入れることができます.
#include "stdafx.h"
#include "stdlib.h"
#include <iostream.h>
#include <string.h>
class Temp {
public:
Temp() { ++ N;Sum += N; }
static void Reset() { N = 0; Sum = 0; }
static int GetSum() { return Sum; }
private:
static int N;
static int Sum;
};
int Temp::N = 0;
int Temp::Sum = 0;
int solution1_Sum(int n)
{
Temp::Reset();
Temp *a = new Temp[n];
delete []a; a = 0;
return Temp::GetSum();
}
void main()
{
cout<<solution1_Sum(100)<<endl;
}
3、虚関数の妙用
私たちも再帰をめぐって文章を作ることができます.再帰を終了すべきかどうか判断できない以上、2つの関数を定義してみましょう.1つの関数は再帰関数の役割を果たし、もう1つの関数は再帰を終了する場合を処理し、私たちがしなければならないのは2つの関数の中で1つを選択することです.2つの選択肢から、ture(1)のときに最初の関数を呼び出し、false(0)のときに2番目の関数を呼び出すなど、ブール変数を自然に思い浮かべます.では、現在の問題は、数値変数nをブール値に変換することです.nに対して連続して2回の反演算をすれば、すなわち!!n,では非ゼロのnはtrueに変換され,0はfalseに変換される.上記の分析では、次のコードを見てみましょう.
#include "stdafx.h"
#include "stdlib.h"
#include <iostream.h>
#include <string.h>
class A
{
public:
virtual int Sum (int n) { return 0; }
};
A *Array[2];
class B: public A
{
public:
virtual int Sum (int n) { return Array[!!n]->Sum(n-1)+n; }
};
int solution2_Sum(int n)
{
A a; B b;
Array[0] = &a;
Array[1] = &b;
int value = Array[1]->Sum(n);
return value;
}
void main()
{
cout<<solution2_Sum(100)<<endl;
}
この方法は虚関数を用いて関数の選択を実現する.nがゼロでない場合、実行関数B::Sum;nが0の場合、A::Sumを実行します.4、関数ポインタの使い勝手
3つ目の方法は、関数ポインタ配列を直接使用することもできます.これにより、より直接的になる可能性があります.
#include "stdafx.h"
#include "stdlib.h"
#include <iostream.h>
#include <string.h>
typedef int (*fun)(int);
int solution3_f1(int n) { return 0; }
int solution3_f2(int n)
{
fun f[2]={solution3_f1, solution3_f2};
return n+f[!!n](n-1);
}
void main()
{
cout<<solution3_f2(100)<<endl;
}