Java中的Prime分解程序

kac*_*ous 2 java math primes

我正在研究用Java实现的素数分解程序.目标是找到最大的素数因子600851475143(项目欧拉问题3).我想我已经完成了大部分工作,但是我遇到了一些错误.此外,我的逻辑似乎已关闭,特别是我设置的方法,用于检查数字是否为素数.

public class PrimeFactor {

    public static void main(String[] args) {
        int count = 0;
        for (int i = 0; i < Math.sqrt(600851475143L); i++) {
            if (Prime(i) && i % Math.sqrt(600851475143L) == 0) {
                count = i;
                System.out.println(count);
            }
        }
    }

    public static boolean Prime(int n) {
        boolean isPrime = false;
        // A number is prime iff it is divisible by 1 and itself only
        if (n % n == 0 && n % 1 == 0) {
            isPrime = true;
        }
        return isPrime;
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑

public class PrimeFactor {

    public static void main(String[] args) {
        for (int i = 2; i <= 600851475143L; i++) {
            if (isPrime(i) == true) {
                System.out.println(i);
            }
        }
    }

    public static boolean isPrime(int number) {
        if (number == 1) return false;
        if (number == 2) return true;
        if (number % 2 == 0) return false;
        for (int i = 3; i <= number; i++) {
            if (number % i == 0) return false;
        }
        return true;
    }
}
Run Code Online (Sandbox Code Playgroud)

小智 22

为什么要这么复杂?你不需要isPrime()那样做任何事情.除以它的最小除数(素数)并从这个素数做循环.这是我的简单代码:

public class PrimeFactor {

    public static int largestPrimeFactor(long number) {
        int i;

        for (i = 2; i <= number; i++) {
            if (number % i == 0) {
                number /= i;
                i--;
            }
        }

        return i;
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        System.out.println(largestPrimeFactor(13195));
        System.out.println(largestPrimeFactor(600851475143L));
    }
}
Run Code Online (Sandbox Code Playgroud)


sov*_*ova 10

编辑:我希望这听起来不是一个令人难以置信的居高临下的答案.我只是想说明一下,从计算机的角度来看,你必须检查所有可能是X因子的数字,以确保它是最佳的.计算机只是通过查看就不知道它是复合的,所以你必须迭代

示例:X是素数吗?

对于X = 67的情况:

你怎么检查这个?

I divide it by 2... it has a remainder of 1 (this also tells us that 67 is an odd number)
I divide it by 3... it has a remainder of 1
I divide it by 4... it has a remainder of 3
I divide it by 5... it has a remainder of 2
I divide it by 6... it has a remainder of 1
Run Code Online (Sandbox Code Playgroud)

事实上,如果数字不是素数,你只会得到0的余数.

你是否必须检查每个小于X的数字以确保它是素数?不.不再了,多亏了数学(!)

让我们看一个较小的数字,比如16.

16不是素数.

为什么?因为

2*8 = 16
4*4 = 16
Run Code Online (Sandbox Code Playgroud)

因此,16可以均匀地除以1和它本身.(虽然"1"在技术上不是素数,但这是技术性的,我离题了)

所以我们将16除以1 ...当然这是有效的,这适用于每个数字

Divide 16 by 2... we get a remainder of 0  (8*2)
Divide 16 by 3... we get a remainder of 1  
Divide 16 by 4... we get a remainder of 0  (4*4)
Divide 16 by 5... we get a remainder of 1
Divide 16 by 6... we get a remainder of 4
Divide 16 by 7... we get a remainder of 2
Divide 16 by 8... we get a remainder of 0  (8*2)
Run Code Online (Sandbox Code Playgroud)

我们实际上只需要一个0的余数来告诉我们它是复合的(与"素数"相反的是"复合").

检查16是否可被2整除与检查它是否可被8整除是一回事,因为2和8乘以得到16.

我们只需要检查一部分频谱(从2到X的平方根),因为我们可以乘的最大数是sqrt(X),否则我们使用较小的数来得到多余的答案.

17素数?

17 % 2 = 1
17 % 3 = 2
17 % 4 = 1 <--| approximately the square root of 17 [4.123...]
17 % 5 = 2 <--|
17 % 6 = 5
17 % 7 = 3
Run Code Online (Sandbox Code Playgroud)

sqrt(X)之后的结果,类似17 % 7等等,是多余的,因为它们必须乘以小于sqrt(X)的东西才能得到X.

那是,

A*B = X.

如果A和B都大于sqrt(X)那么

A*B将产生一个大于X的数字.

因此,A或B中的一个必须小于sqrt(X),并且检查这两个值是多余的,因为您只需要知道其中一个是否均匀地划分X(偶数除法为您提供另一个值一个答案)

我希望有所帮助.

编辑:有更复杂的检查素数的方法,Java有一个内置的"这个数字可能是素数"或BigInteger类中的"这个数字肯定是复合的"方法,因为我最近通过另一个SO答案: