大家五一节快乐啦!劳动光荣!
一大早起来刷刷算法题,脑力劳动劳动,结果就发现了这么道神题~
通过这道题,你可以学会:
- 用自己的语言去实现高级语言提供的快捷工具
题目:求 1+2+…+n,
要求不能使用乘除法、 for、 while、 if、 else、 switch、 case 等关键字以及条件判断语句(A?B:C)
我了个去。。不能使用关键字,那不是自废武功吗??
淡定淡定~~想想,当我们使用for、while的时候,高级语言都做了些什么,他们那边的世界可没有for和while。
所以,for、while循环语句只是高级语言给用户提供的循环方式,我们完全可以自己做一个循环器出来!
思路
创建一个结构体(类),在其构造函数中对数字加一,
然后创建一个大小为N的该结构体类型的数组,
自然就会调用N次构造函数,也就实现了从1加到N
下面是我们自己设计的循环器的构造函数的代码
Temp()
{
++N;
Sum += N;
}
非常简单的代码实现,每次调用时都会执行代码块内的语句,
其实就相当于把for(int i = 1;i<n;i++){xxx}中的,xxx和i++放在我们自己设计的循环器的构造函数中。
源代码
#include <stdio.h>
#include<stdlib.h>
#include <iostream>
#include<sstream>
#include <vector>
using namespace std;
/**
题目:求 1+2+…+n,
要求不能使用乘除法、 for、 while、 if、 else、 switch、 case 等关键字以及条件判断语句(A?B:C)。
思路
for、while循环语句只是高级语言给用户提供的循环方式,
我们完全可以自己做一个循环器出来。
方法:
创建一个结构体(类),在其构造函数中对数字加一,
然后创建一个大小为N的该结构体类型的数组,
自然就会调用N次构造函数,也就实现了从1加到N
*/
class Temp
{
public:
Temp()
{
++N;
Sum += N;
}
static void Reset() { N = 0; Sum = 0; }
static int GetSum() { return Sum; }
private:
static int N;
static int Sum;
};
//静态变量初始化
int Temp::N = 0;
int Temp::Sum = 0;
int solution1_Sum(int n)
{
Temp::Reset();
Temp *a = new Temp[n]; //new 出 n 个数组。
//销毁对象,释放内存
delete []a;
a = 0;
return Temp::GetSum();
}
void main()
{
cout<<solution1_Sum(100)<<endl;
system("pause");
}
运行图
怎样,是不是被这道神题洗脑啦,劳动节快乐!
==== 补充 2015/05/02 ====
根据csdn网友 啊-咧-咧 的评论,新增一种解法,核心思想是递归。
下面是求和函数的代码
int sum(int n)
{
(n)&&(n+=sum(n-1));
return n;
}
该函数巧妙的利用了当&&前半部分为假时,&&后面的那一部分不会被执行这样一个特性
所以当递归到当n=0时,&&后面的那一部分不会被执行,所以也就结束了递归!
我们可以以n=2为例,看看整个执行过程
sum(2)
(2)&&(2+=sum(2-1));
sum(1)
(1)&&(1+=sum(1-1));
sum(0)
(0)&&(n+=sum(n-1)); //后半部分不执行,递归结束
return 0;
return n = 1+0 = 1;
return n = 2+1 = 3;
解法二源代码
#include <stdio.h>
#include<stdlib.h>
#include <iostream>
#include<sstream>
#include <vector>
using namespace std;
/**
思路
当n=0时,&&后面的那一部分不会被执行,所以也就结束了递归!
*/
int sum(int n)
{
(n)&&(n+=sum(n-1));
return n;
}
void main()
{
cout<<sum(2)<<endl;
system("pause");
}
总结:
有时候我们可以自己写代码去实现高级语言给我们封装好的工具。