Here is the link to algorithm without comments, to see better
function getLastFactor(n) {
var tempArr = [2, 3], max = Math.sqrt(n); /* (1 + 1)
it is despised
*/
for(var i = 5; i < max; i += 2) { /*
(sqrt(n) - 5) ---> ( 5 is despised )
*/
if(n%i) continue; /*
sqrt(n) - 5 operations
PD: Should I add this? or is it already included in the for, in (sqrt(n) - 5 above) ?
*/
if(check(tempArr, i)) continue; // How do I measure this? If I do not have security of the number?
tempArr.push(i); // 1 operation it is despised
}
return tempArr[tempArr.length - 1]; // 1 operation
}
function check(array, i) {
for(var j = 0, l = array.length; j < l; ++j) { // sqrt(n) operations
var cur = array[j]; // 1 operation
if(!(i%cur)) return true; // 1 operation
}
// O(3 * sqrt(n))
我不知道到底是什么,我已经读过了,这并不重要,因为
Big O
符号将其标准化,消除了次要顺序的术语。但我有很多疑问,比如我在代码中留下的一些疑问,还有:1)我应该计算依赖于条件的操作吗?,假设我有一个条件,如果你评价为真的话,一个周期会增加n个操作的效率,这应该考虑到,因为它会带来很大的变化。
2)我认为这个代码的效率是
O (sqrt (n) * 3)
,对吗?这个问题并不是另一个问题的重复,我在网络上,特别是这个社区读了很多,几乎所有的问题/答案都是基于理论的,几乎从来没有同时看到过理论和实践的例子。
最佳答案
首先,当使用big-o表示法时,删除所有常量,因此O (sqrt (n) * 3)
实际上是O (sqrt (n))
。
为了正确分析这个代码的渐近复杂性,我们需要一些理论上的背景。该算法的基本功能是确定n
的主因子(只返回最大值)。程序的主要部分是一个循环,循环遍历从for
到5
的所有奇数,因此迭代次数是sqrt(n)
,或者用big-o术语来说是(sqrt(n) - 5) / 2
。
接下来,有一个语句O(sqrt(n))
可以消除所有不是if(n%i) continue;
除数的数字(不管它们是否是素数)。因此,只有当n
是i
的除数时,才会执行其余代码。Asymptotic bound for number of divisors是指n
。
最后,有一个函数O(n^{1 / ln(ln(n))})
在数组check
上迭代,该数组包含迄今为止发现的tempArr
的素因子一个正整数n
有多少素数因子Asymptotic bound for number of prime divisors是最坏的情况(当n
被称为primorial number)n
时。
现在我们来总结一下。即使我们假设O(ln(n) / ln(ln(n)))
是初等,并且所有素数因子都很快找到(所以n
具有最大可能值),后部分码的渐近复杂度为array.length
。这不是很容易看到,但是这个增长比if(n%i) continue;
慢,所以总的复杂性是O(n^{1 / ln(ln(n))} * ln(n) / ln(ln(n)))
。
关于algorithm - 我的算法中对大O符号的测量是否正确?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48910333/