给定一个素数列表和一个因数分解模式,如何构造其因数分解符合给定模式的所有数
Given a list of primes and a factorization pattern, how to construct all numbers whose prime factorization matches the given pattern?
虽然我已经试着在标题中总结了这个问题,但我认为如果我从一个问题的实例开始会更好:
素数列表= {2 3 5 7 11 13}
因子分解模式= {1 1 2 1}
- 2.3.5 ^ 2.7
- 2.3.5 ^ 2.11
- 2.3.5 ^ 2.13
- 2.3.7 ^ 2.11
- 2.3.7 ^ 2.13
- 2.3.11 ^ 2.13
- 2.5.7 ^ 2.11
- 2.5.7 ^ 2.13
- 2.7.11 ^ 2.13
- 3.5.7 ^ 2.11
- 3.5.7 ^ 2.13
- 3.5.11 ^ 2.13
- 3.7.11 ^ 2.13
- 5.7.11 ^ 2.13
#include <iostream>
#include <algorithm>
#include <vector>
#include <cmath>
using namespace std;
static const int factors[] = {2, 3, 5, 7, 11, 13};
vector<int> vFactors(factors, factors + sizeof(factors) / sizeof(factors[0]));
static const int powers[] = {1, 1, 2, 1};
vector<int> vPowers(powers, powers + sizeof(powers) / sizeof(powers[0]));
// currPIdx [in] Denotes the index of Power array from which to start generating numbers
// currFidx [in] Denotes the index of Factor array from which to start generating numbers
vector<int> getNumList(vector<int>& vPowers, vector<int>& vFactors, int currPIdx, int currFIdx)
{
vector<int> vResult;
if (currPIdx != vPowers.size() - 1)
{
for (int i = currPIdx + 1; i < vPowers.size(); ++i)
{
vector<int> vTempResult = getNumList(vPowers, vFactors, i, currFIdx + i);
vResult.insert(vResult.end(), vTempResult.begin(), vTempResult.end());
}
int multFactor = pow((float) vFactors[currFIdx], vPowers[currPIdx]);
for (int i = 0; i < vResult.size(); ++i)
vResult[i] *= multFactor;
}
else
{ // Terminating the recursive call
for (int i = currFIdx; i < vFactors.size(); ++i)
{
int element = pow((float) vFactors[i], vPowers[currPIdx]);
vResult.push_back(element);
}
}
return vResult;
}
int main()
{
vector<int> vNumList = getNumList(vPowers, vFactors, 0, 0);
cout << "List of numbers: " << endl;
for (int i = 0; i < vNumList.size(); ++i)
cout << vNumList[i] << endl;
}
当我运行上面的代码时,我得到了一个不正确的列表:
List of numbers:
66
78
650
14
22
26
我不知怎么地遇到了一个心理障碍,因为我似乎无法弄清楚如何适当地改变递归调用中的最后一个参数(我相信这是我的程序不工作的原因)!!
如果有人能够用缺失的逻辑来调整我的代码(或者甚至指出它-我不是在寻找一个完整的解决方案!),那将是非常棒的。如果您能将您的答案限制为标准c++,我将非常感激!
(如果有人注意到我遗漏了给定模式的排列,这将导致其他数字,如2.3.5.7^2等-别担心,我打算通过使用next_permutate对给定模式的所有可能排列重复此算法!)。
PS:不是作业/面试问题,只是一个非常有趣的欧拉项目问题的算法的一部分(我想你甚至可以猜到是哪个:))。
编辑:我已经自己解决了这个问题——我已经把它作为答案贴出来了。如果你喜欢它,请给它投票(我不能接受它作为答案,直到它得到比其他答案更多的投票!)…暂时忘记分解。你要解决的问题是有两个列表P和F,并找出P在P和F在F中的所有可能的配对(P, F),这意味着你会有|P| * |P|-1…* |P|-(|F|-1)可能的配对(将P中的1赋值给F的第一个元素,留下|P|-1种匹配第二个元素的可能性,等等)。您可能希望在代码中分离出问题的这一部分。如果你这样递归,最后一步是从P中选择剩下的元素到f的最后一个元素,这有帮助吗?我必须承认,我对您的代码了解不够,无法提供适合您当前状态的答案,但这就是我通常处理它的方式。
这是我自己想出来的!下面是它的代码(我希望这是不言自明的,但如果有人需要更多细节,我可以澄清):
#include <iostream>
#include <algorithm>
#include <vector>
#include <cmath>
using namespace std;
static const int factors[] = {2, 3, 5, 7, 11, 13};
vector<int> vFactors(factors, factors + sizeof(factors) / sizeof(factors[0]));
static const int powers[] = {1, 1, 2, 1};
vector<int> vPowers(powers, powers + sizeof(powers) / sizeof(powers[0]));
// idx - The index from which the rest of the factors are to be considered.
// 0 <= idx < Factors.size() - Powers.size()
// lvl - The lvl of the depth-first tree
// 0 <= lvl < Powers.size()
// lvlProd - The product till the previous level for that index.
void generateNumList
(
vector<int>& vPowers,
vector<int>& vFactors,
vector<int>& vNumList,
int idx,
int lvl,
long lvlProd
)
{
// Terminating case
if (lvl == vPowers.size() - 1)
{
long prod = pow((float) vFactors[idx], vPowers[lvl]) * lvlProd;
vNumList.push_back(prod);
}
else
{
// Recursive case
long tempLvlProd = lvlProd * pow((float) vFactors[idx], vPowers[lvl]);
for (int i = idx + 1; i < vFactors.size(); ++i)
generateNumList(vPowers, vFactors, vNumList, i, lvl + 1,
tempLvlProd);
}
}
vector<int> getNumList(vector<int>& vPowers, vector<int>& vFactors)
{
vector<int> vNumList;
for (int i = 0; i < vFactors.size(); ++i)
generateNumList(vPowers, vFactors, vNumList, i, 0, 1);
return vNumList;
}
int main()
{
vector<int> vNumList = getNumList(vPowers, vFactors);
cout << endl << "List of numbers (" << vNumList.size() << ") : " << endl;
for (int i = 0; i < vNumList.size(); ++i)
cout << vNumList[i] << endl;
}
以上代码的输出(我必须花很长时间才能在算法上消除重复条目!):
List of numbers (15) :
1050
1650
1950
3234
3822
9438
5390
6370
15730
22022
8085
9555
23595
33033
55055
real 0m0.002s
user 0m0.001s
sys 0m0.001s
- 通过递归进行因子分解
- 具有奇怪重复模板模式的派生类中的成员变量已损坏
- 有人能分解一下这个c++模板的语法吗
- 为什么在保护模式下继承升级不起作用
- 如何在全屏模式下(在OpenGL中)使背景透明
- 为什么使用__LINE_的代码在发布模式下在MSVC下编译,而不是在调试模式下
- 派生类是否可以在抽象工厂设计模式中具有数据成员
- 此模式的C++RegEx
- avrogencpp能为模式中的每种类型生成单独的头文件吗
- 使用可变模板的Broadcaster/Listener模式
- c++方法参数只能在linux的发布模式下自行更改
- 资源管理设计模式
- 使用 mod_gsoap 部署服务时,如何在 Gsoap 中更改 soap 上下文的模式?
- C++ 无法在字符数组中使用 for 循环打印字母模式
- 小字符串优化(调试与发布模式)
- C++ 乔列斯基因式分解
- 可视化C++:发布模式的运行时库作为'Multi-threaded Debug DLL'
- 如何设计具有不同类型的通知和观察器的观察者模式?
- 在模板生成器模式中分解重复的构造函数调用
- 给定一个素数列表和一个因数分解模式,如何构造其因数分解符合给定模式的所有数