我正在尝试这个但是在输入> 10000这个循环id需要更多时间。
是否有任何方法可以优化它,其时间复杂度小于N或(logn)?
#include <iostream>
using namespace std;
int main(int argc, char* argv[]) {
int n = 10001;
for (int i = 1; i < n; i++) {
if (n % i == 0) {
cout << i;
}
}
return 0;
}
答案 0 :(得分:2)
除dmh2000's answer之外:您可以在检查中利用冗余。例如,如果某个数字不能被n
整除,则它也不能被n
的任何倍数整除。例如,不能被2整除的数字也不能除以4,6或8。
此技术称为sieving。
答案 1 :(得分:1)
你可以迭代到n的平方根而不是n,因为大于平方根的任何东西都不能是n的因子。编辑:阅读ComicSansMs答案比我的编辑更好
答案 2 :(得分:1)
第一步是找出所有主要因素及其多样性。然后,您可以轻松生成因子。
如果您明智地做到这一点,那么找到主要因素的平均速度相当快,大约达到1亿。如果您找到一个因子,则可以将其除以n
,这样可以大大减少一般情况下的时间。此外,除了2:
// I assume n is non-zero
while (!(n & 1)) {
cout << "2" << endl;
n /= 2;
}
for (unsigned int factor = 3; factor * factor <= n; factor += 2) {
while (n % factor == 0) {
cout << factor << endl;
n /= factor;
}
if (n != 1)
cout << n << endl;
}
答案 3 :(得分:0)
如果你需要多次执行,有一个很好的解决方案。我只举一个例子,实施将是你的事。
让我们说你需要将两个数字分解,例如580和72。
首先,您将其分解为素数
580 = 2 x 2 x 5 x 29
72 = 2 x 2 x 2 x 3 x 3
使用缓存可以大大提高分解为素数的速度。您应该std::set<int>
包含所有已知素数,因此在对580
进行分解后,它包含2, 5, 29
。这意味着要对72
进行分解,您只需要确定3
是素数。
在获得所有素数因子之后,您需要将它们在所有组合中相乘以获得非素因子。
正如我所提到的,这个解决方案非常好,只要你需要对很多数字进行分解,但是如果只需要分解一次,那么Sieving会更好。