标题:用位数组计算质数
只看楼主
renkejun1942
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:不是这样
等 级:贵宾
威 望:33
帖 子:1645
专家分:5297
注 册:2016-12-1
结帖率:95.65%
 问题点数:0 回复次数:42 
用位数组计算质数
这道题貌似在很多地方都有出现,就我所记得的就有《C和指针》、《算法》。
效果还不错。
1亿以内的质数,不到1分钟得出结果,只是存储结果的文本文档有60.6M,让人完全没有打开的欲望。

额外吐槽一句:《算法》中的代码风格简直糟糕透顶,对比起来《数据结构与算法分析》的代码风格简直业界良心。

程序代码:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <limits.h>

int
main( void )
{
     unsigned char *BITArray;
     long maxsize;
     long i, j, k;

     scanf( "%ld", &maxsize );    
     maxsize = maxsize / CHAR_BIT;
     BITArray = ( unsigned char * )malloc( maxsize * sizeof( unsigned char ) );
     assert( NULL != BITArray );

     for( i = 0; maxsize > i; ++i )
         BITArray[ i ] |= 0xAA;
     BITArray[ 0 ] = 0xAC;

     for( i = 3; maxsize * CHAR_BIT > i * i; ++i )
         if( BITArray[ i / CHAR_BIT ] & ( 1 << i % CHAR_BIT ) )
             for( j = 2; maxsize * CHAR_BIT > ( k = j * i ); ++j )
                        BITArray[ k / CHAR_BIT ] &= ~( 1 << ( k % CHAR_BIT ) );

     for( i = 2,j = 0; maxsize * CHAR_BIT > i; ++i )
         if( BITArray[ i / CHAR_BIT ] & ( 1 << i % CHAR_BIT ) )
             /*printf("%10ld%c",i, (j + 1) % 8 ? ' ' : '\n'), */++j;

     printf( "\n%ld\n", j );

     return 0;

}



[此贴子已经被作者于2017-4-7 01:36编辑过]

搜索更多相关主题的帖子: 风格 欲望 color 
2017-04-06 03:18
xzlxzlxzl
Rank: 15Rank: 15Rank: 15Rank: 15Rank: 15
来 自:湖北
等 级:贵宾
威 望:125
帖 子:1091
专家分:5825
注 册:2014-5-3
得分:0 
用各种方法求大素数表,我还是认真写过的。对你代码稍作修改,和我写过的代码做了对比,首先你的位法比我的位法用时多近2倍(我的用时不到2秒,你的3。6秒),其次你的1亿内素数总数结果和我的不同,我的代码是进过传统求素数法验证的,所以你的结果应该是错的,对比图如下(图中用时均为毫秒):

为获得1亿内素数总数,修改你的代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <time.h>
#define BIT ( sizeof( unsigned char ) * 8 )

int
main( void )
{
    unsigned char *BitArray;
    long maxsize;
    long i, j,t;

    scanf( "%ld", &maxsize );
    t=clock();
    maxsize = maxsize / BIT;
    BitArray = ( unsigned char * )malloc( maxsize * sizeof( unsigned char ) );
    assert( NULL != BitArray );

    for( i = 0; maxsize > i; ++i )
        BitArray[ i ] |= 0xFF;

    for( i = 2; maxsize * BIT > i; ++i )
        if( BitArray[ i / BIT ] & ( 1 << i % BIT ) )
            for( j = i; maxsize * BIT > j * i; ++j )
                    BitArray[ j * i / BIT ] &= ~(1 << ( j * i % BIT ));

    for( i = 2,j = 0; maxsize * BIT > i; ++i )
        if( BitArray[ i / BIT ] & ( 1 << i % BIT ) )++j;;
            //printf("%10ld%c",i, (j + 1) % 8 ? ' ' : '\n'), ++j;
    printf("time:%d   sum:%d\n",clock()-t,j);

    return 0;

}
2017-04-06 03:52
renkejun1942
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:不是这样
等 级:贵宾
威 望:33
帖 子:1645
专家分:5297
注 册:2016-12-1
得分:0 
回复 2楼 xzlxzlxzl
想不到问题出在哪儿。

先丢在这儿,等哪天想起了再来弄。

[此贴子已经被作者于2017-4-6 09:30编辑过]


09:30 05/21 种下琵琶种子,能种活么?等待中……
21:50 05/27 没有发芽。
20:51 05/28 没有发芽。
23:03 05/29 没有发芽。
23:30 06/09 我有预感,要发芽了。
2017-04-06 07:37
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
得分:0 
看懂了少少~大概就是一个char共8个数位可以记录8个数状态这样节省空间吧~

[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2017-04-06 09:01
renkejun1942
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:不是这样
等 级:贵宾
威 望:33
帖 子:1645
专家分:5297
注 册:2016-12-1
得分:0 
回复 4楼 九转星河
是的。程序的其他部分就是筛选法了。

但是程序貌似还有问题,完全想不到在哪儿,先丢在这儿,等哪天有时间了再来慢慢弄。

09:30 05/21 种下琵琶种子,能种活么?等待中……
21:50 05/27 没有发芽。
20:51 05/28 没有发芽。
23:03 05/29 没有发芽。
23:30 06/09 我有预感,要发芽了。
2017-04-06 09:09
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:432
帖 子:10064
专家分:41463
注 册:2014-5-20
得分:0 
用位运算代替+-*/...运算
2017-04-06 09:22
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:432
帖 子:10064
专家分:41463
注 册:2014-5-20
得分:0 
大素数有什么好方法?
2017-04-06 09:24
renkejun1942
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:不是这样
等 级:贵宾
威 望:33
帖 子:1645
专家分:5297
注 册:2016-12-1
得分:0 
回复 7楼 吹水佬
筛选法了。速度飞快。

对于位运算符我掌握的很烂。

[此贴子已经被作者于2017-4-6 09:32编辑过]


09:30 05/21 种下琵琶种子,能种活么?等待中……
21:50 05/27 没有发芽。
20:51 05/28 没有发芽。
23:03 05/29 没有发芽。
23:30 06/09 我有预感,要发芽了。
2017-04-06 09:31
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:432
帖 子:10064
专家分:41463
注 册:2014-5-20
得分:0 
以下是引用renkejun1942在2017-4-6 09:31:14的发言:

筛选法了。速度飞快。

对于位运算符我掌握的很烂。

不好意思,没说清楚。
是大素数,不只是大量素数,大素数要能突破数值类型的限制。
2017-04-06 09:38
renkejun1942
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:不是这样
等 级:贵宾
威 望:33
帖 子:1645
专家分:5297
注 册:2016-12-1
得分:0 
回复 9楼 吹水佬
对啦,帮我把帖子下沉一下了。程序有错,免得祸害别人。

09:30 05/21 种下琵琶种子,能种活么?等待中……
21:50 05/27 没有发芽。
20:51 05/28 没有发芽。
23:03 05/29 没有发芽。
23:30 06/09 我有预感,要发芽了。
2017-04-06 09:56



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-475824-1-1.html




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

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