题目
思路
1.首先打表:用筛法将sqrt(n)之前的所有素数打到表p[pnum++]中;
2.将组成n的所有素数及相应素数个数存入结构体factor[]中;并在存入的过程中将n逐渐分解为更小的数;
3.当素数表到达p[pnum]时,n被分解剩余的数为最后的素数;
出现错误及纠错过程
0.未注意到需要使用long long int;
1.没想到素数表只需打到sqrt(n);导致素数表太大超出限制出现段错误;
2.在find_factor中分解n的循环边界设定为n!=1,而忽视了pnum的边界;导致p[i]中i超过pnum从而n被错误的divisor分解;
3.素数表的长度只弄到100长度不够导致段错误;
代码
#include<iostream>
#include<cmath>
using namespace std;
int pnum=0; int fnum=0; int p[10000]; bool notprime[100010]={false};//段错误原因p[100]太小
struct factor{
int date;
int num;
}factor[100];
void find_prime(int n){
int m=(int)sqrt(1.0*n);
for(int i=2;i<=m;i++){
if(!notprime[i]){
p[pnum++]=i;
for(int j=i+i;j<=m;j+=i){
notprime[j]=true;
}
}
}
}
void find_factor(int n){
for(int i=0;n!=1&&i<pnum;i++){
if(n%p[i]==0){
factor[fnum].date=p[i];
while(n%p[i]==0){
factor[fnum].num++;
n/=p[i];
}
fnum++;
}
}
if(n!=1){
factor[fnum].date=n;
factor[fnum++].num++;
}
}
int main(){
for(int i=0;i<100;i++){
factor[i].num=0;
}
long long int n;
scanf("%lld",&n);
if(n==1) printf("1=1");
else{
find_prime(n);
find_factor(n);
printf("%lld=",n);
for(int i=0;i<fnum;i++){
if(factor[i].num==1) printf("%lld",factor[i].date);
else printf("%lld^%lld",factor[i].date,factor[i--------].num);
if(i!=fnum-1) cout<<'*';
}
}
return 0;
}
算法笔记中非筛法打表法代码
–