题目:求1+2+…+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字以及条件判断语句(A?B:C)。
分析:这道题没有多少实际意义,因为在软件开发中不会有这么变态的限制。但这道题却能有效地考查发散思维能力,而发散思维能力能反映出对编程相关技术理解的深刻程度。
通常求1+2+…+n除了用公式n(n+1)/2之外,无外乎循环和递归两种思路。由于已经明确限制for和while的使用,循环已经不能再用了。同样,递归函数也需要用if语句或者条件判断语句来判断是继续递归下去还是终止递归,但现在题目已经不允许使用这两种语句了。
我们仍然围绕循环做文章。循环只是让相同的代码执行n遍而已,我们完全可以不用for和while达到这个效果。比如定义一个类,我们new一含有n个这种类型元素的数组,那么该类的构造函数将确定会被调用n次。我们可以将需要执行的代码放到构造函数里。如下代码正是基于这个思路:
classTemp
{
public:
Temp() { ++ N; Sum += N; }
static
void Reset() { N = 0; Sum = 0; }
static
int GetSum() {
return Sum; }
private:
static
int N;
static
int Sum;
};
intTemp::N = 0;
intTemp::Sum = 0;
intsolution1_Sum(int
n)
{
Temp::Reset();
Temp *a =
new Temp[n];
delete []a;
a = 0;
return Temp::GetSum();
}
我们同样也可以围绕递归做文章。既然不能判断是不是应该终止递归,我们不妨定义两个函数。一个函数充当递归函数的角色,另一个函数处理终止递归的情况,我们需要做的就是在两个函数里二选一。从二选一我们很自然的想到布尔变量,比如ture(1)的时候调用第一个函数,false(0)的时候调用第二个函数。那现在的问题是如和把数值变量n转换成布尔值。如果对n连续做两次反运算,即!!n,那么非零的n转换为true,0转换为false。有了上述分析,我们再来看下面的代码:
classA;
A*Array[2];
classA
{
public:
virtual
int Sum (int n) {
return 0; }
};
classB:
public A
{
public:
virtual
int Sum (int n) {
return Array[!!n]->Sum(n-1)+n; }
};
intsolution2_Sum(int
n)
{
A a;
B b;
Array[0] = &a;
Array[1] = &b;
int value =Array[1]->Sum(n);
return value;
}
这种方法是用虚函数来实现函数的选择。当n不为零时,执行函数B::Sum;当n为0时,执行A::Sum。我们也可以直接用函数指针数组,这样可能还更直接一些:
typedef
int (*fun)(int);
intsolution3_f1(int
i)
{
return 0;
}
intsolution3_f2(int
i)
{
fun f[2]={solution3_f1, solution3_f2};
returni+f[!!i](i-1);
}
另外我们还可以让编译器帮我们来完成类似于递归的运算,比如如下代码:
template <int n>
struct solution4_Sum
{
enum Value {N = solution4_Sum<n - 1>::N + n};
};
template <>
struct solution4_Sum<1>
{
enum Value {N = 1};
};
solution4_Sum<100>::N就是1+2+...+100的结果。当编译器看到solution4_Sum<100>时,就是为模板类solution4_Sum以参数100生成该类型的代码。但以100为参数的类型需要得到以99为参数的类型,因为solution4_Sum<100>::N=solution4_Sum<99>::N+100。这个过程会递归一直到参数为1的类型,由于该类型已经显式定义,编译器无需生成,递归编译到此结束。由于这个过程是在编译过程中完成的,因此要求输入n必须是在编译期间就能确定,不能动态输入。这是该方法最大的缺点。而且编译器对递归编译代码的递归深度是有限制的,也就是要求n不能太大。
分享到:
相关推荐
用递归求1+2+3+...+n的算法。初学者使用。
1158:求1+2+3+... 时间限制: 1000 ms 内存限制: 65536 KB 提交数: 14633 通过数: 12299 【题目描述】 用递归的方法求1+2+3+……+N的值。 【输入】 输入N。 【输出】 输出和。 【输入样例】 5 【输出样例】 15 ...
【C语言】1+2+3+...+n的值源码 适用于初学者学习
java代码-使用Java递归求和1+2+3+...+n的源代码 ——学习参考资料:仅用于个人学习使用!
编程求1+1/2+1/3+...+1/n 输入 输入:输入一行,只有一个整数n(1<=n) 输出 输出:输出只有一行(这意味着末尾有一个回车符号),包括1个实数。(保留3位小数) 样例输入 Copy 5 样例输出 Copy 2.283
C语言程序设计-编写函数fun求s=1^k+2^k +3^k + ......+N^k的值,(1的K次方到N的K次方的累加和);
算法的特性:输入输出、有穷性、确定性、可行性。 时间复杂度:T(n)=O(f(n))。 空间复杂度:S(n)=O(f(n))。...常用的时间复杂度所耗费的时间从小到大依次是:O(1)(logn)(n)(n logn)(n²)(n³)(2的n次方)(n!)(n的n次方)
求n个整数的阶乘1!+2!+3!+...n!,VB.net源代码
求1+1*2+1*2*3+...+1*2*3*...*n的和
课程的随堂作业,C语言的,用dev就能运行,萌新代码,勿喷,仅仅帮助不想写作业的朋友方便一下,反正老师也不会仔细检查的
C语言程序设计-编写程序求无理数e的值并输出;计算公式为:e=1+11!+12!+13!+......+1n!当1n!0.000001时e=2.718282;.c
C语言程序设计-编写函数求表达式的和(n的值由主函数输入);1-12+13-14+......+1m例如:当n=20时,表达式的值为0.668771;.c
C语言是一门面向过程的、抽象化的通用程序设计语言,广泛应用于底层开发。C语言能以简易的方式编译、处理低级存储器。C语言是仅产生少量的机器语言以及不需要任何运行环境支持便能运行的高效率程序设计语言。...
递归 阶乘 求和 用两个递归实现1!+2!+3!+。。。+n! 对新手有帮助!
编一个程序,用while循环语句来计算1+1/2+2/3+3/4+...+99/100之和。
c语言程序设计教程(第二版)谭浩强,经典例题,对于学习c语言有很大帮助
本专辑为您列举一些(含源码)方面的下载的内容资源。把最新最全的(含源码)推荐给您,让您轻松找到相关应用信息,并提供(含源码)下载等功能。本站致力于为用户提供更好的下载体验,如有最新(含源码)相关资源信息会推送给...
python1.使用while循环实现输出2-3+4-5+6...+100 的和_一个倔强的女孩的博客-CSDN博客_python1+2+3+4+5+6+…+100代码.pdf
一种是用java中递归思想完成1+2+3+5+8+13+...+n的求和算法; 另一种是用java中一般for循环来完成1+2+3+5+8+13+...+n的求和算法; 把文件解压后编译一下就可以运行了,