我应该找到在2到20,000之间的所有完美数。

huangapple go评论111阅读模式
英文:

I'm supposed to find all of the perfect numbers in between 2-20,000

问题

以下是您要翻译的代码部分:

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;
   }
}
英文:

As the title says, I'm supposed to write a program that outputs all the perfect numbers between 2-20,000. The program I have written looks correct to me, but it only outputs "6" even though it's in a for loop and it should be giving me the rest of the numbers, right? I'm a new computer science student, so I'm still trying to learn all this.

public static void partC(System [] args){
   int number = 2;
   
   while(number &lt;= 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
   }
}   

答案1

得分: 1

你的除数计算方式不正确。你需要将 sum 设置为1,然后从 2 开始迭代,直到 factorNum 小于 number。但更好的方法是考虑如果 a % b == 0,那么 ba/b 都是因子。所以你只需要检查测试数字的平方根以下的因子。代码如下:

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 允许处理任意大的数字,并利用它们的形式,如 完美数 中详细说明的那样。下面提供了简要的解释。

如果 p 是素数且 2p-1 也是素数,那么 (2p-1)(2p-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
英文:

You're not computing your divisors correctly. You need to set sum to 1 and then iterate starting at 2 while factorNum &lt; number. But a somewhat better method is to consider that if a % b == 0 then both b and a/b are divisors. So you only need to check factors &lt;= to the square root of the test number. It would look like the following:

int sum = 1;
int limit = (int)Math.sqrt(number);
for (int factorNum = 2; factorNum &lt;= limit; factorNum++) {        
     if (number % factorNum == 0) {
         sum += (factorNum + number/factorNum);
     }   
}

But even the above is not very efficient for finding larger perfect numbers. As they get large very quickly, the loop is very time consuming. A better way is to use BigInteger to allow for arbitrarily large numbers and to take advantage of their form as detailed in Perfect Number. An abbreviated explanation is provided below.

If p is prime and 2<sup>p</sup>-1 is prime then then (2<sup>p-1</sup>)(2<sup>p</sup>-1) is a perfect number. So the following will find all perfect numbers up to a given maximum. You can adjust it as required, but the max I have chosen is 2<sup>150</sup>. The only thing that is special about the following is that BigInteger is used along with its test for primality. The computations are just basic mathematical operations.

int p = 2;
// BigInteger max = BigInteger.valueOf(22_000);
BigInteger max = BigInteger.TWO.pow(150);
BigInteger perfect = BigInteger.ZERO;
while(perfect.compareTo(max) &lt; 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 &gt; 2 ? 2 : 1;
}

prints

6
28
496
8128
33550336
8589869056
137438691328
2305843008139952128
2658455991569831744654692615953842176
191561942608236107294793378084303638130997321548169216




</details>



# 答案2
**得分**: 0

Your code will exit from the for loop every time "number % factorNum == 0" is not true. So it works when the number is 6 because factorNum's are 1, 2, 3, and it will exit the code when factorNum is 4.

My solution:

```java
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++;
        }
    }
}

Instead of checking if the sum is equal to the number in the for loop, you can just calculate the sums of factorNums in the for loop and check if the sum is equal to that number after the for loop.

英文:

Your code will exit from for loop everytime "number % factorNum == 0" is not true. So it works when number is 6 because factorNum's are 1,2,3 and it will exit the code when factorNum is 4.

My solution:

public class partC {
	public static void main(String[] args) {
		int number = 2;

		while (number &lt;= 20000) {
			int sum = 0;
			for (int factorNum = 1; number &gt; factorNum; factorNum++) {
				
				if (number % factorNum == 0) {
					sum += factorNum;
				}
				
			}
			if (number == sum) {
					System.out.println(number);
            }
			number++;
		}
	}
}

Instead of checking if sum is equal to the number in for loop, you can just calculate the sums of factorNums in for loop and check if sum is equal to that number after the for loop.

答案3

得分: 0

我的解决方案

    import java.util.Scanner;
    
    public class Main {
        public static void main(String[] args) {
    
            for(int loopNumber = 1; loopNumber&lt;20000; loopNumber++) {
    
                int controlValue = 0;
    
                for (int i = 1; i &lt;= loopNumber; i++) {
                    if (loopNumber % i == 0) {
                        controlValue = (controlValue += i);
                    }
                }
    
                if (controlValue == loopNumber*2) {
                    System.out.println("这个数是完美数: "+loopNumber);
                }
            }
    
        }
    }
英文:

My solution:

import java.util.Scanner;

public class Main {
public static void main(String[] args) {

    for(int loopNumber = 1; loopNumber&lt;20000; loopNumber++) {

        int controlValue = 0;

        for (int i = 1; i &lt;= loopNumber; i++) {
            if (loopNumber % i == 0) {
                controlValue = (controlValue += i);
            }
        }

        if (controlValue == loopNumber*2) {
            System.out.println(&quot;This number is perfect number: &quot;+loopNumber);
        }
    }

  }
}

huangapple
  • 本文由 发表于 2023年4月7日 04:24:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/75953484.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定