面试题:使用递归的方法计算1到100的累加。

今天去面试,遇到这道题目,有段时间没写程序了,温习一下:

题目是使用递归的方法计算1到100的累加,也就是计算1+2+3+4+........+100。大家想必已经听说过高斯如何计算这道题的故事,也知道答案是5050。我整理了一下使用递归解决的思路,与大家分享。

递归的特点就是递归函数本身会调用自己,对应到逻辑上就是一段逻辑会使用这段逻辑自身。要使用递归的方法解决这道题,就要先用递归的思维方式描叙这道题。

我们来看看如何描叙题目本身,最直观的描叙:“从1开始,后一个数加上前一个数,后一个数是前一个数加一所得,一直加到100”,但这种描叙无法转化为递归的方法。我们试着按递归的思路思考这个问题,“做一件事情的步骤又包含这个事情步骤的自身”:
  1. 最开始一定是“1”+“某个值
  2. 如果按老思路,这个“某个值”是“1”再加"1",也就是“2”
  3. 到这里,已经完成了一段步骤,并且如果这种思路能形成递归,上面的两步的描叙里面应该会包含对自身同样步骤的一段描叙,但我们仔细想想,里面却没有。
  4. 那我们换个角度思考一下,这个“某个值"也可以是‘2’到‘100’累加的和。到这里,我们看到了点希望,因为”累加的和“这个词就是第1、2步在做的事。
  5. 那么‘2’到‘100’累加的和又应该是‘2’加上”‘3’到‘100’累加的和“,这里我们已经看到递归的迹象了。
  6. 再举一例看看,‘3’到‘100’累加的和又应该是‘3’加上”‘4’到‘100’累加的和“
  7. 对于递归,还有最重要的一点就是这种嵌套何时终止,不然就无穷无尽了。我们看看最后一步,也就是‘100‘到’100‘累加的和是多少?这次我们不用,也无法递归调用了,结果应该直接就是100,所以到这一步,递归终止。

对于整个问题,我们可以进一步抽象为用递归法求两个正整数(m,n)累加和的问题,我们还要考虑m<n, m=n, m>n这三种参数传入方式不同的情况。下面是我写的C#代码,以供参考:

using System;
using System.Collections.Generic;
using System.Text;

namespace Accumulation
{
    class Program
        {
        public static int Accum(int m, int n)
        {
           //对于接受的参数,要考虑m >n,m=n,m<n三种情况。
            if (m < n)
            {
                 return (m + Accum(++m, n)); //如果m<n,返回“m”加上“m+1到n累加的和”
            }

            else
           {
                if (m > n)
               {
                    return (m + Accum(--m, n)); //如果m.n,返回“m”加上“m-1到n累加的和”
            }

                else
                {
                    return n; //如果m=n,直接返回n,这是递归的关键。
                }


           }

        }


        static void Main(string[] args)
        {
            Console.WriteLine(
"The Result of Accumulation from 1 to 100 is:" + Accum(1100));
            Console.WriteLine(
"The Result of Accumulation from 1000 to 1 is:" + Accum(10001));
            Console.WriteLine(
"The Result of Accumulation from 80 to 80 is:" + Accum(8080));
        }

    }

}



posted on 2008-05-12 21:42 m2land 阅读(1701) 评论(19)  编辑 收藏

评论

#1楼  2008-05-12 21:47 oo縼箻ㄗs.鋒      

http://hi.baidu.com/ifos/blog/item/9a0a40812ced9edbbd3e1ec4.html
劝你不要用递归了.太浪费时间了.   回复  引用  查看    

#2楼 [楼主] 2008-05-12 21:58 land      

考试题目吗,讨论的理论知识问题,这里就不讨论效率问题了,递归往往是效率最低的。其实这就是一个等差数列求和,使用公式运算甚至可以不用循环。   回复  引用  查看    

#3楼  2008-05-12 22:10 Jianchidaodi      

为什么这么递归啊?
class Program
{
static void Main(string[] args)
{
//test
Console.WriteLine(Calc(-100));
Console.WriteLine(Calc(100));

}

public static int Calc(int num)
{
if (num == 0)
return num;
else
{
if (num > 0)
return num + Calc(num - 1);
else
return num + Calc(num + 1);
}
}
}   回复  引用  查看    

#4楼 [楼主] 2008-05-12 22:19 land      

这样道理一样,只是比如计算从20到100的累加就没法计算了。   回复  引用  查看    

#5楼  2008-05-13 02:06 Cat Chen      

这么简单的事情,谁都能想到循环递推怎么做,还要用递归,出题者显然有问题,纯粹为考试而考试。   回复  引用  查看    

#6楼  2008-05-13 03:11 jeff377      

這個問題不需要使用遞迴,只需要使用「梯形面積的計算方法」即可,即 (上底+下底)*高/2。

例如 1..100
(1+100)*(100-1+1)/2=5050

例如 20..100
(20+100)*(100-20+1)/2=4860   回复  引用  查看    

#7楼  2008-05-13 09:05 布鲁斯南      

num + Calc(num - 1) 就可以了啊.
为什么搞个那么复杂的递归.   回复  引用  查看    

#8楼 [楼主] 2008-05-13 09:27 land      

最高效的方法就是 jeff377说的使用等差数列求和公式。 Jianchidaodi和 布鲁斯南 的方法,问题是没有通用性,无法计算任意两个正整数m,n的累计和。   回复  引用  查看    

#9楼  2008-05-13 09:45 装配脑袋      

public static int Accum(int m, int n)
{
  int a = Math.Min(m, n);
  int b = Math.Max(m, n);
  return (a + b) * (b - a + 1) / 2;
}

哪里不通用了?   回复  引用  查看    

#10楼  2008-05-13 11:42 neil shu [未注册用户]

这也值得放首页?
太捉弄人的感情了!!!

君子自重!!!   回复  引用  查看    

#11楼  2008-05-13 11:42 hailibu      

不考虑效率,还是蛮有创意滴   回复  引用  查看    

#12楼  2008-05-13 13:26 Justin      

(上底+下底)× 高 /2 即可吧   回复  引用  查看    

#13楼  2008-05-13 13:34 钢钢      

我用C语言调试了一下,C语言版本如下:

# include<stdio.h>

int plus (int x, int y)
{
if(x < y)
{
return (x + plus(x+1,y));
}
else
{
if(x > y)
{
return (x + plus(x-1,y));
}
else return x;
}
}

void main()
{
printf( "累加的和是 %d \n",plus(3,1));
}

  回复  引用  查看    

#14楼  2008-05-13 13:51 RZ [未注册用户]

谁考你这题,说明那人脑子有毛病!!!   回复  引用  查看    

#15楼  2008-05-13 15:03 wayich      

只是一次考试而以。没什么大不了的。   回复  引用  查看    

#16楼  2008-05-13 15:12 zsensi [未注册用户]

这题让我想起高中的一条数学公式
计算:1+2+3+...+n-1+n
公式:(1+n)*n/2

就这简单,效率高。。。

看回复,原来可以这样记,(上底+下底)*高/2 。。。。。。   回复  引用  查看    

#17楼  2008-05-13 18:04 罗晓梅      

值得借鉴的思想   回复  引用  查看    

#18楼  2008-05-13 18:51 liuhong2003 [未注册用户]

这样做有意义吗?   回复  引用  查看    

#19楼  2008-05-14 11:20 Klesh Wong      

有可能出题的人根本是在考你会不会query这个题目。
就是看看你会不会反驳这个命题,转而使用梯形公式。
总的来说,出题的人不是大智就是大愚!   回复  引用  查看    


标题  
姓名  
主页
Email (只有博主才能看到) 
验证码 *  看不清,换一张
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2008-05-12 21:50 编辑过
 
另存  打印
最新IT新闻:
 

导航

公告

统计

与我联系

我管理的小组

我参与的团队

随笔分类

搜索

积分与排名

最新评论

阅读排行榜

评论排行榜

60天内阅读排行