首页 > 代码库 > 质因数分解

质因数分解

 

如何分析问题、解决问题?

 

一个质因数分解的小问题。

如果给定一个数,如果是质数,则除了1和它本身,就没有其他乘积因子了;如果是合数,则一定能变成若干个质数相乘的形式。因此质因数分解就是把一个数分解成很多个质数因子的过程。

刚碰到这个问题的时候的想法是:给一个数,然后用质数去除它。但是问题又来了,怎么知道一个数是否为质数呢?或者说如何自动生成一个质数来作除数呢?总不可能先给一个自己写一个数组然后自己敲一些质数进去,每次要除的时候再一个一个检查过去吧?而且不可能把所有的质数都敲进去。这显然不是一个好方法。

前段时间做ACM,有道题有部分是关于判断一个数是否为质数的。

public static boolean isPrime(int num) {
        int temp;
        for (int i = 2; i < num; i++) {
            temp = num % i;
            if (temp == 0)
                return false;
        }

        return true;
    }

 

由此联想,先判断一个数是否为素数,然后再拿这个数来作除数怎么样?这样至少解决了自动生成质数的问题。

但是,如果一个数可以分解成很多个因子,如420可以分解成 2 2 3 5 7 ,如果每次分解都要先一大堆运算来生成质数,然后再来做除法,显然是一个复杂度很大的算法。因此这又不是一个好方法。

 

其实我们的思路有时候被问题本身的表达形式给限制住了,因此很多时候无法做到思维发散。

就像这个问题,质因数分解,要用一个个质数去除,首先要有质数。一定要这样吗?

 

质数的定义是什么?则除了1和它本身,就没有其他乘积因子了。

那我们可以从另一个角度来找解决方案:

package temp;

import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        Scanner inNum = new Scanner(System.in);
        int num = inNum.nextInt();
        int y = 2;
        while (num != 1) {
            if (num % y == 0) {
                num = num / y;
                System.out.print(y + "\t");
            } else {
                y++;
            }
        }
    }
}

从中可以看到,并不需要特意去找一个质数,而是从2开始除就好了,设被除数(任意给定的数)为num,当num被除得没有2的因子之后,再将除数+1,即y++,继续做除法。不用担心结果中会出现4、6、15、24……这些情况,因为,这些本身就是合数,举例来说,假设num能被6 = 2*3 整除,说明num可以被2或3整除,而做num = num/y的前提是y=6,即y>2且y>3,也即num已经被除得没有2和3的因子了。

因此这个算法是从小到大一步步找出所有质因数,而不是先列出质数然后一个个去除。从某中角度上来说像是跳过了中间多余的环节。

跳过中间多余环节,就像《浪潮之巅》中所写的,戴尔/阿里巴巴都做到了省去了一大部分中间流通环节,因此使成本大大降低,并直接或间接地从中获益。

 

(现在一想,其实一开始学因数分解的时候也是用的这种方法,如果是偶数先用2开始除,然后……

 

 

 

写到这儿,主要不是说找到了一个很好的解决分解质因数的方法,

 

而是从不同的角度切入问题,试着找到更好的解决方案。