所以我写了这个循环,但是我无法分析它最坏的时间复杂度。非常感谢任何帮助。
因子是任意数字 primeNumber是2和素数原始值
之间的素数列表for (int i = 0; i < primeNumbers.size() - 1; i++) {
prime = primeNumbers.get(i);
if(prime<=factor) {
if (factor % prime == 0) {
factor = factor / prime;
divisors.add(prime);
i = 0;
}
if (factor <= 3)
break;
}
else
break;
}
答案 0 :(得分:2)
最糟糕的情况:
因素是素数
所以我们永远不会接受break
指令
循环体将执行primeNumbers.size()
次。
现在我们应该评估primeNumbers.size()
这是number of prime numbers below a given number = O(n/ln n)
。
让我们证明获得if (factor % prime == 0)
陈述会减少计算次数
如果我们到达那里就意味着factor = p*m
所以我们会得到O(p/ln(p) + m/ln(m))
= O((p*ln(m) + m/ln(p))/(ln(m)*ln(p)))
&lt; O((p*m)/(ln(m)*ln(p)))
&lt; O((p*m)/(ln(m) + ln(p)))
= O(p*m/ln(m*p))
= O(n/ln n)
。
因此,这样划分我们减少计算次数。
答案 1 :(得分:0)
Nikolay的回复对您提出的问题做出了最直接的回应,假设每个部门的运营都有统一的成本,这个问题具体就是除法运营数量方面的性能复杂性。但有两点意见:
1)只要素数^ 2> 1,您就可以通过停止循环来显着提高此测试的性能。因子。这样做的原因是,如果你没有在因子的平方根之下找到除数,你也不会在平方根之上找到一个除数。通过此修改,您将获得更新的性能O(sqrt(n)/ ln(sqrt(n)))= O(sqrt(n)/(sqrt(n)/ 2))= O(sqrt(n) / LN(N))。
2)在数字变得足够大以至于有趣的时候#34; (即,数字不能仅仅放入64位整数,但可以任意大),你的方法将面临一个有趣的问题:查找第n项的操作将会增长,因为在今天的大多数现有硬件上,你可能会面对所有素数的内存管理问题。你可能仍然可以适应32位整数的所有质数,因此发现所有小于64位的整数因子,但除此之外,你的方法将面临明显的麻烦。在任何情况下,一旦超过64位并开始寻找任意大整数的因素,例如Java BigInteger,即使您可以管理内存,也需要更新性能分析以考虑实际整数的大小正在考虑。尼古拉的分析很好,假设每个部门都有统一的成本。但是如果你开始使用更大数量的表示法,那么统一成本的假设就会被打破。