找到数字最大因子(除了自身)的最佳方法是什么?到目前为止,我有这个:
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
这显然效率不高。有什么其他方法可以解决这个问题?
答案 0 :(得分:1)
您的要求是从&#34; num&#34;
中移除最小的素数num / i
,而不只是i
(i
是num
的最小素数)(首先我错了,因为我以为你在寻找最好的素数)
现在是经过测试的版本
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;
答案 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;
}
如果最小因子很大,那么它会很慢