例如,16可以用这些方式表达:
2 * 2 * 2 * 2
4 * 2 * 2
4 * 4
8 * 2
(不包括琐碎的案例1 * 16)
36:
2 * 2 * 3 * 3
2 * 2 * 9
2个* 18个
4 * 3 * 3
12个* 3个
4 * 9
因此,我需要像上面一样找到任何给定数字的所有表示 首先,我能够用下面的代码提出给定数字的所有除数:
void FindDivisors(int n)
{
vector<int> my_vector;
for (int i = 2; i < n/2 + 1; i++)
{
if (n % i == 0)
my_vector.push_back(i); //store divisors in a vector.
}
}
在此之后,我被卡住了。我如何从所有除数中得到所有想要的因子? 我可以想到一个似乎有效的递归方法,但不知道如何实现它:
以16为例。让我们命名函数来找到n的所有表示为“因子(n)”。所有16的非平凡除数都是{2,4,8}。我们将每个除数除以16得到{8,4,2}。然后因子(16)= 2 *因子(8),4 *因子(4)和8 *因子(8)的并集。但是,就我而言。我是递归的新手,不知道这条路线是否成功。我需要一些关于如何把事情放在一起的帮助。
答案 0 :(得分:4)
只要您不知道因素的数量,最有效的解决方案就是递归。
您需要一个向量来存储当前路径:
vector<int> path; // it will store all current factors
和递归函数。
对于每次迭代,您尝试划分当前余数并记住:
void OutputRec(int value)
{
if (value == 1) // We have divided the whole number
{
for (int i = 0; i < path.size(); i++) cout << path[i] << " ";
cout << endl;
return;
}
for (int i = value; i > 1; i--)
{
if (value % i == 0) { // if it is divisible
path.push_back(i); // add to path
OutputRec(i, value / i); // continue working
path.pop_back(); // remove from path
}
}
}
void Output(int value)
{
cout << "Result for " << value << ": " << endl;
path = vector<int>();
OutputRec(value);
}
int main() {
Output(4);
Output(16);
Output(36);
Output(256);
return 0;
}
例如,我们有8.这是它的工作原理:
OutputRec(8), path = []:
i = 8: divisible (8 / 1 = 1)
OutputRec(1), path = [8], value == 1 > output "8".
i = 7, 6, 5: not divisible
i = 4: divisible (8 / 4 = 2)
OutputRec(2), path = [4]:
i2 = 2: divisible (2 / 2 = 1)
OutputRec(1), path = [4 2], value == 1 > output "4 2".
i = 3: not divisible
i = 2: divisible (8 / 2 = 4)
OutputRec(4), path = [2]:
i3 = 4: divisible (4 / 4 = 1)
OutputRec(1), path = [2 4], value == 1 > output "2 4".
i3 = 3: not divisible
i3 = 2: divisible (4 / 2 = 2)
OutputRec(2), path = [2 2]:
i4 = 2: divisible (2 / 2 = 1)
OutputRec(1), path = [2 2 2], value == 1 > output "2 2 2"
<强>结果:
8,
4 * 2,
2 * 4,
2 * 2 * 2
现在,您看到了问题:[2 4]和[4 2]是重复的答案。我们怎样才能避免重复答案?最简单的方法是仅按升序(降序,无关紧要)顺序输出值。
让我们添加max
变量并存储插入到路径中的最后一个数字,并找到那些小于或等于它的分频器。
例如,如果当前路径为[2],则递归不应该[2 4],但应该为[2 2]。 max
的初始值等于value
,因为路径中的第一个数字可以是任意数字。
void OutputRec(int max, int value)
{
if (value == 1) {
for (int i = 0; i < path.size(); i++) cout << path[i] << " ";
if (path.size() == 1) cout << "1";
cout << endl;
return;
}
for (int i = max; i > 1; i--) // loop from max. Min(max, value) would be better
{
if (value % i == 0) {
path.push_back(i);
OutputRec(i, value / i);
path.pop_back();
}
}
}
void Output(int value)
{
cout << "Result for " << value << ": " << endl;
path = vector<int>();
OutputRec(value, value);
}
以下是它现在的工作原理:
OutputRec(8), path = []:
i = 8: divisible (8 / 8 = 1)
OutputRec(1), path = [8], value == 1 > output "8".
i = 7, 6, 5: not divisible
i = 4: divisible (8 / 4 = 2)
OutputRec(2), path = [4]:
i2 = 2: divisible
OutputRec(1), path = [4 2], value == 1 > output "4 2".
i = 3: not divisible
i = 2: divisible (8 / 2 = 4)
OutputRec(4), path = [2]:
// notice i3 starts from 2, because last inserted is 2
i3 = 2: divisible (4 / 2 = 2)
OutputRec(2), path = [2 2]:
i4 = 2: divisible (2 / 2 = 1)
OutputRec(1), path = [2 2 2], value == 1 > output "2 2 2"
<强>结果:
8,
4 * 2,
2 * 2 * 2
一切正常!唯一看起来不正确的是&#34; 8&#34;。它应该是&#34; 8 * 1&#34;。您可以在输出中添加if (path.size() == 1) cout << "1";
之类的行。
<强>结果:
8 * 1,
4 * 2,
2 * 2 * 2
我希望我没有让你更加困惑。第一次解释什么是递归真的很难。 递归就像游泳或骑自行车 - 首先看起来很难。然后,你尝试并学习它,一旦你理解它 - 你会想知道为什么你以前不能这样做:)祝你好运。