简体   繁体   English

给定的质数分解遍历c ++中的所有因子而无需递归

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

I am given the prime factorization of a number p1^x1 * p2^x2 * .... in a map. 在映射中,我得到了数p1 ^ x1 * p2 ^ x2 * ....的素因式分解。 I need to iterate through all its factors, prime as well as composite. 我需要遍历所有因素,包括主要因素和综合因素。 I managed to write a solution using recursion. 我设法使用递归编写了一个解决方案。

#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 recursion\n\n";
            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;
}

Questions: 问题:

1) Is there any faster way to generate these factors? 1)有没有更快的方法来产生这些因素?

2) If possible, can I replace the recursion by a while loop? 2)如果可能,我可以用while循环替换递归吗?

  1. No . 不行 Your recursive algorithm works in exactly the same time as the number of divisors. 递归算法的工作时间与除数的数量完全相同。 Any algorithm which works asymptotically faster cannot print all these numbers. 渐近工作的任何算法都不能打印所有这些数字。

  2. Yes . 是的 Any recursive algorithm may be rewritten in a non-recursive way using the std::stack to store local variables. 可以使用std::stack以非递归方式重写任何递归算法,以存储局部变量。 But, in your case this will not probably be faster and will make the code much less readable, so such rewrite is undesirable. 但是,在您的情况下,这可能不会更快,并且会使代码的可读性大大降低,因此这种重写是不可取的。 If necessary, I can provide you code. 如有必要,我可以为您提供代码。

Without recursion, it may look like: 没有递归,它可能看起来像:

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));
}

Demo 演示版

So basically, we count from {0, 0, 0, 0} to {2, 1, 1, 2} . 因此,基本上,我们从{0, 0, 0, 0}{2, 1, 1, 2} {0, 0, 0, 0} 计数

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM