[英]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循环替换递归吗?
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.
渐近工作的任何算法都不能打印所有这些数字。
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));
}
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.