如何纠正我的素数分解计划?

时间:2015-03-30 18:21:02

标签: java primes

这是我输出给定数字的素数因子分解的程序。我仍然只是java的初学者,所以我知道它不是最有效的代码。当我输入相对较大的数字时会出现问题。

输入:11输出:11

输入:40输出:2 2 2 5

输入:5427输出:3 3 3 3 67

输入:435843输出:3 3 79 613

输入:23456789输出:无(似乎存在无限循环且代码应返回23456789,因为它本身是素数)

可能导致此问题的原因是什么?

import java.util.Scanner;

public class PrimeFactorization {
    public static boolean isPrime(long n) {
        boolean boo = false;
        long counter = 0;
        if (n == 1) {
            boo = false;
        } else if (n == 2) {
            boo = true;
        } else {
            for (long i = 2; i < n; i++) {
                if (n % i == 0) {
                    counter++;
                }
            }
            if (counter == 0) {
                boo = true;
            }
        }
        return boo;
    }

    public static void primeFactorization(long num) {
        for (long j = 1; j <= num; j++) {
            if (isPrime(j)) {
                if (num % j == 0) {
                    while (num % j == 0) {
                        System.out.printf(j + " ");
                        num = num / j;
                    }
                }
            }
            if (num == 1) {
                break;
            }
        }
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("Enter any number:");
        long num = scanner.nextLong();
        System.out.print("Prime factorization of your number is: ");
        primeFactorization(num);
        scanner.close();
    }
}

2 个答案:

答案 0 :(得分:3)

没有实际错误 - 您只是以非常低效的方式做事。基本上,在分割之前,您需要检查1和23456789之间的每个数字的素数。

进行此项检查绝对没有意义。当你从1到23456789工作时,每次你发现一个因素,你就知道它必须是素数,因为你已经将所有较小的因素分开了。因此,如果您执行以下所有操作,这仍然可以正常工作,并且更快。

  • 完全删除isPrime方法。
  • 删除第if (isPrime(j)) {行以及匹配的}
  • 更改循环,以便j从2开始,例如for(long j = 2 ; j <= num ; j++) {
  • 从循环结束处删除if (num == 1) { break; }。它完全没有用处。

答案 1 :(得分:-1)

无论代码的效率如何,分解大数字都需要一段时间 - 这么长时间可能会让人觉得计算机已经挂起了。鉴于您的代码,即使是适度的大数字也需要很长时间。

您可以采取的主要措施是提高代码的效率,以便注意对于数字的任何一对因子,其中一个不会超过数字的平方根。您可以使用此事实来限制循环,以减少O(n)到O(log n)的算法顺序。

long sqrt = Math.sqrt(number);

for (long i = 2; i < sqrt; i++) {
    ...

您还可以做很多其他事情,但这种变化会产生最大的影响。

如果number在循环期间更改了值(例如在第二个分解循环中),那么您是否需要重新计算结束值:

for (...)
    // if number changes
    sqrt = Math.sqrt(number);