[英]Find the greatest factor of a number (other than itself)
What is an optimal way to find the greatest factor of a number (other than itself)? 找到一个数的最大因数(本身除外)的最佳方法是什么? So far, I've got this: 到目前为止,我已经知道了:
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
This is obviously not so efficient. 这显然不是那么有效。 What are other ways to solve this? 还有什么其他方法可以解决这个问题?
Your requirement is to remove the smallest prime from "num" 您的要求是从“ num”中删除最小的素数
num / i
, not just i
( i
is the smallest prime of num
) 结果是num / i
,而不仅仅是i
( i
是num
的最小素数) (First I was wrong because I thought you are looking for the greatest prime) (首先我错了,因为我以为你正在寻找最好的素数)
Now a tested version 现在是经过测试的版本
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)); }
First, as indicated by a lot of comments/posts here, you need a fast way of identifying prime numbers. 首先,正如此处的许多评论/帖子所表明的那样,您需要一种识别素数的快速方法。 I'll give you the code in C++, but it should be relatively easy to convert to JavaScript. 我将为您提供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;
}
Now you can easily write a piece of code that generates the next prime number: 现在,您可以轻松编写一段代码来生成下一个质数:
static ulong nextPrime(ulong p)
{
p++;
while(!isProbablePrime(p))
{
p++;
}
return p;
}
Next (final) step is to iterate over numbers starting at 2, and when a number is found that divides the input, return the corresponding largest divisor. 下一步(最后一个步骤)是迭代从2开始的数字,当找到一个将输入除以数字时,返回相应的最大除数。
long largestDivisor(long n)
{
long f = 2;
while(f < sqrt(n))
{
if(n % f == 0)
return n/f;
f = nextPrime(f);
}
return n;
}
I can propose a O(sqrt(N)) approach where N is the number 我可以提出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
Just traverse through 2 to sqrt(N), 只需遍历2到sqrt(N),
if N = i*(N/i) 如果N = i *(N / i)
then N/i is the biggest number possible, so break at this point 那么N / i是最大的数字,所以在这一点上休息
If you know the number is not a prime or even then this should work. 如果您知道该数字不是素数,那么应该可以。
function greatestFactor(num) {
for (var i = 3; num%i>0; ) i+=2;
return num/i;
}
It will be slow if the smallest factor is large though 如果最小的因素很大,那将会很慢
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.