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;
}