我讨厌在这里发布作业帮助,但我已经筋疲力尽了。在C语言中编写一个简单的递归函数时,我遇到了Stack Overflow(至少那是Java中所称的)问题。
我需要n个数的每个r-排列,并且我认为最好的方法是将基数n计算为长度r。
对于少量数字,它可以正常工作,但最高情况(n = 10,r = 6)最终会耗尽内存。我可以很容易地迭代地编写它,但它需要递归。这是我到目前为止所拥有的:
int permute(int *tempArray, int amtNums, int goalLength, int totalMatches) {
totalMatches += 1; //Temporary, will be replaced by a function later
printArray(tempArray, goalLength);
tempArray[0]++;
int j = 0;
while(tempArray[j] >= amtNums) {
tempArray[j+1]++;
tempArray[j] = 0;
j++;
}
if(j+1 > goalLength) return totalMatches;
return permute(tempArray, amtNums, goalLength, totalMatches);
}
对于最大情况被称为permute((int*)calloc(numSlots, sizeof(int)), 10, 6, 0);
,n = 10 r = 6
我应该注意:计数并不完全直观,它有点倒退,但会产生我想要的所有数字组合。例如:n = 4,r = 3
0 0 0
1 0 0
2 0 0
3 0 0
0 1 0
1 1 0
2 1 0
3 1 0
.....
0 2 3
1 2 3
2 2 3
3 2 3
0 3 3
1 3 3
2 3 3
3 3 3
答案 0 :(得分:1)
我相信您必须修改递归函数才能获得goalLength
函数调用堆栈的最大深度。您可以像我在这里一样添加参数depth
:
int permute( int *tempArray, int amtNums, int goalLength, int depth, int totalMatches) {
int i;
if ( depth < goalLength - 1) {
for ( i = 0; i < amtNums; ++i ) {
tempArray[depth] = i;
totalMatches = permute(tempArray, amtNums, goalLength, depth + 1, totalMatches);
}
} else {
for ( i = 0; i < amtNums; ++i ) {
tempArray[depth] = i;
printArray(tempArray, goalLength);
++totalMatches;
}
}
return totalMatches;
}
您当然可以重写它,将for
循环放在外面,if
放在里面。我用这个小测试程序尝试了这个代码:
#include <stdio.h>
#define NDIGIT 4
#define NLENGTH 3
void printArray( int *temp, int size ) {
int i;
for ( i = 0; i < size; ++i ) {
printf("%d ", temp[i]);
}
printf("\n");
}
int permute( int *tempArray, int amtNums, int goalLength, int depth, int totalMatches);
int main(void) {
int results[NLENGTH];
int n = permute(results, NDIGIT, NLENGTH, 0, 0);
printf("Total number of permutations: %d\n", n);
return 0;
}
将NDIGIT
设置为10
,将NLENGTH
设置为6
并注释掉打印功能(如果您需要,可以保留...)程序正常运行输出是:
Total number of permutations: 1000000
答案 1 :(得分:0)
你的函数使用对自身的尾调用,编译器应该能够将这种递归转换为循环。使用命令行选项-O3
或IDE提供的任何内容启用优化。如果编译器实现递归,则函数将递归 amtNums goalLength ,这是n = 10且r = 6的大数字: 1 000 000 递归级别可能导致 Stack Overflow