1、题目:求1+2+.....+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。
通常求求1+2+.....+n除了用公式n(n+1)/2之外,还有递归和循环两种方法。
解法一:利用构造函数求解
循环只是让相同的代码重复执行n遍而已。我们可以先定义一个类型,接着创建n个该类型的实例,那么这个类型的构造函数将确定会被调用n次。我们可以将与累加相关的代码放到构造函数里。
class Temp
{
public:
Temp() {++N; Sum += N; }
static void Reset() {N=0; Sum=0;}
static unsigned int GetSum() {return Sum;}
private:
static unsigned int N;
static unsigned int Sum;
};
unsigned int Temp::N = 0;
unsigned int Temp::Sum = 0;
unsigned int Sum_Solution1(unsigned int n)
{
Temp::Reset();
Temp *a = new Temp[n];
a = NULL;
return Temp::GetSum();
}
解法二:利用虚函数求解
定义两个函数,一个充当递归函数,一个处理终止递归的情况,我们在两个函数里选一个,用布尔变量来表示。关键是如何把数值变量n转换成布尔值。如果对n连续做两次反运算,即!!n,那么非零的n转换为true,0转换为false。
class A;
A* array[2];
class A
{
public:
virtual unsigned int Sum(unsigned int n)
{
return 0;
}
};
class B:public A
{
public:
virtual unsigned int Sum(unsigned int n)
{
return array[!!n]->Sum(n-1) + n;
}
};
int Sum_Solution2(int n)
{
A a;
B b;
array[0] = &a;
array[1] = &b;
int value = array[1]->Sum(n);
return value;
}
这种思路是用虚函数来实现函数的选择。当n不为零时,调用函数B::Sum;当n等于0时,调用函数A::Sum。
解法三:利用函数指针求解
typedef unsigned int (*fun)(unsigned int);
unsigned int Soultion3_Teminator(unsigned int n)
{
return 0;
}
unsigned int Sum_Solution3(unsigned int n)
{
static fun f[2] = {Soultion3_Teminator, Sum_Solution3};
return n + f[!!n] (n - 1);
}
解法四:利用模板类型求解
template <unsigned int n> struct Sum_Solution4
{
enum Value { N = Sum_Solution4<n - 1>::N + n};
};
template < > struct Sum_Solution4<1>
{
enum Value { N = 1; };
};
Sum_Solution4<100>::N就是1+2+.....+100的结果。
当编译器看到Sum_Solution4<100>时,就会为模板Sum_Solution4以参数100生成该类型的代码。
但此种方法要求输入的n必须是在编译期间就能确定的常量,不能动态输入。