剑指offer---不使用循环条件判断等实现求和

来源:互联网 发布:网店美工是什么专业 编辑:程序博客网 时间:2024/05/21 08:00

题目描述:求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;}


上述方法利用的是模板的特化来实现对“递归”结束的控制。

好了,这道题目就整理到这里。



1 0
原创粉丝点击