N!的质因子分解

方法是对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]);
}

个人网站:https://jqh.zone

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值