| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 830 人关注过本帖
标题:偶尔看到一本比较古老的书,才发现 筛选法 往出筛素数 并不是多么新新的算 ...
只看楼主 加入收藏
wp231957
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:神界
等 级:贵宾
威 望:423
帖 子:13688
专家分:53332
注 册:2012-10-18
结帖率:99.76%
收藏
已结贴  问题点数:100 回复次数:14 
偶尔看到一本比较古老的书,才发现 筛选法 往出筛素数 并不是多么新新的算法,相反是一个挺古老的算法
大家帮我看看 是不是这样子筛选的  是否有漏洞 或者有待优化的地方

程序代码:
#include <stdio.h>
#define max 300

//使用筛选法列举素数
int main()
{
    int i=2;
    int k,j;
    int t[max]={0};
    for(k=0;k<max;k++) t[k]=i+k;   //为待扫描数据赋初值 自然数序列 从2开始
    i=0;
    k=t[i];  //初始素数
    while(i<max)
    {
        i++;
        for(j=i;j<max;j++) if(t[j]%k==0) t[j]=0;  //凡能够整除者 赋0
        while(t[i]==0) i++;  //搜索下一个素数
        k=t[i];
    }
    for(k=0;k<max;k++)
    {
        if(t[k]!=0) printf("%d ",t[k]);    //不是0者,即素数 打印输出
    }
    printf("\n");
    return 0;
}

2014-04-02 15:13
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:528
帖 子:9025
专家分:54030
注 册:2011-1-18
收藏
得分:10 
用一个bit就可以保存一个数字,因此你可以压缩到 1/sizeof(int)*8
2的倍数参与计算了,你又可以再压缩 1/2
2014-04-02 15:33
wp231957
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:神界
等 级:贵宾
威 望:423
帖 子:13688
专家分:53332
注 册:2012-10-18
收藏
得分:0 
以下是引用rjsp在2014-4-2 15:33:33的发言:

用一个bit就可以保存一个数字,因此你可以压缩到 1/sizeof(int)*8


都说用bit保存数字  不知道具体咋弄呢  能给一段示例 研究一下!!

DO IT YOURSELF !
2014-04-02 15:39
yuccn
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:何方
等 级:版主
威 望:167
帖 子:6815
专家分:42393
注 册:2010-12-16
收藏
得分:10 
表示没有看懂

我行我乐
公众号:逻辑客栈
我的博客:
https://blog.yuccn. net
2014-04-02 16:16
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:528
帖 子:9025
专家分:54030
注 册:2011-1-18
收藏
得分:0 
以下是引用wp231957在2014-4-2 15:39:14的发言:
  
都说用bit保存数字  不知道具体咋弄呢  能给一段示例 研究一下!!
比如我这代码代码,第0个bit表示3,第1个bit表示5,第2个bit表示7,……

你用int[300]算到293
我只用int[5]就可以算到317

但代码是我仓促写的(可能有错误),你参考一下
程序代码:
#include <stdio.h>

#define MAX 5

#define COUNT        ( MAX*sizeof(unsigned)*8 )
#define IDX2VAL(i)   ( i*2+3 )
#define TESTBIT(t,i) ( (t[i/(sizeof(t[0])*8)] & 1u<<(i%(sizeof(t[0])*8))) == 0 )
#define INVLBIT(t,i) ( t[i/(sizeof(t[0])*8)] |= 1u<<(i%(sizeof(t[0])*8)) )

int main()
{
    unsigned t[MAX] = { 0 };
    for( size_t i=0; IDX2VAL(i)*2<=IDX2VAL(COUNT-1); ++i )
        if( TESTBIT(t,i) )
            for( size_t j=i+IDX2VAL(i); j<COUNT; j+=IDX2VAL(i) )
                INVLBIT(t,j);

    printf( "%u ", 2 );
    for( size_t i=0; i!=COUNT; ++i )
        if( TESTBIT(t,i) )
            printf( "%u ", IDX2VAL(i) );

    printf("\n");
    return 0;
}


2014-04-02 16:23
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:528
帖 子:9025
专家分:54030
注 册:2011-1-18
收藏
得分:0 
果然有问题,
IDX2VAL(i)*2<=IDX2VAL(COUNT-1)
应当改为
IDX2VAL(i)*3<=IDX2VAL(COUNT-1)
虽然不影响结果

下班了,明天我再仔细检查一下

------------------------------------------

代码没错,但我稍微改一下,以便于理解。
程序代码:
#include <stdio.h>

#define BUFSIZE 300

#define BITCOUNT     ( BUFSIZE*sizeof(unsigned)*8 )
#define IDX2VAL(i)   ( i*2+3 )
#define TESTBIT(t,i) ( (t[i/(sizeof(t[0])*8)] & 1u<<(i%(sizeof(t[0])*8))) == 0 )
#define INVLBIT(t,i) ( t[i/(sizeof(t[0])*8)] |= 1u<<(i%(sizeof(t[0])*8)) )

int main()
{
    unsigned t[BUFSIZE] = { 0 };
    for( size_t i=0; i+IDX2VAL(i)<BITCOUNT; ++i )
        if( TESTBIT(t,i) )
            for( size_t j=i+IDX2VAL(i); j<BITCOUNT; j+=IDX2VAL(i) )
                INVLBIT(t,j);

    printf( "%u ", 2 );
    for( size_t i=0; i!=BITCOUNT; ++i )
        if( TESTBIT(t,i) )
            printf( "%u ", IDX2VAL(i) );

    printf("\n");
    return 0;
}

使用bit的好处是,不但节约了内存,而且因为内存寻址范围小了,使得运行效率更高。遍历一个int的32(64)个bits 要快于 遍历32(64)个int。
而且在数据量更大的情况下,还会涉及到内存页的切换,这个代价更大,所以要尽量减少内存页切换次数。


[ 本帖最后由 rjsp 于 2014-4-3 09:16 编辑 ]
2014-04-02 16:31
xing139565
Rank: 2
等 级:论坛游民
帖 子:1
专家分:10
注 册:2014-4-2
收藏
得分:10 
我是嫩手啊....高手都不喜欢在for()后面加上{}吗?上面已经定义了i=2,为何下面又要定义i=0呀?
2014-04-02 17:19
ljx小子
Rank: 8Rank: 8
来 自:星星
等 级:蝙蝠侠
威 望:2
帖 子:222
专家分:916
注 册:2013-10-7
收藏
得分:10 
来学习学习。。

。。。。。。。。。。。
2014-04-02 17:21
神机军师
Rank: 7Rank: 7Rank: 7
来 自:游鱼潜水
等 级:黑侠
威 望:2
帖 子:202
专家分:542
注 册:2013-12-21
收藏
得分:10 
前来学习

未知令人期待!
2014-04-02 18:14
我是殊帕面
Rank: 2
等 级:论坛游民
帖 子:10
专家分:10
注 册:2014-3-30
收藏
得分:10 
楼主刚刚回我贴了,我来学习学习
2014-04-02 18:57
快速回复:偶尔看到一本比较古老的书,才发现 筛选法 往出筛素数 并不是多么新 ...
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.032171 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved