免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: prolj
打印 上一主题 下一主题

求10的10次方以内的素数,怎么能在几小时内算出来结果? [复制链接]

论坛徽章:
0
31 [报告]
发表于 2009-04-21 16:40 |只看该作者
有人算出来了没有?
我算了4小时出来
2.xxxx^10
不过IO应该占了大部分时间。不IO输出又不知道进度...
这次算完了把IO去掉,只最后一次输出结果

看错时间,近两小时了,4.xxxx ^10

[ 本帖最后由 zliming 于 2009-4-21 17:20 编辑 ]

论坛徽章:
0
32 [报告]
发表于 2009-04-21 16:45 |只看该作者

回复 #31 zliming 的帖子

把code帖出来吧,有时间我跑一下。

论坛徽章:
0
33 [报告]
发表于 2009-04-21 22:30 |只看该作者
#include <stdlib.h>
#include <memory.h>
#include <time.h>
#include <stdio.h>
#include <math.h>
typedef unsigned long long uint;
const uint MAX_NUM = 10000000000;

static int* ret_bit = NULL;

void init_ret_bit()
{
    uint size = MAX_NUM / 8 / 2 + 10;
    ret_bit = (int*)malloc(size);
    memset(ret_bit, 0xff, size);
}
void free_ret_bit()
{
    free(ret_bit);
    ret_bit = NULL;
}
inline bool get_bit(uint i)
{
    i = i / 2 - 1;
    return ret_bit[i >> 5] & (1 << (i & 31));
}
inline void clear_bit(uint i)
{
    i = i / 2 - 1;
    ret_bit[i >> 5] &= ~(1 << (i & 31));
}
int main(int, char*[])
{
    time_t start = time(NULL);
    init_ret_bit();
#if 0
    for(uint i = 3; i <= sqrt((double)MAX_NUM); i+=2)
    {
        if(get_bit(i))
        {
            for(uint j = i + 2; j < MAX_NUM; j+=2)
            {
                if(get_bit(j) && (j % i == 0))
                    clear_bit(j);
            }
        }
    }
#else
    for(uint i = 3; i <= sqrt((double)MAX_NUM);  i+=2)
    {
        if(get_bit(i))
        {
            uint i2 = i + i;
            for(uint j = i2 + i; j < MAX_NUM; j += i2)
                clear_bit(j);
        }
    }
#endif
    //for(uint i = 3; i < MAX_NUM; i+=2)
    //    if(get_bit(i))
    //        printf("%u\n", i);
    //只输出个数,太多东西了
    int all_count = 0;
    for(uint i = 3; i < MAX_NUM; i+= 2)
        if(get_bit(i))
            all_count++;
    printf("count = %d, time = %d", all_count, time(NULL) - start);

    free_ret_bit();
    system("pause");
    return 0;
}

下面的实现法快很多了,网友kaikai帮助优化

[[i] 本帖最后由 zliming 于 2009-4-21 22:46 编辑 [/i]]

论坛徽章:
0
34 [报告]
发表于 2009-04-21 23:23 |只看该作者
count = 455052510, time = 1878请按任意键继续. . .
半小时多,不知道结果个数对不对

论坛徽章:
0
35 [报告]
发表于 2009-04-22 08:40 |只看该作者
kaikai出面了?浙大博士?

论坛徽章:
0
36 [报告]
发表于 2009-04-22 09:33 |只看该作者
可能你认错人了,这个kaikai同济搞游戏的

论坛徽章:
1
2015年迎新春徽章
日期:2015-03-04 09:49:45
37 [报告]
发表于 2009-04-22 10:46 |只看该作者
修改了一下代码
1. 在改成了windows下vc 2005可以编译运行的
2. 参照zliming, 位图使用int*代替char*

说明一下, 位图的存取必须用宏或者inline(编译器优化成inline的也可以), 否则函数调用的开销非常大。

运行结果:
Total: 455052511, Time: 904


  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <time.h>
  4. #include <string.h>

  5. #define CLEAR(map, bit) (map)[(bit) / 32] &= ~(1 << (bit % 32))
  6. #define GET(map, bit) ((map)[(bit) / 32] & (1 << (bit % 32)))

  7. const static long long SQUARE_ROOT = 100000;
  8. const static long long BOUND = SQUARE_ROOT * SQUARE_ROOT;

  9. int main() {
  10.         unsigned long long i = 0;
  11.                 int start = time(NULL);
  12.         int* map = (int*)malloc(BOUND / 8 + 1);
  13.         if (map == 0) {
  14.                 printf("Oh no\n");
  15.                 exit(1);
  16.         }
  17.         memset(map, 0xff, BOUND / 8 + 1);

  18.         CLEAR(map, 1);
  19.         for (i = 1; i < SQUARE_ROOT; i++) {
  20.                 if (!GET(map, i)) continue;
  21.                 printf("%lld\n", i);
  22.                 long long j = i * 2;
  23.                 for (; j < BOUND; j += i) {
  24.                         CLEAR(map, j);
  25.                 }
  26.         }
  27.                 long long total = 0;
  28.         for (i = 1; i < BOUND; i++) {
  29.                 if (GET(map, i)) {
  30.                         total++;
  31.                 }
  32.         }
  33.                 printf("Total: %lld, Time: %d\n", total, time(NULL) - start);
  34.                 system("pause");
  35. }
复制代码

[ 本帖最后由 koolcoy 于 2009-4-22 10:51 编辑 ]

论坛徽章:
1
2015年迎新春徽章
日期:2015-03-04 09:49:45
38 [报告]
发表于 2009-04-22 10:52 |只看该作者
原帖由 zliming 于 2009-4-21 23:23 发表
count = 455052510, time = 1878请按任意键继续. . .
半小时多,不知道结果个数对不对

我比你的结果多一个~~~, 看来是正确的

ps: 我感觉你漏了一个数, 不信你把上限改成100, 你多半把97漏了~

[ 本帖最后由 koolcoy 于 2009-4-22 10:54 编辑 ]

论坛徽章:
0
39 [报告]
发表于 2009-04-22 11:16 |只看该作者
我漏了一个2,这个我清楚的,loop从3开始的

论坛徽章:
0
40 [报告]
发表于 2009-04-22 11:22 |只看该作者
偶数不是质数
我 ret_bit 里直接是从3开始的奇数,不过内存也要700+M
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP