黑马程序员技术交流社区

标题: 自己帮别人解答问题结果最后自己迷惑了 [打印本页]

作者: 邵阳    时间: 2012-6-25 11:37
标题: 自己帮别人解答问题结果最后自己迷惑了
本帖最后由 邵阳 于 2012-6-25 16:07 编辑

在论坛上看到一个问题如下然后测试,准备自己解答谁知道自己迷惑了.
public class Test {
    public static void main(String[] args) {
        System.out.println(fnn(40));
   
        //int a1 = 1;
        //int a2 = 2;
        //int a3 = 3;
        //int a4 = 4;
        //System.out.println(a4 + a3 + a2 + a1);
    public static int fnn(int n){
        if(n == 1 || n == 2) {
            return 1;
        }else {
            return fnn(n - 1) + fnn(n);
        }
    }
    }
__________________________________________________________________________________________
主要有两个问题:
1:class Demo
{
    public static void main(String[] args)
{
        System.out.println(fnn(40));
     }   
    public static int fnn(int n)
{
        if(n == 1|| n == 2)
  {
            return 1;
        }
    else
  {
            return fnn (n - 1) + n;
        }
    }
   }        
然后输出是:  818     不知道怎么的出来的
2:class Demo
{
    public static void main(String[] args)
{
        System.out.println(fnn(40));
   
}   
    public static int fnn(int n)
{
        if(n == 40|| n == 2)
  {
            return 1;
        }
      /*else
  {
            return fnn (n - 1) + n;
        }*/   
  }
   }   
结果是D:\java\zuoye\ceshi>javac  d.java
d.java:20: 错误: 缺少返回语句
    }
    ^
1 个错误
    这是为啥啊?,  如果加上
else
  {
            return fnn (n - 1) + n;
        }
则可以得出正确结果 :1,又是为啥啊?  

作者: 游洪波    时间: 2012-6-25 12:01
本帖最后由 游洪波 于 2012-6-25 12:02 编辑

这道题的主要功能是算1+...+40的和。你自己算下1..40的结果你就知道了/、
还有return语句如果写在if语句中的话你想想如果条件为真他会返回值,那么如果条件为假的话方法还有返回值吗?所以编译器在编译的过程中是不允许这种情况出现的,所以你刚才的代码在if中写return 而把else的语句注释掉。编译器就会报一个缺少返回值的错误。
............................................
版主求分
作者: 王明明    时间: 2012-6-25 12:02
本帖最后由 王明明 于 2012-6-25 12:11 编辑
  1. 1:class Demo
  2. {
  3.     public static void main(String[] args)
  4. {
  5.         System.out.println(fnn(40));
  6.      }   
  7.     public static int fnn(int n)
  8. {
  9.         if(n == 1|| n == 2)
  10.   {
  11.             return 1;
  12.         }
  13.     else
  14.   {
  15.             return fnn (n - 1) + n;//这里fnn(n-1) 这里一直循环 就等于fnn(39)+fnn(38)...fnn(2)+40 //当n=2的时候返回的是1
  16.         }
  17.     }
  18.    }      



复制代码
class Demo
{
    public static void main(String[] args)
{
        System.out.println(fnn(40));
   
}   
    public static int fnn(int n)
{
        if(n == 40||n == 2)
  {
            return 1; //因为假如n!=40或者2 就会有异常产生 就会有没有返回语句的情况 所以系统会提示你 缺少返回语句
  }
  return 2;
  }
}   

作者: 李伟    时间: 2012-6-25 12:16
主要有两个问题:
1:class Demo
{
    public static void main(String[] args)
{
        System.out.println(fnn(40));
     }   
    public static int fnn(int n)
{
        if(n == 1|| n == 2)
  {
            return 1;
        }
    else
  {
            return fnn (n - 1) + n;
        }
    }
   }        
然后输出是:  818     不知道怎么的出来的//这个递归程序算的是1加到n的总和再减去2,1+...40=820,再减去2就是818了
2:class Demo
{
    public static void main(String[] args)
{
        System.out.println(fnn(40));
   
}   
    public static int fnn(int n)
{
        if(n == 40|| n == 2)
  {
            return 1;
        }
      /*else
  {
            return fnn (n - 1) + n;
        }*/   
  }
   }   
结果是D:\java\zuoye\ceshi>javac  d.java
d.java:20: 错误: 缺少返回语句//因为这段程序没有考虑到n=1的时候应该返回的值
    }
    ^
1 个错误    这是为啥啊?,  如果加上
else
  {
            return fnn (n - 1) + n;
        }
则可以得出正确结果 :1,又是为啥啊?  

作者: 邵阳    时间: 2012-6-25 12:28
王明明 发表于 2012-6-25 12:02
class Demo
{
    public static void main(String[] args)

但是有  if(条件表达式)
      { 执行语句啊}


这个也是if的一种格式,满足执行,不满足无反应啊,所以你的解答牵强
作者: 邵阳    时间: 2012-6-25 12:29
王明明 发表于 2012-6-25 12:02
class Demo
{
    public static void main(String[] args)

结果不是1 ,是818
作者: 邵阳    时间: 2012-6-25 12:30
游洪波 发表于 2012-6-25 12:01
这道题的主要功能是算1+...+40的和。你自己算下1..40的结果你就知道了/、
还有return语句如果写在if语句中 ...

你都解释不清楚,我都没看懂,你能不能运算过程解释清楚啊,还是糊弄我啊加分
作者: 邵阳    时间: 2012-6-25 12:34
李伟 发表于 2012-6-25 12:16
主要有两个问题:
1:class Demo
{

对于第一个解答为啥是想相加再减2 啊,怎么不减3 啊

对于第二个回答就说的更不是重点啦
作者: 陈淑飞    时间: 2012-6-25 12:36
本帖最后由 陈淑飞 于 2012-6-25 12:44 编辑


一、我表示怀疑,你在哪看到了这样的函数,这显示是个死递归循环,程序将一直运行出来不结果的。
因为这个在数字公式中是 f(n)=f(n)+f(n-1),这样给n传个40,会有结果吗?

二、该函数是 f(n)=f(n-1)+n 的公式,函数是个递归调用的。当n=1或2是,结果是1.
     表达的意义,也是是求n的1到n的和。楼主试着想想,不用计算机干活,你算 n的1到n的求和,是不是也是先算到n-1的 1到n-1的和,最后再与n相加即可。
   那么,当n取值是3是,是不是f(3)=f(2)+3=f(1)+2+3=6。
   基于此,我认为你的循环条件语句  if(n == 1|| n == 2)   应该改成 if(1==n),才是正确的。

三、这个肯定在javac编辑器,就不会通过。javac是有严格语法规定的,你在fnn(int n)方法申明中,明确告诉编辑器,是要求返回int类型的值。
  但是,你在函数体中,当if条例不满足时,编辑器读到函数结尾},你也没有给编辑器说返回了什么类型的值。
  当然,编辑器会在} 位置处,报个缺少返回语句的错误了。


作者: 游洪波    时间: 2012-6-25 12:40
邵阳 发表于 2012-6-25 12:30
你都解释不清楚,我都没看懂,你能不能运算过程解释清楚啊,还是糊弄我啊加分 ...

我把你那个程序拆开让你看看
public int funny(4)//我代个比较小的数给你解释一下
if(n==4 || n==2){//这个是加一个条件限制用于推出递归的
return 1;
}else{
return funny(n-1)+n;
}
咱们这样来看刚开始我带入了4  ,4!=40 上边那个条件不成立执行else中的
把4-1带入这个方法 同时将结果+4 ,这样带入的值现在成了3  ,3!=40 上边那个条件不成立执行else中的
把3-1带入这个方法 同时将结果+3,这样带入的值现在成了2 ,2==2上边那个条件成立执行if中的语句 返回一个1,那么这样下来就清楚多了  结果是不是就等于1+3+4了呢?
作者: 邵阳    时间: 2012-6-25 12:47
陈淑飞 发表于 2012-6-25 12:36
一、我表示怀疑,你在哪看到了这样的函数,这显示是个死递归循环,程序将一直运行出来不结果的。
因为这个 ...

return int 1 不行吗
作者: 陈淑飞    时间: 2012-6-25 13:20

,如这个流程图。
f(40)=f(39)+f(40)=f(37)+f(38)+f(40)(注意f(40)还未递归完成)=.....第一个数f(39)递归读到f(4)之后的流程如上。

你认为,第一个数f(39)会有值得出来吗?f(3)就够它玩的了。
作者: 李伟    时间: 2012-6-25 13:30
邵阳 发表于 2012-6-25 12:34
对于第一个解答为啥是想相加再减2 啊,怎么不减3 啊

对于第二个回答就说的更不是重点啦 ...

第一个比如求fnn(3);结果就是fnn(2)+3=1+3=4,求fnn(4)=fnn(3)+4=fnn(2)+3+4=1+3+4,依此类推,前面始终少了一个2,所以是1+...n的总和再减去2.
第二个我觉得主要是没考虑到n是其它值的时候该返回的值,只要在if语句外面再加一个return语句就可以了
作者: 邵阳    时间: 2012-6-25 13:37
陈淑飞 发表于 2012-6-25 13:20
,如这个流程图。
f(40)=f(39)+f(40)=f(37)+f(38)+f(40)(注意f(40)还未递归完成)=.....第一个数f(39)递归 ...

关于我问的第二个问题,如何进行修改啊。就是那个变异不同过的问题,不加else怎么修改
作者: 陈淑飞    时间: 2012-6-25 14:02
   /*else
  {
            return fnn (n - 1) + n;
        }*/   
不要整体 /* */注释掉。
只要改成用 //注释即可。

//else
  //{
            return fnn (n - 1) + n;
     //   }   

作者: 王明明    时间: 2012-6-25 14:15
本帖最后由 王明明 于 2012-6-25 14:40 编辑
邵阳 发表于 2012-6-25 12:28
但是有  if(条件表达式)
      { 执行语句啊}


假如if 不成立呢??
那怎么执行??
void 是不是没返回语句???
所以在下面加了一个return
你都没认真看俺的代码...
作者: 王明明    时间: 2012-6-25 14:20
邵阳 发表于 2012-6-25 12:29
结果不是1 ,是818

这里fnn(n-1) 这里一直循环 就等于fnn(39)+fnn(38)...fnn(2)+40 //当n=2的时候返回的是1
我不知道你仔细看这个没有
你传入的N=40??
那么fnn(n-1)是不是等于又传了一个39?然后38?
然后就这样了

fnn(39)+fnn(38).......fnn(2)+40  从39到2 一直加

但是当fnn(2)的时候返回的其实 是1 所以就等40+39+38...4+3+1=818




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