方法是对1~n每个数进行质因子分解,然后把每个质数出现的次数都加起来。生成质数表用的是筛选法求素数。
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define MAX_N 60000//N的最大值
#define MAX_ITEM 7500//MAX_N中的质数的估计个数
int primes[MAX_ITEM]= {0},numbers[MAX_ITEM]= {0};
int gen_primes(int n,int *primes);//生成质数表
void gen_factors(int n,int m,int *primes,int *num);//分解质因子
void print(int m,int *primes,int *num);//输出结果
int is_prime(int);//判断是否为素数
void filter(int *,int,int);//筛选
int main()
{
int m,n;
printf("please Enter N:");
scanf("%d",&n);
if(n<2||n>MAX_N)
{
printf("N must be between 2 and %d\n",MAX_N);
}
else
{
m=gen_primes(n,primes);//生成质数表,m为质数的个数
gen_factors(n,m,primes,numbers);//将1~n每个数分解成质因子,并将质数的出现次数保存到number中
print(m,primes,numbers);//输出结果
}
return 0;
}
int gen_primes(int n,int *primes)
{
int i,num=0,*p;
p=(int*)malloc(sizeof(int)*(n+1));//创建一个p数组,用于保存所有的数
for(i=1; i<=n; ++i)//初始化数组p
p[i]=i;//使数组p中的值为1-n
for(i=2; i<=n; ++i)
{
if(p[i]==0)
continue;
if(is_prime(i))//判断是否是素数
filter(p,i,n);//筛选
}
i=2;
for(i=2; i<=n; ++i)
{
if(p[i]!=0)//将所有不是零的元素赋值给primes数组
{
primes[num]=p[i];
++num;
}
}
return num;//返回质数的个数
}
int is_prime(int n)//判断n是否为素数
{
int i,flag=1;//flag初始值为1
for(i=2; i<=sqrt(n); ++i)
{
if(n%i==0)//不是素数
{
flag=0;
break;
}
}
return flag;//如果是素数返回flag初始值1,否则返回0
}
void filter(int *p,int m,int n)
{
int i;
for(i=m*2; i<=n; i+=m)//将数组中素数的整数倍置为0
p[i]=0;
}
void gen_factors(int n,int m,int *primes,int *num)
{
int i,j=0,k;
for(i=1;i<=n;++i)
{
k=i;
while(primes[j]<=k&&j<=m)
{
if(k%primes[j]==0)//如果primes[j]是k的质因子
{
k/=primes[j];//k赋值为k/primes[j]
++num[j];
j=0;//回到素数表的开头,再次寻找质因子
}
else
++j;//尝试下一个素数
}
}
}
void print(int m,int *primes,int *num)
{
int i;
for(i=0;i<m;++i)
printf("%d %dtimes ",primes[i],num[i]);
}