求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. 测试 MD

    上面是一张图片 总店?

  2. 华为OJ 名字美丽度

    这是一道坑爹的题目,为什么这么说,且看我慢慢分析-- 题目例如以下: 给出一个名字,该名字有26个字符串组成,定义这个字符串的"美丽度"是其全部字母"美丽度"的 ...

  3. 福昕熊雨前:PDFium开源项目的背后

    今天编译android的时候,无意中看到命令行提示出输出编译external/pdfium这个目录,于是乎上百度搜索了一下,找到了如下关于PDF文件解析的开源代码的文章: http://www.csd ...

  4. 从头认识java-14.1 再次对照数组与容器

    这一章节我们再次深入的对照数组与容器. 数组与容器主要集中在三个方面:效率.类型.基础类型. 我们能够从三方面做出对照. 1.效率 这里的下来是指add和get 的速度 以下以add为例: packa ...

  5. kubectl技巧之查看资源列表,资源版本和资源schema配置

    系列目录 在kubernetes里,pod,service,rs,rc,deploy,resource等对象都需要使用yaml文件来创建,很多时候我们都是参照照官方示例或者一些第三方示例来编写yaml ...

  6. 简单的HTML5音乐播放器(带歌词滚动)

      // // 0) { this.lrcArr.push(item); } } frag = document.createDocumentFragment(); for(i = 0,len = t ...

  7. LeetCode(155)题解--Min Stack

    https://leetcode.com/problems/min-stack/ 题目: Design a stack that supports push, pop, top, and retrie ...

  8. LeetCode(82)题解: Remove Duplicates from Sorted List II

    https://leetcode.com/problems/remove-duplicates-from-sorted-list-ii/ 题目: Given a sorted linked list, ...

  9. 更改UISearchBar button属性

    //点击搜索框时触发 - (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar { self.theSearchUserSearchBa ...

  10. 【BZOJ4811】[Ynoi2017]由乃的OJ 树链剖分+线段树

    [BZOJ4811][Ynoi2017]由乃的OJ Description 由乃正在做她的OJ.现在她在处理OJ上的用户排名问题.OJ上注册了n个用户,编号为1-",一开始他们按照编号排名. ...