正如标题所说,我应该编写一个程序,输出2-20,000之间的所有完全数。我写的程序在我看来是正确的,但是它只输出了"6"。即使它是在for循环中它应该给我剩下的数,对吧?我是一名计算机科学专业的新生,所以我还在努力学习这些知识。
public static void partC(System [] args){
int number = 2;
while(number <= 20000){
int factorNum = 1;
for(int sum = 0; number % factorNum == 0; factorNum++){
if(number % factorNum == 0){
sum += factorNum;
}
if(number == sum){
System.out.println(number);
}
}
++number
}
}
您没有正确计算除数。您需要设置sum to 1
,然后在factorNum < number
时从2
开始迭代。但是一个更好的方法是考虑如果a % b == 0
,那么b
和a/b
都是约数。所以你只需要检查测试号的factors <= to the square root
。它看起来像这样:
int sum = 1;
int limit = (int)Math.sqrt(number);
for (int factorNum = 2; factorNum <= limit; factorNum++) {
if (number % factorNum == 0) {
sum += (factorNum + number/factorNum);
}
}
但是即使上面的方法对于寻找更大的完全数也不是很有效。由于它们很快就会变大,这个循环非常耗时。更好的方法是使用BigInteger来允许任意大的数字,并利用它们的形式,如完美数中详细介绍的那样。以下是一个简短的解释。
如果pp-1'然后然后(2<一口>p - 1> p一口>1)是一个完美的数。下面的公式将找到所有的完全数,直到一个给定的最大值。你可以根据需要调整,但我选择的最大值是2150。下面唯一的特殊之处在于BigInteger
与它的素数测试一起使用。计算只是基本的数学运算。
int p = 2;
// BigInteger max = BigInteger.valueOf(22_000);
BigInteger max = BigInteger.TWO.pow(150);
BigInteger perfect = BigInteger.ZERO;
while(perfect.compareTo(max) < 0) {
if (BigInteger.valueOf(p).isProbablePrime(50)) {
BigInteger powerOfTwo = BigInteger.TWO.pow(p-1);
BigInteger mersenne = powerOfTwo.multiply(BigInteger.TWO).subtract(BigInteger.ONE);
if(mersenne.isProbablePrime(50)) {
perfect = powerOfTwo.multiply(mersenne);
System.out.println(perfect);
}
}
p += p > 2 ? 2 : 1;
}
打印
6
28
496
8128
33550336
8589869056
137438691328
2305843008139952128
2658455991569831744654692615953842176
191561942608236107294793378084303638130997321548169216
每次"number % factorNum == 0"不是真的。因此,当number为6时,它有效,因为factorNum的值为1,2,3,当factorNum为4时,它将退出代码。
我的解决方案:
public class partC {
public static void main(String[] args) {
int number = 2;
while (number <= 20000) {
int sum = 0;
for (int factorNum = 1; number > factorNum; factorNum++) {
if (number % factorNum == 0) {
sum += factorNum;
}
}
if (number == sum) {
System.out.println(number);
}
number++;
}
}
}
不需要检查sum是否等于for循环中的数字,只需计算for循环中factorNums的和,并检查sum是否等于for循环后的数字。
我的解决方案:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
for(int loopNumber = 1; loopNumber<20000; loopNumber++) {
int controlValue = 0;
for (int i = 1; i <= loopNumber; i++) {
if (loopNumber % i == 0) {
controlValue = (controlValue += i);
}
}
if (controlValue == loopNumber*2) {
System.out.println("This number is perfect number: "+loopNumber);
}
}
}
}