一页天书不分说

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

题目:给一个正整数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;
             }
        }
    }
}

 

posted on 2015-09-25 12:46  一页天书不分说  阅读(2413)  评论(0编辑  收藏  举报