给定一个数的质因数分解,在c++中不递归地遍历所有因子

given prime factorization of a number iterate through all factors in c++ without recursion

本文关键字:递归 c++ 遍历 一个 分解 质因数      更新时间:2023-10-16

给定一个数字p1^x1 * p2^x2 * ....的质因数分解在地图上。我需要遍历它的所有因子,质数和合数。我设法用递归写了一个解决方案。

#include <iostream>
#include <map>
#include <cstdlib>
using namespace std;
struct PROBLEM {
    int mx = 400;
    map<int, int> mp = {{2, 2}, {3, 1},  {5, 1}, {7, 2}};
    int lastPrimeFactor = 7;
    int num = 1;
    auto solve() {
        rec(2, 0);
        return 0;
    }
    int next_prime_factor(int p) {
        return (p == 2) ? 3 : (p == 3) ? 5 : (p == 5) ? 7 : -1;
    }
    void rec(int prime, int power) {
        if (mx == 0) {
            cout << "Infinite recursionnn";
            exit(0);
        } else --mx;
        if (prime == lastPrimeFactor && power > mp[prime]) {
            return;
        }
        if (power < mp[prime]) {
            num *= prime;
            cout << num << endl;
            rec(prime,  power + 1);
            num /= prime;
        }
        if (prime != lastPrimeFactor) {
            rec(next_prime_factor(prime),  0);
        }
    }
};

int main() {
    PROBLEM().solve();
    return 0;
}

问题:

1)是否有更快的方法来产生这些因子?

2)如果可能的话,我可以用while循环代替递归吗?

    没有
  1. 。你的递归算法和除数运算的时间是一样的。

  2. 任何渐进更快的算法都无法打印出所有这些数字。
  3. 。任何递归算法都可以用非递归的方式重写,使用std::stack来存储局部变量。但是,在您的情况下,这样做可能不会更快,而且会使代码的可读性大大降低,所以这样的重写是不可取的。如果需要,我可以提供代码给你。

如果没有递归,它可能看起来像:

bool increase(const std::vector<std::pair<std::size_t, std::size_t>>& v,
              std::vector<std::size_t>& it)
{
    for (std::size_t i = 0, size = it.size(); i != size; ++i) {
        const std::size_t index = size - 1 - i;
        ++it[index];
        if (it[index] > v[index].second) {
            it[index] = 0;
        } else {
            return true;
        }
    }
    return false;
}
std::size_t pow(std::size_t n, std::size_t power)
{
    std::size_t res = 1;
    for (std::size_t i = 0; i != power; ++i) {
        res *= n;
    }
    return res;
}
void do_job(const std::vector<std::pair<std::size_t, std::size_t>>& v,
            std::vector<std::size_t> it)
{
    std::size_t res = 1;
    for (std::size_t i = 0; i != v.size(); ++i) {
        res *= pow(v[i].first, it[i]);         
    }
    std::cout << res << std::endl; 
}
void iterate(const std::vector<std::pair<std::size_t, std::size_t>>& v)
{
    std::vector<std::size_t> it(v.size(), 0);
    do {
        do_job(v, it);
    } while (increase(v, it));
}

演示

基本上,我们把{0, 0, 0, 0}算到{2, 1, 1, 2}