分解质因数

求质因数的数学公式

分解质因数

每个合数都可以写成几个质数相乘的形式,其中每个质数都是这个合数的因数,把一个合数写成质因数相乘的形式,叫做分解质因数。如30=2×3×5 。分解质因数只针对合数(即除1和它本身外,还有因数的数)。[0]分解质因数的用途极其广泛,通过分解质因数可以看出这个合数可以被哪些数整除,合数与合数之间公因数和公倍数的关系等。[1]把一个合数分解成若干个质因数的乘积的形式,即求质因数的过程叫做分解质因数。

每个合数都可以写成几个质数相乘的形式,其中每个质数都是这个合数的因数,把一个合数写成质因数相乘的形式,叫做分解质因数。如30=2×3×5 。分解质因数只针对合数(即除1和它本身外,还有因数的数)。[1]分解质因数的用途极其广泛,通过分解质因数可以看出这个合数可以被哪些数整除,合数与合数之间公因数公倍数的关系等。[2]

定义

把一个合数分解成若干个质因数的乘积的形式,即求质因数的过程叫做分解质因数。

分解质因数只针对合数。(分解质因数也称分解素因数)求一个数分解质因数,要从最小的质数除起,一直除到结果为质数为止。分解质因数的算式叫短除法,和除法的性质相似,还可以用来求多个数的公因式。

定理

不存在最大质数的证明:(使用反证法

假设存在最大的质数为N,则所有的质数序列为:

设,

可以证明不能被任何质数整除,得出也是一个质数。

而,与假设矛盾,故可证明不存在最大的质数

第二种因数分解的方法:

1975年,John M. Pollard提出。该算法时间复杂度为。详见参考资料。

C#

123456789101112131415161718192021static void Main(string[] args){    Practice3();}private static void Practice3(){    List<int> a = new List<int>();        //用于存放质因数    Console.WriteLine("请输入一个整数:");    int n = Convert.ToInt32(Console.ReadLine());    int o = n;                            //用于存放输入的整数    for (int x = 2; x <= n; x++)    {        if (n % x == 0)        {            n /= x;            a.Add(x);            x--;                           //为了防止该整数有多个相同质因数最终只能输出一个的情况        }    }    Console.WriteLine("{0}={1}", o, string.Join("*", a.ToArray()));}

另一种实现

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748#include <stdio.h>Integer m,b,c := 0,j := 0;Integer a; //存放质因数Integer fjzys(Integer k)beginInteger i := 2;while (k> := i) do //判断k是否合格beginif (k mod i=0) then //判断k是否整除当前因数begina[j] := i; //存入因数k/ := i; //余数i := 2; //令i重新等于2j++; //计数值endelsebegini++; //不能整除则当前因数为非质因数end;end;(* C2PAS: Exit *) Result := 0;end;(* 用for实现上面的函数int fjzys(int k){int i=2;for ( ; i<=k ; i++ ) //当因数i<=k时,实现该循环,每次循环因数i自加1for ( ; k%i==0 ; j++ ) //当k整除当前因数,实现该循环,每次循环下标j自加1{k/=i; //使k=k/ia[j]=i; //存入因数}return 0;}解决上面的函数,无法输出,多个相同的质因数,如90=2*3*3*5,只能输出一个3.*)void main()beginprintf('请输入一个整数'#10'k=');scanf('%d', (* C2PAS: RefOrBit? *)&m);fjzys(m);for(b := 0;b<(j-1);b++) //*比质因数少一个beginprintf('%d',a[b]);printf('*');end;printf('%d'#10'',a[j-1]); //输出最后一个质因数end;

pascal

1234567891011121314151617181920212223242526272829//Pascal实现方法于2018.1.28更改,此前版本亲测错误//Pascal实现方法于2018.4.7再次更改,将可处理数字的范围扩大了{注意,此程序在处理过大的数字时速度不佳,在各大OJ上估计都会TLE几个测试数据}Var   n : Int64 ;  i : Longint ;Begin  readln( n ) ;  if n<>1     then write( n , '=' )    else write( n , '=1' );  i := 2 ;  while n<>1 do     Begin      if ( n mod i )=0         then Begin               n := n div i ;               write( i );               if n<>1                 then write( '*' );               i := 2 ;             End        else inc( i ) ;    End;  writeln;End.//By Cubeneo(和之前的Rh。是同一个人)

Java

12345678910111213141516171819202122232425262728293031import java.util.Scanner; public class H6 {    public static void main(String[] args) {        System.out.println("输入所求正整数:");        Scanner sc = new Scanner(System.in);        Long n = sc.nextLong();        long m=n;        int flag = 0;        String[] str = new String;        for (long i = 2; i <= n; i++) {            if (n % i == 0) {                str[flag] = Long.toString(i);                flag++;                n = n / i;                i--;            }        }        if (flag < 2)            System.out.println(m + "为质数");        else {            System.out.print(m + "=" + str);            for (int k = 1; k < flag; k++) {                System.out.print("*" + str[k]);            }            System.out.println("\n"+m+"共有"+flag+"个质因数.");        }        sc.close();    }}此方法最多可分解包含50个质数的合数.  @author寒鸦LMC

Visual Basic

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748Dimx,a,b,kAsString PrivateSubCommand1_Click()a=Val(Text1.Text)x=2Ifa<=1Ora>Int(a)ThenIfa=1ThenText2.Text="它既不是质数,也不是合数"ElseMsgBox"请您先输入数据",vbOKOnly+vbInformation,"友情提示"EndIfElseDoWhilea/2=Int(a/2)Anda>=4Ifb=0ThenText2.Text=Text2.Text&"2"b=1ElseText2.Text=Text2.Text&"*2"EndIfa=a/2k=aLoopDoWhilea>1Forx=3ToSqr(a)Step2DoWhilea/x=Int(a/x)Anda>=x*xIfb=0ThenText2.Text=Text2.Text&xb=1ElseText2.Text=Text2.Text&"*"&xEndIfa=a/xLoopNextk=aa=1LoopIfb=1ThenText2.Text=Text2.Text&"*"&kvElseText2.Text="这是一个质数"EndIfEndIfEndSubPrivateSubCommand2_Click()Text1.Text=""Text2.Text=""EndSub

c语言

实现一

此代码因为用了long long int,为C99标准,故不可在VC6.0上运行。

12345678910111213141516171819202122232425262728#include <stdio.h>#include <math.h> int main(){    int i, b;    long long int in;    /*采用64位整型,以便输入更大的数*/    freopen("F://1.txt", "r", stdin);    freopen("F://2.txt", "w", stdout);    while (scanf("%lld", &in) != EOF)    {        /*在F://1.txt中输入x个数N(N>=2)以换行符或空格符隔开,当没有输入时循环会自动结束*/        b = 0;/*用于标记是否是第一个质因数,第一个质因数在输出时前面不需要加空格*/        for (i = 2; in != 1; i++)        {            if (in%i == 0)            {                in /= i;                b ? printf("%d", i) : printf("%d", i), b = 1;                i--;                /*i--和i++使得i的值不变,即能把N含有的所有的当前质因数除尽,例如:24会一直把2除尽再去除3*/            }            printf("\n");        }    }    return 0;}

实现二

可直接在VC6.0运行。

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950#include <stdio.h>int m, b, c = 0, j = 0;int a;    //存放质因数int fjzys(int k){    int i = 2;    while (k >= i)    //判断k是否合格           {        if (k%i == 0)    //判断k是否整除当前因数        {            a[j] = i;    //存入因数            k /= i;    //余数            i = 2;    //令i重新等于2            j++;    //计数值        }        else        {            i++;    //不能整除则当前因数为非质因数        }    }    return 0;}/* 用for实现上面的函数int fjzys(int k){    int i=2;    for ( ; i<=k ; i++ )    //当因数i<=k时,实现该循环,每次循环因数i自加1        for ( ; k%i==0 ; j++ )   //当k整除当前因数,实现该循环,每次循环下标j自加1        {            k/=i;   //使k=k/i            a[j]=i;   //存入因数        }    return 0;}解决上面的函数,无法输出,多个相同的质因数,如90=2*3*3*5,只能输出一个3.*/ int main(){    printf("请输入一个整数\nk=");    scanf("%d", &m);    fjzys(m);    for (b = 0; b < (j - 1); b++)    //*比质因数少一个    {        printf("%d", a[b]);        printf("*");    }    printf("%d\n", a[j - 1]);    //输出最后一个质因数    return 0;}

C++

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667#include <iostream>using namespace std;int main(){    int n,n2;    cout<<"请输入需要分解的质因数:"    cin>>n;    cout<<n<<"=";//输出等于号    n2=n;    if(n<2){    return 0;//n小于2返回自身    }    cout<<"1*"; //输出 1*    for(int i=2;i*i<=n2;i++)//for循环穷举质因数          {        while(n2%i==0)//while循环判断质因数        {            n2=n2/i;//获得质因数            cout<<i;//返回质因数            if (n2!=1)//判断质因数            cout<<"*";//输出乘号        }    }    if(n2!=1){//判断质因数    cout<<n2;//输出质因数    }    return 0;//返回}//法2:#include <bits/stdc++.h>using namespace std;int main(){ int n; cin>>n; int m=n; int flag=0; cout<<m<<"="; for(int i=2;i*i<=n;i++) {  if(n%i==0)  {   int cnt=0;   while(n%i==0)   {    n=n/i;    cnt++;   }   if(flag==1) printf("*");    if(cnt==1)   {    printf("%d",i);   }    else   {    printf("%d^%d",i,cnt);   }   flag=1;  }  }     if(n>1) {   if(flag==1)printf("*");   printf("%d",n);    } return 0;}

Common Lisp

(defun is-prime-number (number)

(let ((num number))

(do ((index 2 (1+ index)))

((>= index num) t)

(if (= 0 (mod num index))

(return-from is-prime-number nil)))))

(defun decomposition-quality-factor (number)

(let ((num number) (prime-list (make-array 10 :fill-pointer 0 :adjustable t)))

(if (is-prime-number num)

(progn

(format t "~a~%" num)

(return-from decomposition-quality-factor nil)))

(do ((index 2 (1+ index)))

((>= index num) nil)

(if (is-prime-number index)

(push index prime-list)))

(dolist (value prime-list)

(let ((test-flag nil))

(do ()

(test-flag nil)

(if (= 0 (mod num value))

(progn

(format t "~a~%" value)

(setf num (/ num value))

(if (is-prime-number num)

(progn

(format t "~a~%" num)

(return-from decomposition-quality-factor nil))))

(setf test-flag t)))))))

Python 2.x

12345678910111213#!/usr/bin/python# -*- coding:utf-8 -*- num = int(raw_input("请输入要分解的正整数:")) temp = []while num!=1:    for i in range(2,num+1):        if num%i == 0:            temp.append(i)            num /= i            breakprint temp

Python 3.x

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192#MillerRabin素数判定,结合Pollard_rho递归分解,效率极高 import randomfrom collections import Counter def gcd(a, b):    if a == 0:        return b    if a < 0:        return gcd(-a, b)    while b > 0:        c = a % b        a, b = b, c    return a        def mod_mul(a, b, n):    result = 0    while b > 0:        if (b & 1) > 0:            result = (result + a) % n        a = (a + a) % n        b = (b >> 1)    return result     def mod_exp(a, b, n):    result = 1    while b > 0:        if (b & 1) > 0:            result = mod_mul(result, a, n)        a = mod_mul(a, a, n)        b = (b >> 1)    return result     def MillerRabinPrimeCheck(n):    if n in {2, 3, 5, 7, 11}:        return True    elif (n == 1 or n % 2 == 0 or n % 3 == 0 or n % 5 == 0 or n % 7 == 0 or n % 11 == 0):        return False    k, u = 0, n - 1    while not (u & 1) > 0:        k += 1        u = (u >> 1)    random.seed(0)    s = 5    for i in range(s):        x = random.randint(2, n - 1)        if x % n == 0:            continue        x = mod_exp(x, u, n)        pre = x        for j in range(k):            x = mod_mul(x, x, n)            if (x == 1 and pre != 1 and pre != n - 1):                return False            pre = x        if x != 1:            return False        return True         def Pollard_rho(x, c):    (i, k) = (1, 2)    x0 = random.randint(0, x)    y = x0    while 1:        i += 1        x0 = (mod_mul(x0, x0, x) + c) % x        d = gcd(y - x0, x)        if d != 1 and d != x:            return d        if y == x0:            return x        if i == k:            y = x0            k += k def PrimeFactorsListGenerator(n):    result = []    if n <= 1:        return None    if MillerRabinPrimeCheck(n):        return [n]    p = n    while p >= n:        p = Pollard_rho(p, random.randint(1, n - 1))    result.extend(PrimeFactorsListGenerator(p))    result.extend(PrimeFactorsListGenerator(n // p))    return result def PrimeFactorsListCleaner(n):    return Counter(PrimeFactorsListGenerator(n))                   PrimeFactorsListCleaner(1254000000)

Bash Shell

123#!/usr/bin/bashread inputfactor "$input"

批处理

123456789101112131415161718192021222324252627282930313233343536373839404142@echo offcolor 1e :start    cls    title 分解质因数程序    set /p num=请输入待分解的数    set num0=%num%    if %num% EQU 1 cls&echo 1既不是素数也不是非素数,不能分解&pause >nul&goto start    if %num% EQU 2 cls&echo 2是素数,不能分解&pause >nul&goto start    if %num% EQU 3 cls&echo 3是素数,不能分解&pause >nul&goto start    set numx=:loop_1    if %num% EQU 1 goto result    set count=3    set /a mod=%num%%%2    echo %mod%    if %mod% EQU 0 ( set numx=%numx%×2&& set /a num=num/2 && goto loop_1 ) :loop_2    set /a mod=%num%%%%count%    if %mod% EQU 0 ( set numx=%numx%×%count%&& set /a num=num/count )    if %num% EQU 1 goto result    if %count% EQU %num% set numx=%numx%×%count%&&goto result    cls    set /a stop=%count%*%count%    if %stop% GTR %num% set numx=%numx%×%num%&& goto result    set /a count+=2    echo 正在计算......    echo %num0%=%numx:~2%    set /a wc=stop*100/num    echo 正在计算%num%的因数    echo 已完成计算%wc%%%    if %mod% EQU 0 goto loop_1    goto loop_2 :result    cls    set numx=%numx:~1%    if %num0% EQU %numx% echo %num0%是素数,不能分解!&pause >nul&goto start    echo %num0%=%numx%    pause >nul    goto start

javascripts

12345678910111213141516171819202122232425262728293031323334353637function prime(maxValue) {    var minPrime = 2;    var primes = [minPrime];    for (var i = 3; i <= maxValue; i++) {        var isPrime = true;        for (var p = 0; p < primes.length; p++) {            if (i % primes[p] == 0) {                isPrime = false;                break;            }        }        if (isPrime) {            primes.push(i);        }    } return primes;}function decomposition(v) {    var results = [];    var primes = prime(v);    var tmp = v;    for (var i = 0; i < primes.length; i++) {        if (tmp == primes[i]) {            results.push(primes[i]);            break;        }        while (tmp % primes[i] == 0) {            tmp /= primes[i];            results.push(primes[i]);        }    }    if (results.length == 1) {        results = [];        results.push(1);        results.push(v);    }    return results;}

参考资料 2

  1. 参考 1
  2. 参考 2
广告位:底部(ad-bottom)—— 请到中台「公共区块」编辑此内容