C++ 具有重复的给定数字组合的算法?C++;
所以我必须输入N个数字,我得到了这些数字的M个位数,我需要找到所有重复给定数字的组合 下面是一个例子: 假设N是3(我必须输入3个数字),M是4。 例如,让我们输入数字:611和533。 这应该是结果 6,6,6,6 6,6,6,11 6,6,6533 6,6,11,6 533533533533 当我知道N和M是多少时,我知道如何手动操作: 在示例中,N为3,M为4: int main() {C++ 具有重复的给定数字组合的算法?C++;,c++,algorithm,combinations,repeat,C++,Algorithm,Combinations,Repeat,所以我必须输入N个数字,我得到了这些数字的M个位数,我需要找到所有重复给定数字的组合 下面是一个例子: 假设N是3(我必须输入3个数字),M是4。 例如,让我们输入数字:611和533。 这应该是结果 6,6,6,6 6,6,6,11 6,6,6533 6,6,11,6 533533533533 当我知道N和M是多少时,我知道如何手动操作: 在示例中,N为3,M为4: int main() { int N=3; int M=4; 整数*数字=新整数[N+1]; 对于(int i=0;i>数字[
int N=3;
int M=4;
整数*数字=新整数[N+1];
对于(int i=0;i>数字[i];
对于(int a=0;a cout通常执行动态嵌套for循环的最简单方法是创建自己的堆栈并使用递归
#include <iostream>
#include <vector>
void printCombinations(int sampleCount, const std::vector<int>& options, std::vector<int>& numbersToPrint) {
if (numbersToPrint.size() == sampleCount) {
// got all the numbers we need, print them.
for (int number : numbersToPrint) {
std::cout << number << " ";
}
std::cout << "\n";
}
else {
// Add a new number, iterate over all possibilities
numbersToPrint.push_back(0);
for (int number : options) {
numbersToPrint.back() = number;
printCombinations(sampleCount, options, numbersToPrint);
}
numbersToPrint.pop_back();
}
}
void printCombinations(int sampleCount, const std::vector<int>& options) {
std::vector<int> stack;
printCombinations(sampleCount, options, stack);
}
int main()
{
printCombinations(3, {1,2,3});
}
这里有一个算法来解决这个问题,它不使用递归
#include <iostream>
#include <vector>
void printCombinations(int sampleCount, const std::vector<int>& options, std::vector<int>& numbersToPrint) {
if (numbersToPrint.size() == sampleCount) {
// got all the numbers we need, print them.
for (int number : numbersToPrint) {
std::cout << number << " ";
}
std::cout << "\n";
}
else {
// Add a new number, iterate over all possibilities
numbersToPrint.push_back(0);
for (int number : options) {
numbersToPrint.back() = number;
printCombinations(sampleCount, options, numbersToPrint);
}
numbersToPrint.pop_back();
}
}
void printCombinations(int sampleCount, const std::vector<int>& options) {
std::vector<int> stack;
printCombinations(sampleCount, options, stack);
}
int main()
{
printCombinations(3, {1,2,3});
}
我们假设n=2和m=3。考虑下面的对应于这些值的序列:
000
001
010
011
100
101
110
111
这意味着,当你看到一个0时,你取第一个数字,当你看到一个1时,你取第二个数字。因此,给定输入数字[5,7],然后000=555,001=557,010=575等等
上面的序列看起来与在基数2中表示从0到7的数字完全相同。基本上,如果从0到7并在基数2中表示数字,则具有上面的序列
如果取n=3,m=4,则需要在基数3中工作:
0000
0001
0002
0010
0011
0012
因此,你检查了从0到63(4^3-1)的所有数字,用基数3表示它们,然后按照编码:0=第一个数字,1=第二个数字,2=第三个数字,3=第四个数字
对于一般情况,从0到M^N-1,以N为基数表示每个数字,并应用编码0=第一个数字,以此类推
以下是一些示例代码:
#include <stdio.h>
#include <math.h>
void convert_to_base(int number, char result[], int base, int number_of_digits) {
for (int i = number_of_digits - 1; i >= 0; i--) {
int remainder = number % base;
number = number / base;
result[i] = '0' + remainder;
}
}
int main() {
int n = 2, m = 3;
int num = pow(n, m) - 1;
for (int i = 0; i <= num; i++) {
char str[33];
convert_to_base(i, str, n, m);
printf("%s\n", str);
}
return 0;
}
这里完全不需要递归。这是动态编程的典型工作。只需获得n=1的第一个解决方案(1个插槽可用),这意味着答案是[[6],[11],[533]]
,然后依靠之前记忆的一个解决方案逐个前进
很抱歉,我不是一个流利的C,但在JS这是解决方案。我希望它有帮助
函数组合n(a,n){
var res={};
对于(var i=1;i r.concat(a.map(n=>e.concat(n))),[])
:a.map(e=>[e]);
返回res[n];
}
var arr=[6,11533],
n=4;
控制台.log(JSON.StrugInt(COMBOSFON(ARR,N));第一个简短提示:当我们拥有RAII和更快的数据结构时,不要在C++中使用“新”或C风格的数组。
对于你的问题的解决方案,我建议你用递归来做单独的函数。你说你知道如何手工做,所以把它变成算法的第一步是一步一步地分解你的手工解。对于这个问题,当你手工解算它时,你基本上从所有第一个数字的数组开始,然后是最后一个位置n您只需循环使用可用数字。然后您转到第二个最后位置,再次循环使用可用数字,不同的是,对于每个数字,您还必须重复最后一个点数字循环。这是递归。对于每个“n”第个位置必须循环使用可用的号码,并且每次调用“n+1”第个号码的相同函数
下面是一个简化的解决方案,省去了输入处理和精确打印,以使代码更短,更关注问题:
#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;
}
#包括
#包括
无效打印组合(常量std::向量和数字、无符号大小、std::向量和线){
for(无符号i=0;i 如果(大小在输出数组中填充的位置上使用递归。继续递增最后一个位置,直到达到533。然后将其重置为6,然后向左移动,将所有533的值都转到6,直到达到一个不是533的数字;递增该值,如果现在第一个位置是533,则完成,否则返回到最后一个位置,然后停止rt结束。这项工作是典型的动态编程方法。谢谢你的回答:)但如果你有空闲时间,你能给我写一个代码吗?我过去从来没有太多使用递归,所以我真的不知道如何做…谢谢:)所以我应该使用std::vector而不是数组[]?矢量比经典的C数组更通用、更安全。在代码中,当您创建*个数字时,如果您将*个数字移动到另一个数据,并且不删除原始数组,则可能会产生内存泄漏(请参阅动态分配内存)对于数字向量,你也可以使用STD::Advector,这对使用矢量来说几乎没有好处。如果你想用新的动态分配内存,对于每一个新的使用,都应该有一个删除。我看到游戏开发是你的爱好。我在Curnncpp.com上学习了我的大部分C++,我在UnyD3D中做了几次游戏。在SFML上5-6分,我也在UnrealEngine4上做了一点工作。你能推荐我下一步应该关注什么吗?我现在在读高中(四年级三年级)我目前也在学习,从去年开始,游戏开发就是我的爱好。到目前为止,我在game maker Studio做过一些游戏,如果你刚刚开始,我完全推荐这些游戏。但正如你所说,你对unity和unreal engine有一定的经验,这两者都提供了坚实的基础。只需专注于在任何游戏机上创建游戏即可你想要的NGIN或平台,RealEnter(或者如果你足够自信的话就销售),接受反馈,改进和重复。最近我开始尝试OpenFrasWorksC++,到目前为止还不错。虽然不是专注于游戏,但它是C++所需要的。
000
001
010
011
100
101
110
111
#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;
}