题意:
给出一个int型正整数N,要求把N分解成若干个质因子,如N=97532468,则把N分解成:97532468=2^2*11*17*101*1291。质因子按增序输出,如果某个质因子的幂是1,则1不输出。
思路:质因子分解的基础题。
首先,定义如下因子的结构体,用于存放最终的结果。因为N是一个int范围的正整数,由于2*3*5*7*11*13*17*19*23*29>INT_MAX,也就是说,任意一个int型整数,可分解出来的不同的质因子的个数不会超过10个,因此,数组只要开到10就够了。
struct Factor{ int fac;//质因子 int cnt;//质因子出现的次数 }factor[10];
在对正整数N进行分解之前,首先要获取素数表,令其存在数组prime中,这样一来,则逐个判断这个prime数组中的素数,若整除,则一直用N除以当前这个素数,记录这个素数出现的次数,除到不能整除为止,再进入下一个素数的判断。
但是,如果我们要求N=2,147,483,647(INT_MAX)的质因子呢?难道需要求出所有整型的素数吗?这样做当然没有错,但却会超时(判断素数的时间复杂度是O(sqrt(N)),枚举获取1~N的全部素数的时间复杂度是O(N),因此总的时间复杂度是O(N*sqrt(N)),若N>10^5基本就超时了),事实上,对于质因子分解,有这样一个结论:如果一个整数n存在[2, n]内的质因子,这些质因子要么全部小于等于sqrt(n);要么只存在一个质因子大于sqrt(n),而其他质因子全部小于等于sqrt(n)。基于此,我们考虑,int型的最大值是2,147,483,647,而sqrt(2,147,483,647)≈46,341,根据刚才所说的结论,也就是说一个int型整数若不能被46341以内的素数整除的话,说明因子就是其本身了。因此,我在获取素数表的getPrime()函数中直接硬编码了。
代码:
#include <stdio.h> #include <math.h> #include <vector> using namespace std; struct Factor{ int fac;//质因子 int cnt;//质因子出现的次数 }factor[10]; vector<int> prime;//素数表 //判断素数 bool isPrime(int n) { if(n<=1) return false; int sqr=(int)sqrt(n); for(int i=2;i<=sqr;i++) if(n%i==0) return false; return true; } //获取素数表,打表思想 void getPrime() { for(int i=2;i<50000;i++) if(isPrime(i)) prime.push_back(i); } int main() { int val; scanf("%d",&val); getPrime(); int temp=val; int len=0;//factor数组的长度 for(int i=0;i<prime.size();i++){ int p=prime[i]; if(temp%p==0){ factor[len].fac=p; factor[len].cnt=0; while(temp%p==0){ factor[len].cnt++; temp/=p; } len++; if(temp==1) break;//表示除尽 } } if(temp!=1){ factor[len].fac=temp; factor[len].cnt=1; len++; } printf("%d=",val); if(val==1) printf("1"); for(int i=0;i<len;i++){ printf("%d",factor[i].fac); if(factor[i].cnt>1) printf("^%d",factor[i].cnt); if(i<len-1) printf("*"); } return 0; }
原文地址:https://www.cnblogs.com/kkmjy/p/9534279.html