随笔 - 68  文章 - 57  trackbacks - 0
<2015年4月>
2930311234
567891011
12131415161718
19202122232425
262728293012
3456789

常用链接

留言簿(8)

随笔分类(74)

随笔档案(68)

搜索

  •  

最新评论

阅读排行榜

评论排行榜

这个是经典的Eraosthenes筛法:
for (int i = 2; i * i < N; i++)
{
    
if (tag[i]) continue;
    
for (int j = i; i * j < N; j++)
        tag[i
*j] = 1;
}
for (int i = 2; i < N; i++)
    
if (!tag[i])
        prime[tol
++= i;

但是Eraosthenes筛法的速度并不快,原因在于对于一个合数,这种方法会重复的标记。一种线性筛素数的方法有效的解决了这一点,代码如下:
void get_prime()
{
    
int cnt = 0;
    
for (int i = 2; i < N; i++)
    {
        
if (!tag[i])    p[cnt++= i;
        
for (int j = 0; j < cnt && p[j] * i < N; j++)
        {
            tag[i
*p[j]] = 1;
            
if (i % p[j] == 0)
                
break;
        }
    }
}
可以用均摊分析的方法来分析这个算法的复杂度:由于每个合数都唯一的被它的最小素因子筛一次,而每个合数的最小素因子都是唯一的,因此总复杂度是O(n)。
这种筛法的思想很强悍,有很多利用价值,可以根据这种方法做到线性筛欧拉函数等等,继续研究中。。
posted on 2009-03-16 21:29 sdfond 阅读(4583) 评论(5)  编辑 收藏 引用 所属分类: Algorithm - Number Theory

FeedBack:
# re: 筛法求素数 2010-08-09 16:37 asdf
这个筛素数的方法是什么原理呀呀呀。。。  回复  更多评论
  
# re: 筛法求素数 2010-12-14 14:20 Someone
原来的算法也是线性的啊
外层循环量:O(n)
内层循环量:O(n/lg(n))*O(lg(n))=O(n)  回复  更多评论
  
# re: 筛法求素数 2015-04-26 23:10 eval
有个typo; inner loop是 i * j < N 而不是 j * j < N

望尽快修改过来,不要误导网友。  回复  更多评论
  
# re: 筛法求素数 2015-04-27 18:21 sdfond
@eval
感谢您的指正!

已修改  回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理