如何找到给定数N的所有因子,时间复杂度小于N?

时间:2014-07-31 14:28:18

标签: c++ factors

我正在尝试这个但是在输入> 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;
}

4 个答案:

答案 0 :(得分:2)

dmh2000's answer之外:您可以在检查中利用冗余。例如,如果某个数字不能被n整除,则它也不能被n的任何倍数整除。例如,不能被2整除的数字也不能除以4,6或8。

此技术称为sieving

答案 1 :(得分:1)

你可以迭代到n的平方根而不是n,因为大于平方根的任何东西都不能是n的因子。编辑:阅读ComicSansMs答案比我的编辑更好

答案 2 :(得分:1)

第一步是找出所有主要因素及其多样性。然后,您可以轻松生成因子。

如果您明智地做到这一点,那么找到主要因素的平均速度相当快,大约达到1亿。如果您找到一个因子,则可以将其除以n,这样可以大大减少一般情况下的时间。此外,除了2:

之外,您只需要检查多达sqrt(n)的奇数因子
// 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会更好。