微软面试百题012——5050的各种限制解法

来源:互联网 发布:巴黎贝甜 加盟费 知乎 编辑:程序博客网 时间:2024/06/03 20:23

1.问题描述:

题目:求1+2+…+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字以及条件判断语句(A?B:C)。

2.解法:

2.1位运算:

首先我们需要了解一下,在该操作中我们需要用奥的位运算有哪些首先,我们根据公式对式子进行化简
原式=(n*n+n)/2

首先对于最后的除以2操作我们直接调用右移操作就可以实现:
在这里我解释一下,为什么右移k位相当于对2^k做除法,首先我们要知道,在二进制转化成十进制的时候我们是对每一位乘上2的几次方最后做的加法,那么显然,我们一旦执行了移位操作之后,我们每一位是1的对应 的乘的倍数便都会下降,自然就实现了除以每一位都是对2的次方做除法,整体的数值也就相当于对2的次方做除法

其次,我们来看看如何不用乘法和循环来实现n*n的操作,这里我们就会看到这种方法 的局限性了,我们要对二进制做乘法,只能利用我们乘法的基本操作,但是我们是实现不明白该数 的大小的,所以说,我们需要手动进行很多次操作,这里明显就会很麻烦,所以说我们不建议用这种方法

2.2类的静态成员+构造函数

我们这里有一个好方法,在之前,我们需要知道两点
1.类的构造对象的时候必定会调用构造函数,并且,如果我们构造一些列对象的时候,这种情况也是对的,我们会隐式的调用一系列的构造函数
这里我们就会看到循环的影子

2.静态成员,我们知道,类的静态成员一个类只有一份内存空间,并且类的静态成员修改之后的效果在对象之间是互相影响的,所以说,这一点结合上面的构造函数的方式可以模拟一个循环的过程

3.代码如下:
#include"iostream"#include"cstdio"#include"cstdlib"#include"cstring"using namespace std;class test{public:test(){++n;sum+=n;}void reset(){n=0;sum=0;}static int returnresult(){return sum;}private:static int n;static int sum; };int test::n=0;int test::sum=0;int main(){test my[100];cout<<test::returnresult()<<endl;return 0;} 

2.3虚函数+多态终止递归

我们采用虚函数,一个类的函数充当终止条件,另一个类的函数充当递归的条件
具体看代码:
#include"iostream"#include"cstring"#include"cstdlib"#include"cstdio"using namespace std;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){n--;return array[!!n]->sum(n)+n+1;}};int main(){a test1;b test2;array[0]=&test1;array[1]=&test2;cout<<array[1]->sum(100)<<endl;return 0;}


2.4逻辑与的短路+递归终止条件

#include"stdio.h"int sum(int n){int val=0;n&&(val=n+sum(n-1));return val;}int main(){printf("%d\n",sum(100));return 0;}

2.5C++模板特化+递归终止条件

#include"iostream"#include"cstdio"#include"cstdlib"using namespace std;template<int N>class a{public:a(){sum=0;}int sum;int getsum(int n=N-1){a<N-1> b;sum=b.getsum(n)+N;return sum;}};template<>class a<0>{public:int sum=0;int getsum(int n){return 0;}};int main(){a<10> b;cout<<b.getsum()<<endl;return 0;} 



1 0
原创粉丝点击