求1+2+…+n

题目:求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次。可以将需要执行的代码放到构造函数里。如下代码正是基于这个思路:

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];
delete[] a;
a = 0; return Temp::GetSum();
}

同样可以围绕递归做文章。既然不能判断是不是应该终止递归,我们不妨定义两个函数。一个函数充当递归函数的角色,另一个函数处理终止递归的情况,我们需要做的就是在两个函数里二选一,从二选一很自然想到布尔变量,比如ture(1)的时候调用第一个函数,false(0)的时候调用第二个函数。那现在的问题是如何把数值变量n转换成布尔值。如果对n连续做两次反运算,即!!n,那么非零的n转换为true,0转换为false。有了上述分析,代码如下:

class A;
A* Array[2]; class A
{
public:
virtual int Sum(int n){ return 0; }
}; class B : class A
{
public:
virtual int Sum(int n)
{
return Array[!!n] -> Sum(n-1)+n;
}
}; int solution2_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);

int solution3_f1(int i)
{
return 0;
} int solution3_f2(int i)
{
fun f[2] = { solution3_f1, solution3_f2 };
return i+f[!!i](i-1);
}

另外还可以让编译器来完成类似递归的运算,代码如下:

template<int n> struct solution4_Sum
{
enum Value{ N = solution4_Sum<n-1>:: N+n };
};
template<> structsolution4_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不能太大。

【Data Structure & Algorithm】求1+2+…+n的更多相关文章

  1. 【Data Structure & Algorithm】求子数组的最大和

    求子数组的最大和 题目:输入一个整型数组,数组里有正数和负数.数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和.求所有子数组的和的最大值,要求时间复杂度为O(n).例如输入数组为1, - ...

  2. [Data Structure & Algorithm] Hash那点事儿

    哈希表(Hash Table)是一种特殊的数据结构,它最大的特点就是可以快速实现查找.插入和删除.因为它独有的特点,Hash表经常被用来解决大数据问题,也因此被广大的程序员所青睐.为了能够更加灵活地使 ...

  3. [Data Structure & Algorithm] 七大查找算法

    查找是在大量的信息中寻找一个特定的信息元素,在计算机应用中,查找是常用的基本运算,例如编译程序中符号表的查找.本文简单概括性的介绍了常见的七种查找算法,说是七种,其实二分查找.插值查找以及斐波那契查找 ...

  4. 【Data Structure & Algorithm】字符串全排列

    字符串全排列 题目:输入一个字符串,打印出该字符串的所有排列.例如输入字符串abc,则输出由字符a.b.c所能排列出来的所有字符串abc.acb.bac.bca.cab.cba. 分析:考察对递归的理 ...

  5. 【Data Structure & Algorithm】在排序数组中查找和为定值的两个数

    在排序数组中查找和为定值的两个数 题目:输入一个已经按升序排序过的数组和一个数字,在数组中查找两个数,使得它们的和正好是输入的那个数字,要求时间复杂度是O(n).如果有多对数字的和等于输入的数字,输出 ...

  6. 【Data Structure & Algorithm】 查找最小的k个元素

    查找最小的k个元素 题目:输入n个整数,输出其中最小的k个. 例如输入1, 2, 3, 4, 5, 6, 7和8这八个数字,则最小的4个数字为1, 2, 3和4. 分析:这道题最简单的思路是把输入的n ...

  7. [Data Structure & Algorithm] 八大排序算法

    排序有内部排序和外部排序之分,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存.我们这里说的八大排序算法均为内部排序. 下图为排序 ...

  8. 【Data Structure & Algorithm】二叉树中和为某值的所有路径

    二叉树中和为某值的所有路径 题目:输入一个整数和一个二叉树,从树的根节点开始往下访问一直到叶节点所经过的所有节点形成一条路径.打印出和与输入整数相等的所有路径. 例如输入整数22和如下二叉树: 10 ...

  9. 【Data structure & Algorithm】把二元查找树转变成排序的双向链表

    把二元查找树转变成排序的双向链表 题目:输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表,要求不能创建任何新节点,只调整指针指向. 比如将二元查找树 10 /       \ 6       ...

随机推荐

  1. Windows 7 &amp; Ubuntu 14.04完美双系统安装及系统引导配置----校园网Mentohust配置

    本文写于完美安装双系统之后,所以图片会不全然.主要目的是总结下注意事项.备用. 一.Win7-64-旗舰版U盘安装 win7-64-旗舰版纯净版下载,下载安装后仅仅有1个驱动人生! 附刻盘工具激活工具 ...

  2. 对canvas arc()中counterclockwise参数的一些误解

    一直没有很细心地去研究CanvasRenderingContext2D对象的arc方法,对它的认识比较模糊,导致犯了一些错误,特发此文,以纠正之前的错误理解. arc()方法定义如下: arc() 方 ...

  3. JS控制input 文本框只允许输入汉字

    onblur="value=value.replace(/[^/u4E00-/u9FA5]/g,'')" onbeforepaste="clipboardData.set ...

  4. jni集成第3方third party动态库libwebrtc_audio_preprocessing.so时android.mk的编写

    现在要调用一个第3方库libwebrtc_audio_preprocessing.so 最终布局如下: 即创建2个文件夹,将第3方库放进去. include目录放第3方库的头文件  其中lib目录如下 ...

  5. Android SDK 更新不下来解决方法

    国内的小伙伴是不是更新SDK总是更新不动呢,小弟找到一个好的解决方式,把SDK的全部都下载全了也就用了一个小时,匀速2M/s. 解决方法是改动win7的host文件. 路径:C:\Windows\Sy ...

  6. 针对Web.config敏感信息加密

    cd C:\Windows\Microsoft.NET\Framework\v4.0.30319 ==在appSettings节点上添加== <configProtectedData> & ...

  7. Share Memory By Communicating

    Share Memory By Communicating - The Go Programming Language https://golang.google.cn/doc/codewalk/sh ...

  8. 如何让A20,android开机自动启动C程序【转】

    本文转载自:http://blog.csdn.net/u011258134/article/details/50749174 如何让A20,android开机自动启动C程序 2014-12-26 11 ...

  9. HDU4686 Arc of Dream —— 矩阵快速幂

    题目链接:https://vjudge.net/problem/HDU-4686 Arc of Dream Time Limit: 2000/2000 MS (Java/Others)    Memo ...

  10. Spring MVC 注解开发详解

    @Controller控制器定义 1.Controller是单利模式,被多个线程请求共享,因此设计成无序状态. 2.通过@controller标注即可将class定义为一个controller类.为使 ...