1 # include<iostream> 2 # include<cstdio> 3 # include<cstring> 4 # include<map> 5 # include<algorithm> 6 using namespace std; 7 int ans[205]; 8 void just_do() 9 { 10 map<int,int>m; 11 map<int,int>::iterator it; 12 memset(ans,0,sizeof(ans)); 13 for(int i=1;i<=200;++i){ 14 cout<<i<<": "; 15 m.clear(); 16 int n=i,j=2; 17 while(j*j<=n){ ///外部循環 18 while(n%j==0){ ///內部循環 19 cout<<j<<' '; 20 n/=j; 21 } 22 ++j; 23 } 24 if(n>1) 25 cout<<n; 26 cout<<endl; 27 } 28 } 29 int main() 30 { 31 just_do(); 32 return 0; 33 }
上述方法類似於篩法,原理如下:
我們用所有正整數試驗一下,從2開始進行試除,逐步增加除數的值,去尋找一個可以整除n的數。在Eratosthenes篩法的討論中,我們知道如果n是一個復合數,那么它就會有一個素數 。算法9.3所示的就是這種方法的偽代碼。這個算法有兩個偱環路徑,外部的和內部的。外部循環求唯一因數,內部循環求一個因數的多個復本。例如,
,外部循環求出因數2和3。內部循環求出2是一個多因數。
實際上就是將不是素數的因數篩掉。
Pollard Rho因數分解
1975年,John M. Pollard提出了第二種因數分解的方法,Pollard Rho快速因數分解。該算法時間復雜度為O(n^(1/4))。
將一個正整數分解質因數。例如:輸入90,打印出90=2*3*3*5。
程序分析:對n進行分解質因數,應先找到一個最小的質數k,然后按下述步驟完成:
(1)如果這個質數恰等於n,則說明分解質因數的過程已經結束,打印出即可。
(2)如果n<>k,但n能被k整除,則應打印出k的值,並用n除以k的商,作為新的正整數你n,
重復執行第一步。
(3)如果n不能被k整除,則用k+1作為k的值,重復執行第一步。
程序分析:對n進行分解質因數,應先找到一個最小的質數k,然后按下述步驟完成:
(1)如果這個質數恰等於n,則說明分解質因數的過程已經結束,打印出即可。
(2)如果n<>k,但n能被k整除,則應打印出k的值,並用n除以k的商,作為新的正整數你n,
重復執行第一步。
(3)如果n不能被k整除,則用k+1作為k的值,重復執行第一步。
分解質因數代碼:
1 #include "stdio.h" 2 #include "conio.h" 3 main() 4 { 5 int n,i; 6 printf("\nplease input a number:\n"); 7 scanf("%d",&n); 8 printf("%d=",n); 9 for(i=2;i<=n;i++) 10 while(n!=i) 11 { 12 if(n%i==0) 13 { 14 printf("%d*",i); 15 n=n/i; 16 } 17 else 18 break; 19 } 20 printf("%d",n); 21 }
另一種方法是利用打好的素數表來分解質因數,針對於大整數。
1 a[0]=0; 2 int prim_reduce(int n) //整數素分解 3 { 4 for(int i = 0; prim[i] * prim[i] <= n; ++i) 5 { 6 while(n % prim[i] == 0) 7 { 8 n /= prim[i]; 9 a[++a[0]]=pri[i]; 10 } 11 } 12 if(n > 1) 13 a[++a[0]]=pri[i]; 14 }