关于Java中新手的递归

时间:2016-10-28 22:55:04

标签: java recursion return static-methods

所以,我有这个代码,这就是我解决了一个给我的练习的方式,它包括创建一个接收数字的递归函数,然后给你1的总和,所有的数字在之间和你的号码。我知道我让它听起来很混乱,但这是一个例子:

如果我插入数字5,那么返回的值必须是15,因为:1 + 2 + 3 + 4 + 5 = 15.

public class Exercise {

    public static void main(String[] args) {
        int returnedValue = addNumbers(6);
        System.out.print(returnedValue);
    }

    public static int addNumbers(int value) {
        if (value == 1) return value;
        return value = value + addNumbers(value-1);
    }

}

从技术上讲,我的代码工作正常,但我仍然不明白为什么Eclipse让我写了两个返回,这就是我想知道的。

有没有办法我只能写一次“返回”?

6 个答案:

答案 0 :(得分:5)

当然,你可以只用一次回复来写它:

public static int addNumbers(int value) {
   if (value > 1) {
      value += addNumbers(value - 1);
   }
   return value;
}

正如您所看到的,通过让一些变量保留运行结果直到您结束为止。在这种情况下,我能够在value中就地执行此操作,在其他情况下,您可能需要创建一个局部变量,但是将中间结果存储到某个地方直到到达返回点的想法是一般的之一。

答案 1 :(得分:1)

应该有两个回报。你的第一次回归说

day2

,第二个说

if at 1: stop recurstion

您可以使用三元组合它们:

continue recursion by returning my value plus computing the value less than me

但它不具有可读性。

这样的递归功能
  • Fibbonacci的序列
  • 分形

多次使用自己,因为他们包含

答案 2 :(得分:1)

递归函数总是至少有2个路径,正常的路径将递归,而#34; end"刚返回的路径(通常是常数)。

但是,您可以这样做:

public static int addNumbers(int value) {
    if (value != 1) 
        value = value + addNumbers(value-1);
    return value;
}

但是我不能说我觉得它好得多(有些人对修改参数感到恼火,就像他们在多次回报时一样)。当然,您可以创建一个新变量并将其设置为一个值或另一个值,但是有人会因为您使用过多行代码和不必要的变量而感到不安。欢迎编程:)您的原始代码可能与您可能获得的一样好。

至于为什么" Eclipse"这样做对你来说,它实际上是Java - Java比大多数语言更好,确保你没有尽快做出明显错误的事情(在这种情况下,当你打字而不是等你的时候编译)。它检测到你的一个分支返回了一个值而另一个分支没有 - 这显然是错误的。

Java也非常明确地强迫你使用" return"声明,另一种语言可能让你少走开。在Groovy中你很想消除回报并写下类似的东西:

def addNumbers(value){value + (value-1?0:addNumbers(value-1))}

只是为了好玩,但我当然不会称之为更具可读性! Java只是认为在大多数情况下强迫你明确是最好的。

答案 3 :(得分:1)

如果我错了,请随意纠正我,但我不认为除非您决定将变量置于方法之外或更改方法,否则有办法消除其中一个返回是递归的。

在java中,一个返回值的方法,必须在某个时刻返回一个值,无论它内部有什么代码。 eclipse要求你添加第二个返回的原因是因为只有当if语句的计算结果为true时才会运行第一个返回。如果你没有第二次返回,并且if语句没有结束,java将无法离开该方法,并且不知道该怎么做,因此,eclipse将要求你添加if语句之后的return语句。

这些类型的错误称为检查错误或编译时错误。这意味着eclipse字面上无法将您的代码转换为可运行的文件,因为它不知道如何;有语法错误,或者您错过了返回等等。

答案 4 :(得分:0)

来自维基百科的递归:

  

在数学和计算机科学中,一类对象或方法   当它们可以由两个属性定义时,它们表现出递归行为:

     
      
  1. 一个简单的基本案例(或案例) - 一个不使用递归来产生答案的终止案例

  2.   
  3. 一组规则,将所有其他案例减少到基本案例

  4.   

有两个退货,因为您必须处理上述两种情况。在您的示例中:

基本情况为value == 1

将所有其他案例减少到基本案例的案例是value + addNumbers(value-1);

来源:https://en.wikipedia.org/wiki/Recursion#Formal_definitions

当然还有其他方法来编写它,包括一些不需要多次返回的方法,但通常多次返回是表达递归的一种清晰而正常的方式,因为递归自然会落入多种情况。

答案 5 :(得分:0)

与Asimov的机器人一样,所有递归算法都必须遵守三个重要的法则:

  1. 递归算法必须具有基本情况。
  2. 递归算法必须改变其状态并向基本情况移动。
  3. 递归算法必须递归调用自身。
  4. 您的if (value == 1) return value;退货声明是基本情况。递归(调用自身)停止时的情况。当函数调用发生时,编译器将当前状态推送到堆栈然后进行调用。因此,当该调用返回一些值时,它从堆栈中提取值,进行计算并将结果返回到上一级。这就是其他退货声明的原因。

    想到这就像打破你的问题一样:

    addNumbers(3) = 3 + addNumbers(2) (this is returned by second one)
                          -> 2 + addNumbers(1) (this is returned by second one)
                                   -> 1 (this is returned by base case)