题目描述:求1+2+3+....+n,要求不使用乘除法,for,while,if,else,switch,case
等关键字及三目表达式。
题目分析:由于不能使用条件判断的关键字,所以,一般的递归也是不允许的,因为通过
条件判断来确定递归是否结束。但是下边的方法有模仿递归来实现求和。
方法一:构造函数
由于静态成员是属于类而不属于对象,根据这一特性,来实现求和。
下边给出代码:
class Sum
{
public:
Sum()
{
++n;
sum += n;
}
static void ShowSum()//必须是静态成员函数
{
cout << sum << endl;
}
private:
static size_t sum;
static size_t n;
};
size_t Sum::sum = 0;
size_t Sum::n = 0;
int main()
{
Sum* a = new Sum[100];
delete[] a;
a = NULL;
Sum::ShowSum();
system("pause");
return 0;
}
我们知道静态成员是属于类不属于对象,所以静态成员方法无this指针;
静态成员必须在类外进行初始化;
静态方法中不能调用非静态成员变量(解释:返回的时候不知道返回哪个变量的成员)
方法二:虚函数
下边看代码:
class A
{
public:
virtual size_t Sum(size_t n)
{
return 0;
}
};
A* Array[2];
class B :public A
{
public:
virtual size_t Sum(size_t n)
{
return Array[!!n]->Sum(n - 1) + n;
}
};
int main()
{
A a;
B b;
Array[0] = &a;
Array[1] = &b;
int sum = Array[1]->Sum(100);
cout << sum << endl;
system("pause");
return 0;
}
这里用到动态多态。实现多态的标志就是父类指针或者引用指向子类对象。当n>=1时,
!!n都是1.当n=0时,!!n=0.这就是“!!”的用途。父类的虚函数充当着递归结束的条件。
......当递归到n = 1时,Array[1]->Sum(0)+1.而Sum(0) = Array[0]->Sum(-1) = 0.
<小插曲>说到虚函数,说到多态,不由得想到下边这道题目(以分割线分隔开):
-------------------------------------------------------------------------------------------------------
代码如下:
class AA
{
public:
AA()
{
memset(this,0,sizeof(*this));
}
virtual void fun()
{
cout << "fun()" << endl;
}
};
int main()
{
AA a;
a.fun();
AA& ra = a;
ra.fun();
AA* pa = &a;
pa->fun();
system("pause");
return 0;
}
问题是,以上的几个调用语句,哪个编译通过,哪个不通过?
a.fun()调用正确,其他两个都不正确。
解析:构造函数的memset会将函数的虚表指针置为空。而a.fun()是静态多态,调用的时
候并不会去虚表中找,所以是会调用通过。后边两个调用是动态多态,调用的时候会去
虚表中找,而虚表指针已经被置空。所以,在构造函数中尽量不要使用memset等函数.
----------------------------------------------------------------------------------------------------------------
方法三:函数指针:
typedef size_t(*fun)(size_t);
size_t sum1(size_t n)
{
return 0;
}
size_t sum2(size_t n)
{
fun f[2] = { sum1,sum2 };
return n + f[!!n](n-1);
}
int main()
{
cout<<sum2(100)<<endl;
system("pause");
return 0;
}
上边的方法类似于虚函数实现。
方法四:模板
template<size_t n>
struct Sum
{
enum Value
{
N = Sum<n - 1>::N + n
};
};
template<>
struct Sum<1>
{
enum Value
{
N = 1
};
};
int main()
{
cout << Sum<100>::N << endl;
system("pause");
return 0;
}
上述方法利用的是模板的特化来实现对“递归”结束的控制。
好了,这道题目就整理到这里。