题目:给一个正整数N,分解质因数,按照从小到大输出。
例如:给了正整数100,就可以分解成下面的这样:
分解:2 2 5 5
解析:
先来想一个事情,按照从小到大输出,那么肯定是这种形态:
(若干个2) (若干个3) (若干个5) ... (...) 按照【质数】顺序,形成一个最终分解方式。
这里,若干个,也包括0个。
比如示例的100,
(2个2) (0个3) (2个5).
其实我们就是要找,有几个2,有几个3,有几个5,以此类推。
好,逻辑上就可以这么来想,给定一个正整数N:
第一步:看N能被2整除几次,2的个数就算出来了,如果不能被2整除,那么2的个数就是0个。
第二部:同理,看N(注意这里确实写的是N,而不是上一步除以2的结果)能被3整除几次,3的个数就算出来了,如果不能被3整除,那么3的个数就是0个。
以此类推。。
那么,这样做,有一个问题:
就是,你事先得有一个质数表,就像这样(2,3,5,7,11,。。。。。等等),如果你没有这个表,你就得这么搞:
第一步,计算2的个数;
第二步,找到比2大的一个质数,这里找到了3,计算3的个数;
第三步,找到比3大的一个质数,这里找到了5,计算5的个数;
,,以此类推。。。
这样搞,相当于,在程序里面,又加了一个冗余的功能,找下一个质数。这样就复杂了。
优化:
我随便给出一个分解结果:
[2 2] -> [3 3 3] -> [5 5] -> [7]
这种。
观察。
每个箭头后面的所有数的乘积有一个性质,肯定不含有前面的任意因子的倍数。
解释一下这句话,比如说[2 2]->这个箭头后面肯定不能分解出 【2 4 6 8 10等等】 这样的因子了。
[2 2] -> [3 3] -> 这个箭头,后面肯定不能分解出【2 4 6 8 10等等】和【3 6 9 12 15 等等】这样的因子了。
这样可以推出:每个箭头后面的所有数的乘积,的最小因子,肯定是质数。
解释一下这句话:
比如说[2 2]->这个箭头后面,最小因子是3,3就是个质数。
[2 2] -> [3 3 3] -> 这个箭头后面,最小因子是5,5也是个质数。
所以在写程序的时候:
第一步:从2开始,计算个数,保留整除的结果。
再去计算3,保留整除的结果。
再去计算4,因为上面说了,到了这一步,不可能被整除,所以可以不用判断4到底是不是质数。【加强解释:如果这一步会被4整除,那么,第一步(算2的那一步)的循环会结束么?不可能结束。】
再去计算5,保留整除的结果。
等等。。
等等。。
所以程序就很好写了:
void fun(int N) { int re = N; if(N == 1) { return; } for(int i = 2; i!=N;i++) { for(int j = 0; ;j++) { if(re%i == 0) { printf("%d ", i); re = re / i; } else { break; } } } }