JS埃式筛法(求素数)

题:求 0 至 x 的素数的个数。

接触算法之前,我们求素数常常用的是暴力枚举。

但即便是暴力枚举,多琢磨琢磨,我们也能想到优化的思路,如:只需枚举至x的平方根,2的倍数一定不是素数,等等。

暴力枚举是从素数下手的,相对的埃式筛法是从合数下手的。

假设m、n在0-100内,且m*n也在0-100内,那么显然m*n是100以内的一个合数。

/**
 * @description: 埃氏筛选
 * @param {*} x
 * @return {*}
 */

function primeNum (x) {
    //创建一个长度为x的空数组。
  let arr = Array(x)
    //素数计数器。
  let count = 0;

  for(let i = 2; i < arr.length; i++){
    //如果为素数,遍历剔除合数
    if(!arr[i]){
      count ++
      for(let j = i; i * j <= x; j ++){
    //将合数标记为true
        arr[i * j] = true
      }
    }
  }
   //如果return arr 的话会发现其实为101位,因为前面的遍历逻辑是按照自然数来的。
  return count;
}

解释下剔除合数的逻辑的几个疑问:

1、为什么从2开始遍历?因为1 * j会把素数也给标记为true。而2*2之前的数(即1、2、3)刚好都为素数。

2、所有合数都能剔除么?假设x为合数,那么存在m*n = x,且 m<x,n<x。而m,n一定比x先遍历。如果m和n中有素数,那么会被我们遍历到;如果m和n都是合数,且m和n中有偶数那么一定会被开始的2遍历到。现在就剩下m和n都为奇数且都为合数的情况。一个数是奇数且为合数,那么相乘等于它的数一定也都是奇数,进而存在更小的值会被先遍历到,直到遇到最小的颗粒度3,5,7,11,17这些不是合数的奇数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值