挑战各位高手,一个求素数的算法

madeinchina 2001-11-26 06:57:37
求10的10次方内的所有素数
...全文
201 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
vioy 2001-12-07
  • 打赏
  • 举报
回复
因为计算步长的时候,步长的累加和等于你数集中所有的素数之积

出现回环的感觉是因为这些数太接近了

如果你能找出规律,那就恭喜你,可能解出歌德巴赫猜想了。
Arter 2001-11-28
  • 打赏
  • 举报
回复
"求10的10次方内的所有素数"---古老的筛法就可以了(用高精度算法).
monkeyy_cn 2001-11-27
  • 打赏
  • 举报
回复
to : vioy(负电子云) 
你说的步长计算怎么有回环的感觉!!
随机素数测试法那儿有??
bjay 2001-11-27
  • 打赏
  • 举报
回复
贴子好
madeinchina 2001-11-27
  • 打赏
  • 举报
回复
多谢斑竹,我来慢慢理解
starfish 2001-11-27
  • 打赏
  • 举报
回复
用随机素数测试法测试素数即可搞定。代码如下,原理和证明请参阅数论方面的资料


/*********************************************

Miller_Rabin随机素数测试算法

说明:这种算法可以快速地测试一个数是否
满足素数的必要条件,但不是充分条件。不
过也可以用它来测试素数,出错概率很小,
对于任意奇数n>2和正整数s,该算法出错概率
至多为2^(-s),因此,增大s可以减小出错概
率,一般取s=50就足够了。

*********************************************/

int Witness(int a, int n)
{
int i, d = 1, x;
for (i = ceil( log( (float) n - 1 ) / log(2.0) ) - 1; i >= 0; i--)
{
x = d;
d = (d * d) % n;
if ( (d == 1) && (x != 1) && (x != n-1) ) return 1;
if ( ( (n - 1) & ( 1<<i ) ) >0 ) d = (d * a) % n;
}
return (d == 1 ? 0 : 1);
}

int Miller_Rabin(int n, int s)
{
int j, a;
for (j = 0; j < s; j++)
{
a = rand() * (n - 2) / RAND_MAX + 1;
if (Witness(a, n)) return 0;
}
return 1;
}

madeinchina 2001-11-27
  • 打赏
  • 举报
回复
当n很大时,a[]数组中的值会较大在100万内好象最大的达100
另外,10的10次方即100亿如何存储?
vioy 2001-11-26
  • 打赏
  • 举报
回复
我有一个根据筛法略加优化的算法。

主要思想是:

1:判断一个数是不是素数,只要不能被小于它的平方根的所有素数整除就可以了。

2:我归纳出了一个数组,循环使用这个数组中的数为递增步长来查找下一个可能的素数。
这个数组的构造是这样的:

a[1]={2}
这是被2筛下来的数的间距值,从2下一个素数,也就是3开始筛上的数总是比前一个大2。

a[2]={2,4}
这是被2,3筛下来的数的间距值,从3下一个素数,也就是5开始筛上的数总是按+2,+4的步长增加的。

a[8]={4,2,4,2,4,6,2,6}
这是被2,3,5筛下来的数的间距值,从5下一个素数,也就是7开始筛上的数总是按+4,+2,+4,+2,+4,+6,+2,+6的步长增加的。

你也可以自己推更长的数组,减少你运算的次数。

你用数集E={2,3,5,7,...,n}(n为素数)确定了你的素数筛子数组,程序运算的时候,从大于n的下一个素数开始,按你的筛子数组递增,数组用完了之后,从头再开始。这个时候,选出来的数x已经不能被E中的素数整除了,你只要判断x能不能被从n下一个素数到sqr(x)之间的素数整除就可以了。

这个算法的速度,在于你的筛子数组,数组越大,速度越快。
alphagx 2001-11-26
  • 打赏
  • 举报
回复
所以不能用求余的操作

改为:
不能简单的用%来进行整除
alphagx 2001-11-26
  • 打赏
  • 举报
回复
建议:
因为是10 的10次方,所以不能用求余的操作。
你定义一个类,放DWORD
你就需要自己写一个求余的函数。
然后每次增加的时候进行一些处理+2,
再在进函数前判断是否能被3整除, 因为一个数每一位加起来的和能被3整除,说明这个数就能被3整除,

再判断能否被5整除, 只需要判断个位是0 或是5,
除此之外,都不能被5整除




hfcRabbit 2001-11-26
  • 打赏
  • 举报
回复
我有一个办法: (伪码)
for( i = 2; i < 0.5e10; i ++ )

if( i 作标志了吗? )如果没有做标志 则是素数
for( j = 2; j * i < 1.0e10; j ++ )
对 j*i 作标志(即 它不是素数)
madeinchina 2001-11-26
  • 打赏
  • 举报
回复
??
madeinchina 2001-11-26
  • 打赏
  • 举报
回复
?
madeinchina 2001-11-26
  • 打赏
  • 举报
回复
不要用2到sqrt(n)

33,028

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧