Java中的这个素数分解代码有什么问题?

时间:2016-08-16 14:36:45

标签: java math primes

我试图制定一种方法来对数字进行素数分解,它可能不是最有效的,但我不明白它为什么不能工作。

public static ArrayList<Integer> primeFactorize(int num) {
    ArrayList<Integer> primeFactors = new ArrayList<Integer>();

    for (int i = 2; i < Math.sqrt((double) num); i++) {
        if (isPrime(i) && factor(num).contains(i)) {
            primeFactors.add(i);
            num /= i;

            if (isPrime(num)) {
                primeFactors.add(num);
                break;
            }
            i = 2;
        }
    }
    return primeFactors;
}

它调用了我写的另外两个名为factor()isPrime()的方法,这些方法完全符合您的预期(返回ArrayList因子和true }或false取决于输入是否分别为素数。

我通过调试器,num为12,它在第一个循环中工作正常,在primeFactors中添加了2。但是,当它在num为6且i为2时再次到达数组顶部时,它会退出循环,就好像i < Math.sqrt((double) num)返回false一样。

但这没有意义,因为6的平方根有点超过2.我也试过(double) i < Math.sqrt((double) num),但它只是做了同样的事情。

任何人都能看到我失踪的东西吗?感谢您的回复。

编辑:这是我的代码,感谢您的帮助!我知道我可以确保它更有效率,所以我可能会在以后这样做,但现在这是完美的。

public static ArrayList<Integer> primeFactorize(int num) {
    ArrayList<Integer> primeFactors = new ArrayList<Integer>();

    int i = 2;
    while (i < Math.sqrt((double) num)) {
        if (isPrime(i) && num % i == 0) {
            primeFactors.add(i);
            num /= i;

            if (isPrime(num)) {
                primeFactors.add(num);
                break;
            }
            i = 2;
        }
        else
            i++;
    }
    return primeFactors;
}

2 个答案:

答案 0 :(得分:4)

for循环中,i++部分将在每个循环结束时被调用。所以在你的代码中,你将i设置为2.然后,循环结束,并将{1}增加1,使其为3.然后进行比较,3超过sqrt(6 ),所以循环退出。

如果希望i在下一次迭代中为2,则需要将其设置为一个值,以便在增量操作运行后将为2,而不是;在这种情况下,您应该将其设置为1.更好的解决方案是更改您的代码结构,因此它不是必需的。 As pointed out by biziclopi循环可让您决定是否增加,并避免此问题。

答案 1 :(得分:3)

既然您已经接受了答案,我认为您的问题已经解决了。我想要指出的是,如果有另一种方式,将整数转换为双精度通常是一个坏主意。因此,我想向您展示以下实现,它不使用浮点运算。另外我认为检查num是否为素数是一个坏主意,因为这会降低算法的速度。此外,如果num % i == 0的计算结果为true,则i始终为素数,因此isPrime(i)检查是多余的,也会降低算法速度。

List <Integer> primeFactors(int n) {
    List<Integer> factors = new ArrayList<>();
    for (int i = 2; i <= n / i; ++i) {
        while (n % i == 0) {
            factors.add(i);
            n /= i ;
        }
    }
    if (n > 1) {
        factors.add(n);
    }
    return factors ;
}