弄了个欧拉筛求素数

最近遇到某方面的内容和欧拉筛有关系,于是就自己重新弄了个欧拉筛,当然记得以前自己曾经写过一次,这次自己完全写起来发现和第一次写的主体方面还是差不多(就那么一个细微的区别),可以参考一下

程序代码:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<assert.h>

void nodeMal( void** ,size_t );
void nodeFree( void** );
void nodeRea( void** ,size_t );

void fun ( char**,size_t**,size_t );
void print( const size_t* );

int main( void )
{
    char* isPrime=NULL;
    size_t* prime=NULL;

fun(&isPrime,&prime,101);
    print(prime);
    
    nodeFree(( void** )&isPrime);
    nodeFree(( void** )&prime);
    
    return 0;
}

void nodeMal( void** p,size_t size )
{
    assert(p);
    
    *p=malloc(size);
    
    assert(*p);

memset(*p,0,size);
}

void nodeRea( void** p,size_t size )
{
    void* p_new=NULL;
    
    assert(p);
    
    p_new=realloc(*p,size);
    
    assert(p_new);
 
     *p=p_new;
}

void nodeFree( void** p )
{
    assert(p);
    
    free(*p);
    *p=NULL;
}

void fun ( char** _isPrime,size_t** _prime,size_t len )
{
    
    char* isPrime=NULL;
    size_t* prime=NULL;
    
    size_t i;
    
    if (len<3)
        return ;
    
    nodeMal(( void** )_isPrime,sizeof (isPrime)*len);
    nodeMal(( void** )_prime,sizeof (isPrime)*len);
    
    isPrime=*_isPrime;
    prime=*_prime;
    
    for (i=0;i!=len;++i)
        isPrime[i]=0;  //测试手机运调用memset后可能还有少量内存块没有清零,所以这里重新赋值保险一点
        
    prime[0]=0;
    
    for (i=2;i!=len;++i)
    {
        size_t j;

if (isPrime[i]==0)
            prime[++prime[0]]=i;
       
        for (j=1;prime[j]<=len/i;++j)
        {
            isPrime[i*prime[j]]=1;
            
            if (i%prime[j]==0)
                break;
        }
    }

nodeRea(( void** )_prime,sizeof ( size_t )*((*_prime)[0]+1));
    
}

void print( const size_t* prime )
{
    size_t i;
    if (prime==NULL)
        return ;

for (i=1;i!=prime[0]+1;++i)
        printf("%-6u",( unsigned )prime[i]);
        
    puts("");
}

PS:如果需要简单版参考的可以看看这个我第一次弄的(的确除了那个细节地方差不多一个样)~

程序代码:

#include<stdio.h>

#define MAX 100
char IsPrime[MAX+1]={0};
int prim[MAX+1]={0};

int main()
{
    int i=0;
    int j=0;
    int num=0;

for (i=2;i<=MAX;++i)
    {
        if (!IsPrime[i])
            prim[num++]=i;

for (j=0;j<num&&i*prim[j]<=MAX;++j)
        {
            IsPrime[i*prim[j]]=1;

if (i%prim[j]==0)
                break;
        }
    }

for (i=0;i<num;++i)
        printf("%-4d",prim[i]);

puts("");

return 0;
}

原创文章:http://blog.163.com/huyunsong1314/

原文地址:https://www.cnblogs.com/5aafa/p/8686769.html

时间: 2024-08-06 15:45:29

弄了个欧拉筛求素数的相关文章

欧拉筛法求素数

欧拉筛法求素数     首先,我们知道当一个数为素数的时候,它的倍数肯定不是素数.所以我们可以从2开始通过乘积筛掉所有的合数.     将所有合数标记,保证不被重复筛除,时间复杂度为O(n).代码比较简单↓_↓ /*求小于等于n的素数的个数*/ #include<stdio.h> #include<string.h> using namespace std; int main() { int n, cnt = 0; int prime[100001];//存素数 bool vis[

欧拉筛法求素数个数

判断a是否为素数,求1——n的素数个数 考虑欧拉筛法———— http://wenku.baidu.com/link?url=dFs00TAw8_k46aeSbXy5nB5LVqJ51uUJgY9zVWEDQdwjLN-qLFWZuYcGPE5EDcztNQAMtKfUbSseBvfBzV4fcQvlneOVHJJQvgJjcGC1iN7 //判断是否为素数:计算1到n的素数个数 #include<iostream> #include<cstring> #define MAX 10

线性筛法(欧拉筛法)求素数

写$\text{O}\left( n \log{\log{n}}\right)$的筛法很长时间了,我却从来没想过它的优化.偶然间看到线性筛法,心想大约是不错的优化,于是便爬去学习下. 首先,$\text{O}\left( n \log{\log{n}}\right)$的筛法肯定要比$\text{O}\left( n\right)$的慢,虽然在现在的机子上不明显.还是不要将$\text{O}\left( n \log{\log{n}}\right)$比较靠谱.但是线性筛法有着它自己的用途.

素数筛&amp;&amp;欧拉筛 BZOJ2818 Gcd BZOJ2190 [SDOI2008]仪仗队

折腾了一晚上很水的数论,整个人都萌萌哒 主要看了欧拉筛和素数筛的O(n)的算法 这个比那个一长串英文名的算法的优势在于没有多次计算一个数,也就是说一个数只筛了一次,主要是在%==0之后跳出实现的,具体的解释看的迷迷糊糊,特别是欧拉函数的求解 http://blog.csdn.net/lerenceray/article/details/12420725 代码如下 1 void ES(){ 2 for(int i=2;i<n;i++){ 3 if (!pd[i]){ 4 prime[++top]=

2018南京icpc-J-Prime Game (欧拉筛+唯一分解定理)

题意:给定n个数ai(n<=1e6,ai<=1e6),定义,并且fac(l,r)为mul(l,r)的不同质因数的个数,求 思路:可以先用欧拉筛求出1e6以内的所有质数,然后对所有ai判断,如果ai不是质数就利用唯一分解定理计算其所有质因数.然后按照顺序依次计算每个质因子的贡献.假设n=5,对质因子2,依次记录它在数组出现的下标,如果它在2.4下标出现了,那么它的贡献即为所有包含2或4的区间个数,逆向计算,即所有区间个数-不包含2和4的区间个数,即 n(n+1)/2-m1(m1+1)/2-m2(

[数论]欧拉函数&素数筛

一.欧拉函数 欧拉函数是小于x的整数中与x互质的数的个数,一般用φ(x)表示. 通式: 其中p1, p2--pn为x的所有质因数,x是不为0的整数. 比如x=12,拆成质因数为12=2*2*3, 12以内有1/2的数是2的倍数,那么有1-1/2的数不是2的倍数(1,3,5,7,9,11), 这6个数里又有1/3的数是3的倍数, 只剩下(1 - 1/2 - 1/3)的数既不是2的倍数,也不是3的倍数(1,5,7,11). 这样剩下的12*(1 - 1/2 - 1/3)=4,即4个数与12互质,所以

常见模板(欧拉筛素数,最小生成树,快排,并查集,单源最短路)

欧拉筛素数: #include<cstdio> #define maxn 10000000+10 using namespace std; int n,prime[5000001],num_prime=0,m; bool if_prime[maxn]; void euler(int limit) { for(int i=2;i<=limit;i++) { if(!if_prime[i]) prime[++num_prime]=i; for(int j=1;prime[j]*i<=l

线性筛素数(欧拉筛)

线性筛素数(欧拉筛) 欧拉筛为啥是\(O(n)\)的呢?我们先来看看代码. #include <cstdio> using namespace std; const int maxn=10000000; int n, m, prime[maxn], isnt_prime[maxn], tot; void get_prime(int n){ isnt_prime[0]=isnt_prime[1]=1; for (int i=2; i<=n; ++i){ //当前数是所有数小于n的数而不只是

素数表的获取(埃氏筛和欧拉筛)

Eratosthenes筛法(埃氏筛) 时间复杂度:O(nlognlogn) 思路 代码 const int maxn=1e6+10; //表长 int prime[maxn],cnt=0; //prime数组存放所以素数,cnt为素数个数 bool st[maxn]; //false为素数 void get_prime(int n){ for(int i=2;i<=n;i++){ if(!st[i]){ prime[cnt++]=i; //把素数i存到prime数组中 for(int j=i+