试图突破for循环但继续回到它并执行递归调用

时间:2014-03-07 23:13:33

标签: java break return

我刚刚发现了项目euler网站,我已经完成了挑战1和2并且刚刚在java中开始了number 3 ...这是我目前的代码:

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;
                }
            }
        }
    }

}

我没有使用他们要求我使用的大数字,我正在使用一些较小的数字测试我的代码,使用13195(他们的示例)我在这段代码中得到了29:

else if(isPrimeNumber(i) && num % i == 0) {
                    primeFactors.add(i);
                    findPrimeFactors(num / i);
                }
            }

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

它到达break语句然后最终检查然后返回语句。 我希望程序在返回语句后返回main方法,但它会跳到:

findPrimeFactors(num / i);

并试图完成迭代......我想我的理解是有缺陷的,有人可以向我解释为什么它的表现如此?我迫不及待想要完成它:)我会发现一个更有效的方法,我知道我可以让这个低效的工作。

2 个答案:

答案 0 :(得分:2)

您正在使用递归,这意味着函数将调用自身。

因此,如果我们在您致电return时跟踪您的函数调用的内容,我们会有类似的内容:

IntegerFactorise.main()
|-> IntegerFactorise.findPrimeFactors(2639)
    |-> IntegerFactorise.findPrimeFactors(377)
        |-> IntegerFactorise.findPrimeFactors(29) -> return true;

所以,当你在最后一个findPrimeFactors()中返回时,你只会从这个调用返回,而不是从所有的调用堆栈返回,并且之前的findPrimeFactors()的执行将在该点之后继续你打电话给findPrimeFactors()

如果你想从所有的电话堆中返回,你必须修改你的代码来做类似的事情:

        else if(isPrimeNumber(i) && num % i == 0) {
            primeFactors.add(i);
            return findPrimeFactors(num / i);
        }

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

答案 1 :(得分:0)

我认为问题在于您忽略了递归调用findPrimeFactors()的返回值。

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

if (findPrimeFactors(num / i))
    return true;

我假设如果递归调用返回false,则需要继续循环。如果你应该总是在返回时完成循环(无论是真还是假),那么试试这个:

return findPrimeFactors(num / i);