分解质因数(附数学原理)

分解质因数并记录各质因数出现次数:

   对于数 n =756,它的因数里有4、6、14、42等非质因数,而i = 2是这些因数的公质因数,这里有一个推论:

            若b是一串数的公因数,能被这一串数整除的肯定能被b整除,但不能被b整除的,肯定不能被以上数整除。

  当我们不断地对 n 除以2,最终 n =189,此时2不再是 n 的因数,根据推论,4、6、14、42等数也不再是 n 的因数。这一步就相当于剔除了 n 中所有包含2这个质因数的合数因数。(各位稍微思考也能推出)

  当 n 不再能被2整除时,我们让i++,把i=2变成i=3,i=3变成i=5……不断地重复上面的步骤,最终 n 会被分解成为一系列质因数。

  注意(只看绿色字体的部分也能推出)

         1.当 n 不能再被2整除时,根据推论可知, n 也不能被4、6、8等数整除,所以i=这些数的时候在程序中并不会被记录。其实主要原因是一个合数C,一定能写成由C之前的质数相乘的形式,因为:C是合数,所以C一定能分解成除1和C本身以外的数,且分解成的数肯定比C小,如果分解成的数还是合数,那么继续将这个合数分解,直到C的因数里全是由小于C的质数相乘构成的。由这一个思维过程以及开头给出的结论我们可以得到:合数之前肯定存在质数,且合数自身一定能分解成这些质数相乘的形式,所以在决定i的取值时,只要让i从最小的质数开始取值,一定会先于某个合数而取遍其前的所有质数。当 n 无法被这些质数整除时,n 也一定无法被由这些质数相乘构成的合数整除(甚至于这个推论都不需要限定于质数)。如:n 不能被p、q、m这三个数整除,那 n 肯定也不能被p*q*m这个数整除。所以当i=3时,所有的因数中含2这个质数的合数就都不是a的因数。当i=5时,同理可得:所有的因数中含3这个质数的合数……,当i=7……

或者换个角度,如果a是合数,那么a一定能分成一系列按大小排列的质数。下面则对此进行说明。

           2.取两相邻质数分别为x,y。若x与y之间存在合数,那么这些合数一定由x及x以前的这些质数组合相乘构成的。因为合数能分解,分解的因数如果还是合数那就继续分解,直到分解得到的因数全为质因数时才不可继续分,且这些质因数肯定在x及x以前的质因数中(x以后的质因数比这个合数大,所以这个合数不可能分解出x以后的质数)。当i = x + 1时,说明x和x以前的所有质数都不再是此时a的因数(如果是的话,n 会一直÷这个质数,直到这个质数不是 n 的因数),由此可得x与y之间所有合数都不是 n 的因数。所以i可以放心的取两个质数之间的合数而不用担心这些合数是否为 n 的因数。

          3.临界条件为i <= n 。根据推论,如果n / i后得到的 n 还是合数的话,那么 n 一定 ≥ i 这个质数自身的平方。因为能取到i,说明i以前的质数都不能被 n 整除,如果 n 仍是一个合数,那么他分解出的质因数一定 ≥ i,这时的 i 是对于 n 来说的最小的质因数(如果i 还是a的因数的话):

    ① 某次循环结束后, 此时 i 一定不是 n 的因数。i++,如果i^2 < n,说明n可能还能再分解(后面还有数未尝试),所以循环继续。

    ② 当 i 的平方等于 n 时,可以明确知道这时候 n 的因数就是且只有 i 。该轮循环结束以后,n = 1。

    ③ i++进入新一轮循环,此时若 i^2 > n ,n 此时一定为一个质数。且一定是 i 及 i 以后的某个质数 。因为,如果 n 是合数(至少是两个质数相乘,且不包含 1 和本身),那么n分解出来的质因数一定大于等于 i ,但这里条件为 i^2 > n ,说明 n 一定不是合数,又 n 一定不是2 与 i 之间的质数 , 所以 n 只能是i 以及 i 以后的某个质数。

        如果n是 i,本次循环结束即可。如果n是i 后面的某个质数,那么i就必须要能取到n。所以循环终止条件是 i <= n(n不可能是1,因为i ≥ 2的,在i <= n的条件下,如果n是1,都不会进入循环)。举例 n = 2× 3 × 11 = 42。i 取完 2 和 3 时,n更新为 11 ,此时 i 必须能取到 11 , 所以循环终止条件必须要有 i = n 的情况,所以为 i <= n。

C语言代码实现(文主目前在学习C语言,其他语言可按照思路自己写)

  #include <stdio.h>
  int main(){
    
    int n;
    scanf("%d",&n);
    
    int i;
    for( i=2;i<=n;i++){
        
        int cnt = 0;
        while(n%i==0){
             cnt++;
             n /= i;
        }
        if(cnt!=0){
             printf("%d : %d\n",i,cnt);
        }
    }
    return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值