打卡第二十二天(问题:欧拉函数,最大数因数,快速计算素数程序)

1.欧拉函数

欧拉函数是数论中的一个重要函数。

同时,它也是密码系统不可缺少的极其重要的函数。

 
  • * 欧拉函数:数论中,对于正整数n,欧拉函数是小于n的数中与n互质的数的数目。

  • * 此函数以其首名研究者欧拉命名(Ruler'so totient function),

  • * 又称为Euler's totient function、φ函数、欧拉商数等

#include<stdio.h>
int eular(int n)
{
    int ret=1,i;
    for(i=2;i*i<=n;i++){
        if(n%i==0){
            n/=i;
            ret*=i-1;
            while(n%i==0){
                n/=i;
                ret*=i;
                
            }
        }
    }
    if(n>1)
    {
        ret*=n-1;
    }
    return ret;
    
 }
 int main(void)
 {
     int i;
     for(i=2;i<=100;i++)
     {
         printf("i=%d eular=%d\n",i,eular(i));
     }
     return 0;
 }

2.最大素因数

Largest prime factor

筛选法原理适用于本程序,但是不需要用数组来存储筛选结果。

本程序参考欧拉函数写成,是采用逐步排除小素数因子最后得到最大素因数的方法。

 * 最大素因数—Largest prime factor
 *
 * The prime factors of 13195 are 5, 7, 13 and 29.
 * What is the largest prime factor of the number 600851475143 ?
 *
 * 这个问题称为"Prime Factorization"(分解质因数),prime factor称为质因子(或素因子)。
 * 素数也称为质数,是只能被1和自身整除的整数,不包括1。
 *
 * 本程序是参考欧拉函数写成的。
 * 条件:n>=2
#include<stdio.h>
long maxfact(long n)
{
    long ret=2L,i;
    while(n%2==0)
    n/=2;
    for(i=3;i*i<=n;i+=2){
        if(n%i==0){
            ret=i;
            n/=i;
            while(n%i==0)
            n/=i;
        }
    }
    return (n==1)?ret:n;
}
int main(void)
{
    printf("n=%ld maxfact=%ld\n",32L,maxfact(32));
    printf("n=%ld maxfact=%ld\n",9L,maxfact(9));
    printf("n=%ld maxfact=%ld\n",13195L,maxfact(13195));
    printf("n=%ld maxfact=%ld\n",600851475143L,maxfact(600851475143));
    return 0;
}

3.Eratosthenes筛选法

Sieve of Eratosthenes

使用埃拉托斯特尼筛选法计算小于100000的素数。

埃拉托斯特尼筛选法是最为知名的产生素数的筛选法,适用于产生最小的N个素数。

该方法的唯一缺点是使用的存储空间大,可以进一步改进。

另外,该算法也不适用于计算某个范围内的全部素数。

 

 筛选法计算小于100000的素数

筛选法求最小的素数序列,原本是不朽的数学家们手工计算的方法,

 稍微费点空间,也是适合于计算机进行计算的算法

#include<stdio.h>
#include<math.h>
#define MAX 100
int arr[MAX+1]={0,0,1};
int main(void)
{
    int i,j;
    int num=0;
    for(i=3;i<MAX;i++){
        arr[i++]=1;
        arr[i]=0;
    }
    int max=sqrt(MAX);
    for(i=3;i<max;i++){
        if(arr[i]){
            for(j=i+i;j<MAX;j+=i)
            arr[j]=0;
        }
    }
    for(i=2;i<MAX;i++){
        if(arr[i]){
            ++num;
            printf("%d:%d\n",num,i);
        }
    }
    return 0;
}

4.快速计算素数程序

Wheel factorization

Wheel factorization是一种生成素数方法。

对于大于30的数,只有30n+1,30n+7,30n+11,30n+13,30n+17,30n+19,30n+23,30n+29才可能是素数,这里n>=1。

#include<stdio.h>
#include<math.h>
#define NUM_O_PRIMES 2015
long primes1[NUM_O_PRIMES];
void primes()
{
    int base=30,pc=0,column[]={1,7,11,13,17,19,23,29};
    int pp=0;
    primes1[pp++]=2;
    primes1[pp++]=3;
    primes1[pp++]=5;
    primes1[pp++]=7;
    primes1[pp++]=11;
    primes1[pp++]=13;
    primes1[pp++]=17;
    primes1[pp++]=19;
    primes1[pp++]=23;
    primes1[pp++]=29;
    while(pp<NUM_O_PRIMES)
    {
        if(pc==8)
        {
            base+=30;
            pc=0;
        }
        long p,q;
        p=base+column[pc++];
        q=sqrt(p);
        int j=3;
        while(primes1[j]<=q)
        {
            if(p%primes1[j]==0)
            break;
            j++;
        }
        if(primes1[j]>q)
        primes1[pp++]=p;
    }
    
}
int main(void)
{
    primes();
    int i;
    for(i=0;i<NUM_O_PRIMES;i++)
    {
    printf("%d:%d\n",i+1,primes1[i]);

    
}
return 0;
}

猜你喜欢

转载自blog.csdn.net/huangluping12345/article/details/83062455