c言語は1+2+...+を求めますnの解決方法

3123 ワード

テーマ:1+2+…+nを求めて、乗除法、for、while、if、else、switch、caseなどのキーワードと条件判断文(A?B:C)を使うことができないことを要求します.
分析:この問題はあまり実用的な意味がありません.ソフトウェア開発ではこのような変態の制限はありませんから.しかし、この問題は発散思考能力を効果的に調べることができ、発散思考能力はプログラミング関連技術の理解の深さを反映することができる.
通常、1+2+...+nを求めるには、式n(n+1)/2を用いる以外に、サイクルと再帰の2つの考え方にほかならない.forとwhileの使用が明確に制限されているため、ループはもう使えません.同様に,再帰関数もif文または条件判断文で再帰を継続するか終了するかを判断する必要があるが,現在では問題ではこの2つの文の使用は許されていない.
私たちは依然として循環をめぐって文章を作っている.ループは同じコードをn回実行させるだけで、forとwhileを使わずにこの効果を達成することができます.たとえばクラスを定義し、newがn個のこのタイプの要素を含む配列を定義すると、クラスの構造関数はn回呼び出されると決定します.実行するコードをコンストラクション関数に入れることができます.次のコードは、この考え方に基づいています.
 
  
class Temp
{
private:
 static int N;
 static int Sum;
public:
 Temp() {   ++ N;   Sum += N;    }
 static void Reset() {   N = 0;   Sum = 0; }
 static int GetSum() {   return 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();
}

私たちも再帰をめぐって文章を作ることができます.再帰を終了すべきかどうか判断できない以上、2つの関数を定義してみましょう.1つの関数は再帰関数の役割を果たし、もう1つの関数は再帰を終了する場合を処理し、私たちがしなければならないのは2つの関数の中で1つを選択することです.2つの選択肢から1つを選ぶと自然にブール変数を思い浮かべます例えば、ture(1)のときに1番目の関数を呼び出し、false(0)のときに2番目の関数を呼び出す.では、現在の問題は、数値変数nをブール値に変換することである.nに対して2回連続して逆演算を行うと、すなわち!!n、ゼロでないnはtrueに変換され、0はfalseに変換される.上記の解析から、次のコードを見る.
 
  
class A;
A* Array[2];
class A
{
public:
 virtual int Sum (int n) { return 0; }
};
class B: public A
{
public:
 virtual int Sum (int n) { return Array[!!n]->Sum(n-1)+n; }
};
int solution2_Sum(int n)
{
 A a;

 Array[0] = &a;
 Array[1] = &b;
 int value = Array[1]->Sum(n);
 return value;
}

この方法は虚関数を用いて関数の選択を実現する.nがゼロでない場合、実行関数B::Sum;nが0の場合、A::Sumを実行します.関数ポインタ配列を直接使用することもできます.これにより、より直接的になる可能性があります.
 
  
typedef int (*fun)(int);
int solution3_f1(int i)
{
 return 0;
}
int solution3_f2(int i)
{
 fun f[2]={solution3_f1, solution3_f2};
 return i+f[!!i](i-1);
}

また、次のコードのような再帰的な演算をコンパイラに手伝ってもらうこともできます.
 
  
template struct solution4_Sum
{
 enum Value { N = solution4_Sum::N + n};
};
template <> struct solution4_Sum<1>
{
 enum Value { N = 1};
};

solution4_Sum<100>::Nは1+2+...+100の結果.コンパイラがsolution 4_を見たらSum<100>の場合、テンプレートクラス
solution4_Sumは、このタイプのコードをパラメータ100で生成する.ただし、solution 4_Sum<100>::N=solution4_Sum<99>::N+100.このプロシージャは、パラメータが1のタイプまで再帰されます.このタイプは明示的に定義されているため、コンパイラは生成する必要はありません.再帰コンパイルはこれで終わります.このプロセスはコンパイル中に完了するため,入力nはコンパイル中に決定され,動的に入力できない必要がある.これはこの方法の最大の欠点である.また,コンパイラは再帰コンパイルコードの再帰深さに制限があり,すなわちnがあまり大きくならないことが要求される.