为什么我的尝试解决方案不起作用?

时间:2013-03-24 17:40:52

标签: javascript

当我在控制台中运行代码时,浏览器停止工作(假设堆栈溢出)。

我已经提出了几种不同的算法来解决这个问题,但我认为这个算法不会引起任何问题。

问题:

  

通过添加自然数来生成三角数的序列。所以第7个三角形数字是1 + 2 + 3 + 4 + 5 + 6 + 7 = 28.前十个术语是:

     

1,3,6,10,15,21,28,36,45,55,......

     

让我们列出前七个三角形数字的因子:

     

1:1

     

3:1 3

     

6:1,2,3,6

     

10:1,2,5,10

     15:1,3,5,15

     

21:1,3,7,21

     

28:1,2,4,7,14,28

     

我们可以看到28是第一个超过五个除数的三角形数。

     

第一个三角形数的值超过500个除数是多少?

解决方案失败:

function divisors(n){
    var counter = 0;
    var triangle = 3;
    var triangle_add = 2;
    while (counter < n){
        for (var i = 1; i = triangle; i++){
            if (triangle % i === 0){
                counter++;
            }
        };
        if (counter < n){
            triangle_add++;
            triangle = triangle + triangle_add;
            counter = 0;
        };
    };
    return triangle;
};

console.log(divisors(501));

1 个答案:

答案 0 :(得分:0)

您的解决方案无法正常工作,因为它很可能非常慢。通过以下方法可以更快地解决此问题:

  1. 使用Sieve of Eratosthenes查找小于某些N的所有素数(例如,N = 100'000)。这很快。
  2. 正如我们从基本数学知道的那样,每个数字都可以用 X = p1 ^ i1 * p2 ^ i2 * ... * pn ^ 的形式写成,其中pj是素数和ij是相应素数的幂。 X的除数等于(i1 + 1)*(i2 + 1)* ... *(in + 1),因为我们可以通过许多不同的方式形成一个数字X的除数。有一个素数数组,X的除数可以很快计算出来(代码仍有优化的地方):

    int divisorCount(long long X)
    {
        int c = 1;
        for (int i = 0; PRIMES[i] <= X; ++i)
        {
            int pr = PRIMES[i];
            if (X % pr == 0)
            {
                int p = 1;
                long long r = X;
                while (r % pr == 0)
                {
                    r = r / pr;
                    ++p;
                }
                c *= p;
            }
        }
        return c;
    }
    
  3. 使用上述函数迭代所有三角形数并计算它们的除数数。第i个三角形数字是 i *(i + 1)/ 2 ,因此无需保留变量,增加变量并每次添加变量。

相关问题