所以我遇到了一个问题,在我看来,我需要在另一个内部使用递归程序。我有一个4x4矩阵作为一个平面数组。一些条目将是非零,但每次都不是相同的数量。对于每个非零条目,都有一个我可以用该特定值交换的候选列表。当然,我可以为所有非零条目执行此操作。我想要非零条目的所有可能的交换组合,以递归到程序的下一级。
例如,对程序的一个级别的输入是
2 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
假设2的交换候选者是{1,3,4},那么,对于每个值,我想用该值替换2并递归到下一个级别,但首先我将申请转换,导致可能存在或多或少的非零值。
例如,当我们将2替换为3时,我们会得到(转换前后)
3 0 0 0 5 2 1 8
0 0 0 0 -> 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
并且在我们用2替换3的情况下,这是我们在下一级递归中使用的,其中5,2,1和8中的每一个都有自己的替换候选者,依此类推。
所以我很难得到的是这个;我认为我需要使用递归来尝试矩阵中非零值的所有可能交换组合,但同时,对于它们中的每一个,递归到“外部过程”的下一级。 / p>
关于如何实现这一目标的任何提示?我用C编码,但C ++也可以接受。
答案 0 :(得分:1)
听起来你想要做一些像(假的代码):
DoThing(int[,] a, int rows, int cols) {
for(int i=0;i<rows;i++) {
for(int j=0;j<cols;j++) {
if (a[i,j]>0) {
int[] replacements;
int size = GetReplacements(a[i,j], replacements);
for (int k=0;k<size;k++) {
int[rows,cols] r = CopyArray(a, rows, cols);
r[i,j]=replacements[k];
Transform(r, rows, cols);
DoThing(r, rows, cols);
}
}
}
}
}
或者如果你在同一个阵列上操作:
DoThing(int[,] a, int rows, int cols) {
for(int i=0;i<rows;i++) {
for(int j=0;j<cols;j++) {
if (a[i,j]>0) {
int[] replacements;
int size = GetReplacements(a[i,j], replacements);
for (int k=0;k<size;k++) {
a[i,j]=replacements[k];
Transform(a, rows, cols);
DoThing(a, rows, cols);
}
}
}
}
}
这将继续跟随第一个非零条目中的第一个替换及其所有相应的替换,然后再返回并在第一个字段上执行第二次替换......
编辑:另一个版本
This code (c# Console app)首先确定替换可以发生的位置以及可以在每个位置替换哪些数字,然后生成一个包含所有可能方法的数组来组合这些替换,然后遍历每个可能性,在每个位置进行替换在原始矩阵中,然后在进行下一次迭代之前在新替换的矩阵上递归。
代码很容易转换为c ++(out和ref参数将是int&amp;或int *)。
要小心,引入替代周期非常容易。该示例专门设置为最终终止,但您可以轻松创建替换周期,这将导致算法运行直到溢出,例如:1 - &gt; {2,3},2 - &gt; {1,3},3-> {0,0}将'永远'将1替换为2,然后将2替换为1,然后将1替换为2,等等。增加的MaxRecursion深度或其他一些全局保护可能有所帮助。
性能可能会得到优化,我这样做很快而且很脏。
答案 1 :(得分:0)
尝试摆脱递归:使用stack data structure,例如std::vector<>
(在C ++中)来记忆下一步做什么而不是调用递归过程。如果递归调用在过程结束时(tail recursion),这是相当简单的,如果在递归之后有代码,则需要更多的工作。
这是适用于所有递归过程的一般策略,我不是试图将它应用于给定的问题。
答案 2 :(得分:0)
递归是处理矩阵的一种简单方法,但请注意您的内存使用情况。程序的每个“级别”将跟踪所有先前的更改,仅在4或5级之后可能很重...
如果我做对了,你的算法看起来像这样:
StartProcedure:
替换Procecure:
迭代可以。但是当你在“转换”矩阵时有一个矩阵和重叠值(显然),你选择递归并复制矩阵:最后你需要多个矩阵还是你有两个矩阵的合并规则? / p>
在递归中,算法看起来像:
StartProcedure:
ReplaceProcedure:
ReplaceCandidate:
答案 3 :(得分:0)
简单(资源密集型)管理解决方案:将数组包装在结构中,以便在每个递归级别拥有不同的数组。
struct arraywrap {
int data[4][4];
};
int recurse(struct arraywarp arg);
int main(void) {
struct arraywrap flatarray = {0};
recurse(flatarray);
}