简体   繁体   English

Java递归编译错误

[英]Java Recursion compilation error

I am a fresh student in computer science and currently we study Java recursion. 我是计算机科学的应届生,目前我们正在学习Java递归。 Unfortunately, the academy only explains the following regarding this topic: 不幸的是,该学院仅解释了有关该主题的以下内容:

  1. What recursion means. 递归意味着什么。
  2. There are 2 types of cases when using a recursive algorithm: base cases and recursive cases and their purpose. 使用递归算法时,有两种情况:基本情况和递归情况及其用途。
  3. An example of factorial and Fibonacci implementation using recursion. 使用递归的阶乘和斐波那契实现的示例。

Now I got the following exercise: 现在,我进行了以下练习:

Two integer numbers will be called "strangers" if their greatest common divisor (aka GTC) is ONLY 1". For example, the numbers 8 and 9 are "strangers" because their GTC is 1. However, 8 and 9 are not "strangers" because their GTC is 2. 如果两个最大整数的最大公约数(也称为GTC) 仅为 1,则将它们称为“陌生人”。例如,数字8和9因为它们的GTC为1而为“陌生人”。但是,8和9不是“陌生人” ”,因为他们的GTC为2。

Please implement a recursive method which receives an array of integers, and returns "true" if every pair numbers in this array are strangers, and "false" otherwise. 请实现一个递归方法,该方法接收一个整数数组,如果该数组中的每个对数都是陌生人,则返回“ true”,否则返回“ false”。

Method signature must be as follows: 方法签名必须如下:

 public boolean checkGCD(int[] values) 

For example: 例如:

{3, 5, 7, 11} -> method will returns true. {3,5,7,11}->方法将返回true。
{4, 7, 8, 9} -> method will returns false because 4 and 8 are not strangers. {4,7,8,9}->方法将返回false,因为4和8不是陌生人。

For assistance, you can use the following method for finding GTC (Euclidean algorithm): 为了获得帮助,您可以使用以下方法查找GTC(欧几里德算法):

 private static int gcd(int n, int m){ if (m==0) return n; return gcd(m,n % m); } 

In addition, the method checkGCD(int[] values) should be overloaded... 另外,方法checkGCD(int [] values)应该重载...

Loops cannot be used! 不能使用循环!

The above can be done very easily with a nested loop, but I must use recursion! 使用嵌套循环可以很容易地完成上述操作,但是我必须使用递归!

I understand that I need to use an overloaded method which gets the array , lo index and hi index . 我知道我需要使用重载方法来获取the arraylo indexhi index

So this is what I came up in mind: 所以这就是我想到的:

@@@@@@ @@@@@@

Base case: if there is at least one pair of numbers in the array which are not strangers, method returns false (no need to continue the comparison...). 基本情况:如果数组中至少有一对不陌生的数字,则方法返回false(无需继续比较...)。

@@@@@@ @@@@@@

Comparison will be done in the following way: lo index points to the 1st cell -> hi index points to the 2nd cell -> comparing -> hi index is incremented by 1 until it reaches the last cell of the array. 比较将通过以下方式进行:lo索引指向第一个单元格-> hi索引指向第二个单元格->比较-> hi索引递增1,直到到达数组的最后一个单元格。

Then, lo index is incremented by 1, and then repeating the above. 然后,将lo索引增加1,然后重复上述操作。

So bottom line, I should compare the first cell to all consecutive cells, compare the 2nd to all consecutive cells, the 3rd etc... 因此,最重要的是,我应该将第一个单元格与所有连续单元格进行比较,将第二个单元格与所有连续单元格进行比较,第三个等。

@@@@@@@@ @@@@@@@@

If all pairs of numbers are strangers, I need something else to stop recursion. 如果所有数字对都是陌生人,那么我需要别的东西来停止递归。 Therefore, if all pairs are strangers, it means that lo index and hi index will eventually point to the last cell (cause both lo and hi index has incremented gradually, and they reach the last array cell after all comparisons turned out to be OK ie strangers). 因此,如果所有对都是陌生人,则意味着lo索引和hi索引最终将指向最后一个单元格(因为lo和hi索引都逐渐增加,并且在所有比较都确定之后它们到达了最后一个数组单元格,即陌生人)。

The following is the overloaded function: 以下是重载函数:

   private static boolean checkGCD(int[] values, int lo, int hi)
    {

        if ( (gcd(values[lo], values[hi]) )!= 1 )
            return false;

        else if (lo < values.length-1 && hi < values.length-1)
                return checkGCD(values, lo, hi+1);
        else if (lo < values.length-2 && hi == values.length-1)
                return checkGCD (values, lo+1, lo+2);

        if (lo == values.length-1 && hi == values.length-1)
            return true;

         } -> Compiler says "missing return statement"**

The following is the method the exercise requires to have, and it basically just calls the overloaded method which does everything recursively. 以下是练习所需的方法,它基本上只是调用重载的方法,该方法以递归方式进行所有操作。

 public static boolean checkGCD(int[] values)
  {
      return checkGCD(values, 0, 1);      
  }

When I try to compile, I get "missing return statement" which points to the close bracket in the overloaded function 当我尝试编译时,出现“缺少返回语句”,该语句指向重载函数中的右括号

But I do use "return" in the overloaded function. 但是我确实在重载函数中使用了“返回”。

Please clarify how to fix. 请说明如何解决。 I am sure after compilation error, the above overloaded function is still not OK. 我确定编译错误后,上述重载函数仍然无法正常运行。

You get the compiler error because, if every if fails, the method does not return anything. 您会收到编译器错误,因为如果每个if失败,该方法将不会返回任何内容。 The solution is add the appropriate return statement when the final if fails. 解决方案是在最终if失败时添加适当的return语句。

Not to give the answer away, but here's a strong hint: the base case is an array with two elements. 并没有给出答案,但是有一个强烈的提示:基本案例是一个包含两个元素的数组。 All larger arrays are recursive cases. 所有较大的数组都是递归的情况。

There's a general pattern for going through a list with a recursion (pseudocode): 有一种使用递归(伪代码)遍历列表的一般模式:

 Result f(List f) {
      if(f is an empty list) {
          return Result for an empty list;
      } else {
          return (Result for head of list) merged with f(tail of list)
      }
 }

Since you're using arrays, rather than a type with convenient head() and tail() methods, you could pass in an index to say how much of the array you want to process. 由于您使用的是数组,而不是使用方便的head()tail()方法的类型,因此您可以传入索引来说明要处理的数组数量。 When index == array.length you are processing an "empty list". index == array.length您正在处理“空列表”。

 boolean allMembersPositive(int[] array, int index) {
     if(index == array.length) {
          return true;
     } else {
          return (array[index] >=0) && (allMembersPositive(index + 1));
     }
 }

It's a small step to adapt this to consume two array items per recursive call. 这是一小步,可以使其适应每个递归调用消耗两个数组项。

I can guarantee you that when you understand recursion clearly you are going to level up your programming skills. 我可以向您保证,当您清楚地了解递归时,您将提高编程技能。

I recommend reading these URLs: 我建议阅读以下URL:

http://howtoprogramwithjava.com/java-recursion/ http://howtoprogramwithjava.com/java-recursion/

http://danzig.jct.ac.il/java_class/recursion.html http://danzig.jct.ac.il/java_class/recursion.html

Now, lets move back to your questions. 现在,让我们回到您的问题。 I think that is one possible way to implement it: 我认为这是实现它的一种可能方法:

public class Test {

    public static void main(String[] arguments) {
    int[] strangers = { 3, 5, 7, 11 };
    int[] acquaintances = { 4, 7, 8, 9};

    boolean verifyStrangers = checkGCD(strangers);
    boolean verifyAcquaintances = checkGCD(acquaintances);

    System.out.println(verifyStrangers);
    System.out.println(verifyAcquaintances);

    }

    public static boolean checkGCD(int[] values) {
    return checkGCD(values, 0, 1);
    }

    /*
     * I'm really not sure why your professor wants this method signature: "checkGCD(int[] values, int i, int j)"
     * I'm coding what I understood from the problem.
     */
    private static boolean checkGCD(int[] values, int i, int j) {
    boolean result = true;
    if (gcd(values[i], values[j]) != 1){
        result = false;
    }
    j++;
    if (j < values.length ) {
        result = result && checkGCD(values, i, j);
    }
    return result;
    }


    private static int gcd(int n, int m) {
    if (m == 0)
        return n;
    return gcd(m, n % m);
    }

}

I managed to solve the exercise. 我设法解决了这个问题。

    public static int gcd(int n, int m)
    {
           if (m==0) 
            return n;

            return gcd(m,n % m);
    }


    private static boolean checkGCD(int[] values, int lo, int hi)
    {

  //      System.out.println("lo is " + lo + " hi is " + hi);
  //      System.out.println("");

  //      System.out.println("[lo] is " + values [lo] + " [hi] is " + values[hi]);
  //      System.out.println("");

        if ( (gcd(values[lo], values[hi]) )!= 1 )
            return false;

        if (lo < values.length-1 && hi < values.length-1)
                return checkGCD(values, lo, hi+1);

        if (lo < values.length-2 && hi == values.length-1)
            return checkGCD(values, lo+1, lo+2);

        if (lo == values.length-2 && hi == values.length-1)
          return true;  

          return true; 

    }


  public static boolean checkGCD(int[] values)
  {
      return checkGCD(values, 0, 1);      
  }

:-) :-)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM