分解質因數(質因數分解)

分解質因數

質因數分解一般指本詞條

每個合數都可以寫成幾個質數相乘的形式,其中每個質數都是這個合數的因數,把一個合數用質因數相乘的形式表示出來,叫做分解質因數。如30=2×3×5 。分解質因數隻針對合數。

基本介紹

  • 中文名:分解質因數
  • 外文名:Prime factor decomposition, Prime factorization
  • 釋義:求質因數的過程
  • 又稱:分解質因子
定義,定理,編程分解,C#,pascal,Java,Visual Basic,c語言,C++,Common Lisp,Python 2.x,Python 3.x,Bash Shell,批處理,javascripts,

定義

把一個合數分解成若干個質因數的乘積的形式,即求質因數的過程叫做分解質因數。
分解質因數隻針對合數。(分解質因數也稱分解素因數)求一個數分解質因數,要從最小的質數除起,一直除到結果為質數為止。分解質因數的算式叫短除法,和除法的性質相似,還可以用來求多個數的公因式

定理

不存在最大質數的證明:(使用反證法)
假設存在最大的質數為N,則所有的質數序列為:N1,N2,N3……N
設M=(N1×N2×N3×N4×……N)+1,
可以證明M不能被任何質數整除,得出M也是一個質數。
而M>N,與假設矛盾,故可證明不存在最大的質數
第二種因數分解的方法:
1975年,John M. Pollard提出。該算法時間複雜度為O(
)。詳見參考資料。

編程分解

C#

static 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()));}
另一種實現
#include <stdio.h>Integer m,b,c := 0,j := 0;Integer a[10]; //存放質因數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

//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

import 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[50];        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[0]);            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

Dimx,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上運行。
#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運行。
#include <stdio.h>int m, b, c = 0, j = 0;int a[10];    //存放質因數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++

//將一個數n分解為若干個從小到大排列的質數的積#include <iostream>using namespace std;int main(){    int n, n2;    cin >> n;    cout << n << "=";    n2 = n;    if(n < 2)return 0;                //小於2的數不合法,若n為質數則輸出它本身    for (int i = 2; i*i <= n2; i++)        //根號n複雜度    {        while (n2%i == 0)        {            n2 = n2 / i;            cout << i;            if (n2 != 1)cout << "*";        }    }    if(n2! = 1)    cout << n2;        //當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

#!/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

#MillerRabin素數判定,結合Pollard_rho遞歸分解,效率極高import randomfrom collections import Counterdef 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 += kdef 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 resultdef PrimeFactorsListCleaner(n):    return Counter(PrimeFactorsListGenerator(n))                  PrimeFactorsListCleaner(1254000000)

Bash Shell

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

批處理

@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

function 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;}

相關詞條

熱門詞條

聯絡我們