黑马程序员技术交流社区

标题: 关于递归的问题 [打印本页]

作者: 王春蕾    时间: 2014-4-23 22:24
标题: 关于递归的问题
我写了一个累加一个从0到指定值的求和的递归方法,代码如下:
  1.         public static int getSum(int maxValue) {
  2.                 if (maxValue == 1)
  3.                         return 1;
  4.                 else {
  5.                         return maxValue + getSum(maxValue-1);
  6.                 }
  7.         }
复制代码

运行可以得到正确的答案,但是我能不能把else里面的getSum(maxValue-1)改成getSum(maxValue--)呢?
改过运行时内存溢出,为什么不行啊?
作者: kuroro自走核炮    时间: 2014-4-23 22:32
本帖最后由 kuroro自走核炮 于 2014-4-23 22:45 编辑


i=3
a=i++
a=3,i=4

i=3
a=++i
a=4,i=4



运算先后顺序问题……
return maxValue + getSum(maxValue--);
先getSum(maxValue)再maxValue--
无限循环了

作者: igi9009    时间: 2014-4-23 22:41
这里有一个问题,就是maxValue--和--maxValue的区别。
--maxValue是把maxValue的值先减一再赋给getSum.
maxValue--是先把maxValue的值赋给getSum.然后再减一,但是减一的值没有重新赋给maxValue,所以getSum的得到的maxValue一直都是原来的数,进入了无限循环。所以就内存溢出了。所以把maxValue--改成--maxValue就行了
  1. public static int getSum(int maxValue) {

  2.                 if (maxValue == 1)

  3.                         return 1;

  4.                 else {

  5.                         return maxValue + getSum(--maxValue);

  6.                 }

  7.         }
复制代码

作者: xtxiaolu    时间: 2014-4-23 22:50
本帖最后由 xtxiaolu 于 2014-4-23 23:04 编辑

递归就是自己调用自己,如果是-1也就是循环到(maxValue-1)-1,如果是--哪么每次过来就自身 - 一次哪么也就成了死循环.所以就溢出了呀!
对应的API文档:当应用程序递归太深而发生堆栈溢出时,抛出该错误。

作者: 清风夜独醉    时间: 2014-4-23 23:08
maxValue--是先把maxValue的值做getSum的参数传进去做运算,然后再减1,getSum实际得到的参数是10,由于是递归,所以每次都是执行getSum(10),无限循环下去了。
楼主可能没搞明白a--和--a的区别。把maxValue--换成--maxValue就可以正常运行了。

另外补充一点,“内存溢出”描述的不够具体,应该是内存中的“栈溢出”。
作者: 大恶魔先森~    时间: 2014-4-23 23:17
这就是a--与--a的区别了,a--是先参加运算,然后再自减一。而--a是先自减一,在参加运算。而你上面那个题目需要的是先自减一在运算,如果换成--maxValue应该就可以了。
作者: 心?=忐§忑]    时间: 2014-4-23 23:18
其实就是--在前还是在后的问题,在后,先运算,在自减,在前,先自减,在调用。
经过修改代码:
  1. public class Demo8 {
  2.     public static void main(String args[]){
  3.             System.out.println(getSum(10)) ;
  4.     }
  5.     public static int getSum(int maxValue) {
  6.         if (maxValue == 1)
  7.                 return 1;
  8.         else {
  9.                 return maxValue + getSum(--maxValue);  //修改此处,减减在前
  10.         }
  11.     }
  12. }
复制代码

作者: fufeng    时间: 2014-4-23 23:41
getSum(maxValue--):是maxValue先被getSum方法调用,然后再自减
getSum(--maxValue):是maxValue先自减,再被getSum方法调用

比如:如下代码输出结果
class  DiGui
{
public static void main(String[] args)
{
     int x = 3;
     get(x--);//结果为3,即先被调用了
     System.out.println(x);//结果为2,即被调用之后在自减了
}
   public static void get(int maxValue)
{
   System.out.println(maxValue);
}
}
当你将代码改为下面的时候
getSum(maxValue--):在调用自身方法时,总是在调用你maxValue,而没有将自减后值的传递给getSum方法,这样就会永远满足不等于1的条件无限递归

所以要改为
getSum(--maxValue):先自减,自减后的值在被方法调用,就可以了




作者: 四川男人    时间: 2014-4-24 00:01
return maxValue + getSum(maxValue--);//这里的问题。
单目运算符--在右边,是先赋值再自减,所以运行一次以后,先赋值给getSum()再自减1,所以计算的还是原来的getSum(maxValue),陷入了死循环,
你可以改成--maxValue,先自减再赋值,就不会了
作者: peku    时间: 2014-4-24 09:28
每次调用getSum(maxValue--)都会在栈内存中开辟属于下一个getSum函数的maxValue局部变量来接收值,如果传递是表达式maxValue--则会将本次maxValue的值直接赋给下一个maxValue,然后将本次的maxValue减1,这样的话每次接收的maxValue还是原来的初值,而不会执行return 1停止递归,而本次maxValue的内存并不会释放因为本次return没有执行到就去执行下一次getSum函数,这样无限循环会新建很多个maxValue直到栈内存溢出。也就是说这个递归的完成是新建了很多个maxValue来接收值,只有本次的getSum结束才会释放。



               
作者: 爱翚    时间: 2014-4-24 10:07
public class Demo8 {
    public static void main(String args[]){
        System.out.println(getSum(10)) ;
    }
    public static int getSum(int maxValue) {
        if (maxValue == 1)
            return 1;
        else {
            return maxValue + getSum(maxValue-1);  //如果maxValue为3,(maxValue-1)当前的结果是2
            return maxValue + getSum(maxValue--);  //如果maxValue为3,(maxValue--)当前的结果仍然是3,执行完这步后maxValue结果变为2
            return maxValue + getSum(--maxValue);  //如果maxValue为3,(--maxValue)当前的结果是3
        }
    }
}

所以这个问题修改应为将maxValue-1变为--maxValue
作者: pray    时间: 2014-4-26 00:23
呵呵我很开心~~~
作者: 二小傻    时间: 2014-4-26 08:04
这么回事




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2