所以我N - 我必须输入的数字,我得到M - 这些数字的位数,我需要找到重复给定数字的所有组合。
以下是示例:
假设N是3(我必须输入3个数字),M是4。 例如,让我们输入数字:6 11和533。 这应该是结果
6,6,6,6
6,6,6,11
6,6,6,533
6,6,11,6
...
533533533533
当我知道N和M有多少时,我知道如何做到这一点:
在N为3且M为4的示例中:
int main() {
int N = 3;
int M = 4;
int *numbers = new int[N + 1];
for (int i = 0; i < N; i++)
cin >> numbers[i];
for (int a = 0; a < N; a++)
for (int b = 0; b < N; b++)
for (int c = 0; c < N; c++)
for (int d = 0; d < N; d++)
{
cout << numbers[a] << " " << numbers[b] << " " << numbers[c] << " " << numbers[d] << endl;
}
return 0;
}
但是我如何制作算法以便我可以通过std :: cin输入N和M并且我得到正确的结果?
感谢。
答案 0 :(得分:2)
这里完全不需要递归。这是动态编程的典型工作。只需获得n = 1的第一个解决方案(1个插槽可用),这意味着答案为[[6],[11],[533]]
,然后依靠先前记忆的解决方案逐个移动。
很抱歉,我不熟悉C,但在JS中这是解决方案。我希望它有所帮助。
function combosOfN(a,n){
var res = {};
for(var i = 1; i <= n; i++) res[i] = res[i-1] ? res[i-1].reduce((r,e) => r.concat(a.map(n => e.concat(n))),[])
: a.map(e => [e]);
return res[n];
}
var arr = [6,11,533],
n = 4;
console.log(JSON.stringify(combosOfN(arr,n)));
&#13;
答案 1 :(得分:1)
第一个简短提示:不要使用&#34; new&#34;当我们拥有RAII和更快的数据结构时,或者使用C ++中的C风格数组。
对于你的问题的解决方案,我建议使用递归来创建单独的函数。你说你知道如何手动完成它所以将其纳入算法的第一步就是逐步拆除你的手动解决方案。对于这个问题,当你手动解决它时,你基本上从所有第一个数字的数组开始,然后在最后一个位置,你只需循环通过可用的数字。然后你转到倒数第二个位置,然后再次循环显示可用的数字,区别在于每个数字都必须重复最后一个点数循环。这是递归。对于每个&#34; n&#34;这个位置你必须循环通过可用的数字,并且对于每个呼叫都有相同的功能用于&#34; n + 1&#34;这个数字。
这是一个简化的解决方案,省略了输入处理和精确打印,以使代码更短,更专注于问题:
#include <vector>
#include <iostream>
void printCombinations(const std::vector<int>& numbers, unsigned size, std::vector<int>& line) {
for (unsigned i = 0; i < numbers.size(); i++) {
line.push_back(numbers[i]);
if (size <= 1) { // Condition that prevents infinite loop in recursion
for (const auto& j : line)
std::cout << j << ","; // Simplified print to keep code shorter
std::cout << std::endl;
line.erase(line.end() - 1);
} else {
printCombinations(numbers, size - 1, line); // Recursion happens here
line.erase(line.end() - 1);
}
}
}
int main() {
std::vector<int> numbers = {6, 11, 533};
unsigned size = 4;
std::vector<int> line;
printCombinations(numbers, size, line);
return 0;
}
如果您有任何问题,请随时提出。