我刚刚发现了项目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);
并试图完成迭代......我想我的理解是有缺陷的,有人可以向我解释为什么它的表现如此?我迫不及待想要完成它:)我会发现一个更有效的方法,我知道我可以让这个低效的工作。
答案 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);