找出数字的最大因子(除了它自己)

时间:2017-08-17 08:13:11

标签: javascript algorithm for-loop math optimization

找到数字最大因子(除了自身)的最佳方法是什么?到目前为止,我有这个:

function biggestFactor(num) {
  if (num % 2 == 0) return num / 2;
  var result;
  for (var i = 1, m = Math.floor(num / 2); i < m; i++) {
    if (num % i == 0) result = i;
  }
  return result;
}

greatestFactor(1024); // 512
greatestFactor(1025); // 205
greatestFactor(1026); // 513
greatestFactor(1027); // 79

这显然效率不高。有什么其他方法可以解决这个问题?

4 个答案:

答案 0 :(得分:1)

您的要求是从&#34; num&#34;

中移除最小的素数
  • 测试2是好的,而不是从3开始到squareroot(num)
  • 你应该增加2
  • 结果为num / i,而不只是iinum的最小素数)

(首先我错了,因为我以为你在寻找最好的素数)

现在是经过测试的版本

&#13;
&#13;
function biggestFactor(num) {
  if (num % 2 == 0) return num / 2;
  var stop = Math.sqrt(num);
  for (var i = 3; i <= stop; i += 2) { // = because of prime squares
    if ((num % i) == 0) { // test if integer
      return num / i; // return of smallest prime
    }
  }
  return num; // no int or < 2
}

for (var num = 10; num < 40; num ++) {
   console.log(num + ' => ' + biggestFactor(num));
}
&#13;
&#13;
&#13;

答案 1 :(得分:0)

首先,正如此处的大量评论/帖子所示,您需要一种快速识别素数的方法。我会用C ++给你代码,但转换成JavaScript应该相对容易。

/**
 * Miller Rabin primality test
 * Returns true if n is probably prime
 * optionally, you can specify a vector of witnesses to test against
 * leave empty if you want the algorithm to randomly generate witnesses
 */
static bool isProbablePrime(ulong n, std::vector<ulong> w)
        {
            // easy
            if(n==2 || n==3 || n==5 || n==7)
            {
                return true;
            }
            if(n<10)
            {
                return false;
            }

            // write (n-1) as 2 ^ s * d
            auto d = n - 1L;
            auto s = 0L;
            while(d%2==0)
            {
                d/=2;
                s++;
            }

            // witness loop
            std::random_device rd;
            std::mt19937 gen(rd());
            std::uniform_int_distribution<ulong> dis(1, n - 1);
            bool nextWitness = false;
            for(int k=0; k<(w.empty() ? 10 : w.size()); k++)
            {
                // random base between 1 and n - 1
                auto a = w.empty() ? dis(gen) : w[k];

                // mod pow
                auto x = modpow(a, d, n);

                if(x == 1 || x == n - 1)
                {
                    continue;
                }

                // modular exponentiation with repeated squaring
                for(auto i=s-1; i>=0; i--)
                {
                    x = (x * x) % n;

                    // composite
                    if(x == 1)
                    {
                        return false;
                    }

                    if(x==n-1)
                    {
                        // the behaviour of this flag, and the break are meant to emulate a 'continue <loopname>' statement
                        nextWitness = true;
                        break;
                    }
                }
                if(!nextWitness)
                {
                    return false;
                }
                nextWitness = false;
            }

            // probably prime
            return true;
        }

现在您可以轻松编写一段生成下一个素数的代码:

static ulong nextPrime(ulong p)
        {
            p++;
            while(!isProbablePrime(p))
            {
                p++;
            }
            return p;
        }

下一步(最后)步骤是迭代从2开始的数字,当找到一个除以输入的数字时,返回相应的最大除数。

long largestDivisor(long n)
{
    long f = 2;
    while(f < sqrt(n))
    {
        if(n % f == 0)
            return n/f;
        f = nextPrime(f);
    }
    return n;
}

答案 2 :(得分:0)

我可以提出O(sqrt(N))方法,其中N是数字

function biggestFactor(num) {
  let result = 1;
  for(let i=2; i*i <=num; i++){
      if(num%i==0){
          result = num/i;
          break;
      }
  }
  console.log(result);
  return result;
}

biggestFactor(1024); // 512
biggestFactor(1025); // 205
biggestFactor(1026); // 513
biggestFactor(1027); // 79

只需遍历2到sqrt(N),

  

如果N = i *(N / i)
  那么N / i是最大的数字,所以在这一点上突破

答案 3 :(得分:0)

如果你知道这个数字不是素数,那么这应该可行。

function greatestFactor(num) {
  for (var i = 3; num%i>0; ) i+=2;
  return num/i;
}

如果最小因子很大,那么它会很慢