【问题标题】:finding sum of prime numbers under 250求250以下的素数之和
【发布时间】:2012-02-26 16:10:55
【问题描述】:
var sum = 0

for (i = 0; i < 250; i++) {

    function checkIfPrime() {

        for (factor = 2; factor < i; factor++) {
            if (i % factor = 0) {
                sum = sum;
            }
            else {
                sum += factor;
            }
        }
    }
}

document.write(sum);

我正在尝试检查 250 以下的所有质数的总和。我收到一条错误消息,指出我在声明 if (i % factor = 0) 中无效我知道是在原始 for 声明中创建的,但有什么办法在 if 语句中引用它?

【问题讨论】:

  • 你需要使用双等号:(i % factor == 0)
  • 你如何计算任何东西?您只需创建 checkIfPrime 函数 250 次,然后从不调用它。
  • +1 表示@dfsq。是的,算法没有意义。

标签: javascript primes


【解决方案1】:

i % factor === 0

使用=== 进行比较。 = 用于分配。是的,我说 triple 等于。类型强制很烦人。

【讨论】:

  • JavaScript 支持相等函数,当给定两个不相等类型的事物时,它会尝试以不明显的方式强制它们。三等号没有强制,所以它更容易理解,并且可能会做人们通常期望的事情。例如(0 == "") 在 JavaScript 中计算为真!
【解决方案2】:

您需要=====if (i % factor == 0)

【讨论】:

    【解决方案3】:

    对于素数计算,您是否考虑过使用Sieve of Eratosthenes?这是一种更优雅的确定素数的方法,并且对结果求和也很简单。

    var sieve = new Array();
    var maxcount = 250;
    var maxsieve = 10000;
    
    // Build the Sieve, marking all numbers as possible prime.
    for (var i = 2; i < maxsieve; i++)
        sieve[i] = 1;
    
    // Use the Sieve to find primes and count them as they are found.
    var primes = [ ];
    var sum = 0;
    for (var prime = 2; prime < maxsieve && primes.length < maxcount; prime++)
    {
        if (!sieve[prime]) continue;
        primes.push(prime); // found a prime, save it
        sum += prime;
        for (var i = prime * 2; i < maxsieve; i += prime)
            sieve[i] = 0; // mark all multiples as non prime
    }
    
    document.getElementById("result").value =
          "primes: " + primes.join(" ") + "\n"
        + "count: " + primes.length + "\n"
        + "sum: " + sum + "\n";
    #result {
        width:100%;
        height:180px
    }
    <textarea id="result">
    </textarea>

    (编辑)使用更新的算法,现在涉及两个最大值:

    • maxcount 是您希望找到的最大素数个数
    • maxsieve 是一个足以包含 maxcount 个素数的筛子的猜测

    您必须通过实际检查真正的 count 来验证这一点,因为有两个终止条件(1)我们达到了筛子的极限并且找不到更多的素数,或者(2)我们实际上找到了我们正在寻找的东西。

    如果您将数字增加到远大于 250 的数字,那么 Sieve 将不再可行,因为它会消耗大量内存。无论如何,我认为这一切都是有道理的,对吧?在这一点上,你真的需要自己玩筛子,而不是依赖我对它的解释。

    【讨论】:

    • 非常感谢。如果我想说出前 250 个素数的总和而不是 250 以下的素数,它将如何影响代码?我无法删除所有 0 值并循环直到 array.length 为 250,因为这会弄乱位置的值。嗯
    • Nic,根据您的新问题,我重新编写了 JavaScript 以显示新答案。但是,如果将 maxsieve 设置回 250,原始答案的本质仍然存在。
    【解决方案4】:

    你同样可以使用这个

    let sum = 0;
    let num = 250;
    
    
    for (let i = 2; i < num; i++) {
      let isPrime = true;
      
      for (let j = 2; j < i; j++) {
        if (i % j === 0) {
          isPrime = false;
        }
      }
      
      if (isPrime) {
        sum += i;
      }
    }
    
    console.log(sum);

    【讨论】:

      【解决方案5】:

      所以我不得不面对类似的挑战,这是我的解决方案,希望对您有所帮助:

       function sumPrimes(num) {
      
            // determine if a number is prime
            function isPrime(n) {
              if (n === 2) return true;
              if (n === 3) return true;
              if (n % 2 === 0) return false;
              if (n % 3 === 0) return false;
      
              var  i = 5;
              var  w = 2;
              while (i * i <= n) {
                  if (n % i === 0) {
                      return false;
                  }
                  i += w;
                  w = 6 - w;
              }
              return true;
            }
      
            // subtract 1 for 'not being prime' in my context
            var sum = isPrime(num) ? num - 1 : -1;
      
            for (var x = 0; x < num; x++) {
              if (isPrime(x) === true) {
                sum += x;
              }
            }
      
            return sum;
          }
      

      【讨论】:

        【解决方案6】:

        这是一个相当不错的方法。它不像筛子那么先进,但它是一个不错的起点。注意:我使用的是 ES6 语法。

         /*
         * Sum the first n prime numbers
         *
         * @param n (integer)
         * @return integer 
         *
         */
        function sumNprimes(n){
          const arr = [];
          let i = 2
        
          while (arr.length < n) {
            if (isPrime(i)) {
              arr.push(i)
            }
            i++
          } 
          return arr.reduce( (x,y) => x+y );
        
          /*
          * @param n (integer)
          * @return Boolean
          *
          */
          function isPrime(n) {
        
            if ( n < 2 ) {
              return false
            }
        
            for ( let i = 2; i <= Math.sqrt(n); i++ ) {
              if ( n % i === 0 ) {
                  return false;
              } 
            }
            return true
          }
        
        }
        

        【讨论】:

          【解决方案7】:

          按照“Sieve of Eratosthenes”,我已经用JS实现了代码:

          function isPrime(n){
            return ((n/2 === 1 || n/3 === 1 || n/5 === 1 || n/7 === 1)?true:(n%2===0 || n%3 === 0 || n%5 ===0 || n%7 === 0)?false:true);
          };
          
          var val = 250;
          
          let outArr = [];
          for(let i=2;i<val;i++){
            if(isPrime(i)){
              outArr.push(i);
            }  
          }
          console.log("Prime number between 0 - "+val+" : "+outArr.join(","));

          【讨论】:

            【解决方案8】:

            这是一个简单的遍历数组并实现埃拉托色尼筛子的方法......

            function sumPrimes(num) {
              var t, v = [],
                w = [],
                x = [],
                y = [],
                z = 0;
              //enumerating Vee array starts at 2 as first prime number
              for (let a = 2; a <= num; a++) {
                v.push(a)
              }
              //creating a moving loop by splicing its first index
              for (let i = 0; i < v.length; i) { //ensure all items spliced 
                t = v[i]; // t as prime to be removed from Vee array 
                x.push(t); // x storage of primes
                z += t //  total of peculiar primes
                w.push(v.splice(i, 1)) //tested to move all one by one
                // prompt(v) //tested that v loses its v[i] every iteration
                //= now trying to remove others using remainder (%) vs prime t
                for (let vi in v) {
                  v[vi] % t === 0 ? y.push(v.splice(vi, 1)) : ""; //recursive removal of composite items by prime t
                }
              }
              return z // returns sum of primes
            }
            sumPrimes(250);

            您生成以 2 开头的数组作为第一个素数, 您使用 % === 0 筛选数组以删除素数的剩余部分。 您通过使用下一个素数循环遍历剩余的数组,直到最后一个剩余的素数被推入素数数组。将所有素数相加得到总和。

            【讨论】:

              【解决方案9】:

              如果问题纯粹是学术问题,那么更早的答案更适合。

              下面的示例使用现代库,以防您需要高效而优雅的解决方案。

              import {generatePrimes} from 'prime-lib';
              import {from, reduce, takeWhile} from 'rxjs';
              
              from(generatePrimes())
                  .pipe(takeWhile(p => p < 250), reduce((a, c) => a + c))
                  .subscribe(sum => {
                      // sum = 5830
                  });
              

              就性能而言,所需时间明显少于 1 毫秒。

              如果我想说的是前 250 个素数的总和而不是 250 以下的素数,它将如何影响代码?

              您只需将takeWhile(p =&gt; p &lt; 250) 替换为take(250)

              import {generatePrimes} from 'prime-lib';
              import {from, reduce, take} from 'rxjs';
              
              from(generatePrimes())
                  .pipe(take(250), reduce((a, c) => a + c))
                  .subscribe(sum => {
                      // sum = 182109
                  });
              

              附:我是prime-lib的作者。

              【讨论】:

                猜你喜欢
                • 2015-07-08
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2013-05-15
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多