Java 试图跳出for循环,但一直返回到它并执行递归调用

Java 试图跳出for循环,但一直返回到它并执行递归调用,java,break,return,Java,Break,Return,我刚刚发现了project euler网站,我已经完成了挑战1和挑战2,并且刚刚开始使用java。。。以下是我目前的代码: import java.util.ArrayList; public class IntegerFactorise { private static int value = 13195; private static ArrayList<Integer> primeFactors = new ArrayList<Integer>(

我刚刚发现了project euler网站,我已经完成了挑战1和挑战2,并且刚刚开始使用java。。。以下是我目前的代码:

import java.util.ArrayList;

public class IntegerFactorise {

    private static int value = 13195;
    private static ArrayList<Integer> primeFactors = new ArrayList<Integer>();
    private static int maxPrime = 0;

    /**
     * Check whether a give number is prime or not
     * return boolean
     */
    public static boolean isPrimeNumber(double num) {
        for(int i = 2; i < num; i++) {
            if(num % i == 0) {
                return false;
            }
        }

        return true;
    }

    /*Multiply all of the prime factors in the list of prime factors*/
    public static int multiplyPrimeFactors() {
        int ans = 1;
        for(Integer i : primeFactors) {
            ans *= i;
        }

        return ans;
    }

    /*Find the maximum prime number in the list of prime numbers*/
    public static void findMaxPrime() {
        int max = 0;
        for(Integer i : primeFactors) {
            if(i > max) {
                max = i;
            }
        }

        maxPrime = max;;
    }

    /**
     * Find all of the prime factors for a number given the first
     * prime factor
     */
    public static boolean findPrimeFactors(int num) {
        for(int i = 2; i <= num; i++) {
            if(isPrimeNumber(i) && num % i == 0 && i == num) {
                //could not possibly go further
                primeFactors.add(num);
                break;
            }
            else if(isPrimeNumber(i) && num % i == 0) {
                primeFactors.add(i);
                findPrimeFactors(num / i);
            }
        }

        int sumOfPrimes = multiplyPrimeFactors();
        if(sumOfPrimes == value) {
            return true;
        }
        else {
            return false;
        }   
    }

    /*start here*/
    public static void main(String[] args) {
        boolean found = false;
        for(int i = 2; i < value; i++) {
            if(isPrimeNumber(i) && value % i == 0) {
                primeFactors.add(i);
                found = findPrimeFactors(value / i);
                if(found == true) {
                    findMaxPrime();
                    System.out.println(maxPrime);
                    break;
                }
            }
        }
    }

}
它到达break语句,最后是check语句,然后是return语句。 我希望程序在返回语句后返回main方法,但它会跳到:

findPrimeFactors(num / i);

并试图完成迭代…我想我的理解在这里是有缺陷的,有人能解释一下为什么它会这样吗?我迫不及待地想完成它:)我会找到一个更有效的方法,在我知道我可以让这个低效的方法工作之后。

我想问题是你忽略了递归调用
findPrimeFactors()
的返回值

让我们来看看这个。我们首先调用
findPrimeFactors
,它发生在
main
中。然后我们进入for循环,因为它是该方法中的第一件事。现在让我们假设在某个时刻我们进入else语句,从而递归调用
frindPrimeFactors(num/i)
。这将暂停循环,但当这个递归调用开始运行时,您将再次进入for循环(请记住,上一个循环只是暂停了,尚未完成循环)。这一次,您遇到了中断,这允许这个递归调用结束,返回true或false。当这种情况发生时,您现在回到原始循环。此时,即使递归调用返回true,原始循环仍将继续。因此,您可以尝试以下方法:

if (findPrimeFactors(num / i))
    return true;
我假设如果递归调用返回false,您需要继续循环。如果您应该始终在返回时完成循环(无论是真是假),请尝试以下方法:

return findPrimeFactors(num / i);

您使用的是递归,这意味着函数将调用自身

因此,如果我们在调用
return
时跟踪函数调用的内容,我们将得到如下结果:

IntegerFactorise.main()
|-> IntegerFactorise.findPrimeFactors(2639)
    |-> IntegerFactorise.findPrimeFactors(377)
        |-> IntegerFactorise.findPrimeFactors(29) -> return true;
        else if(isPrimeNumber(i) && num % i == 0) {
            primeFactors.add(i);
            return findPrimeFactors(num / i);
        }
因此,当您在最后一个
findPrimeFactors()
中返回时,您将只从该调用返回,而不是从所有调用堆栈返回,并且上一个
findPrimeFactors()
的执行将在调用
findPrimeFactors()
之后继续

如果要从所有调用堆栈返回,则必须修改代码以执行以下操作:

IntegerFactorise.main()
|-> IntegerFactorise.findPrimeFactors(2639)
    |-> IntegerFactorise.findPrimeFactors(377)
        |-> IntegerFactorise.findPrimeFactors(29) -> return true;
        else if(isPrimeNumber(i) && num % i == 0) {
            primeFactors.add(i);
            return findPrimeFactors(num / i);
        }

这样,当最后一个
findPrimeFactors()
返回时,调用它的所有先前的
findPrimeFactors()
也将返回。

@boristesspider在返回true之后,它不会返回到公共静态void main方法…它会返回到循环中,我原以为break会退出循环而不会返回。您的代码有点复杂-我终于解决了这个问题。我要注意的是,
if(x==true)
是一个可怕的反模式,
if(x)
是正确的语法。与您的
返回类似
-只需直接返回布尔值。@BoristeSpider优点:)谢谢,与我的返回类似是什么意思?@user2405469其中代码导致问题:
如果(isPrimeNumber(i)和&num%i==0){primeFactors.add(i);findPrimeFactors(num/i)尝试添加
返回
如下:
否则如果(isPrimeEnumber(i)和&num%i==0){primeFactors.add(i);返回findPrimeFactors(num/i)
@user2405469这里最重要的是要理解问题是由错误使用的递归引起的。这不是语言依赖性的。每种基于C的语言(如Java)有一个叫做
调用堆栈
的东西。为了理解你为什么会遇到这个问题,我认为最好的开始是理解
调用堆栈
,它是如何工作的等等…@FlorenBayle谢谢你的解释,我现在很清楚了。