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 }