阅读了几篇文章之后,我仍然对排列和递归函数感到难过。我试图在不等长的2D数组中创建所有可能的3个字母排列,其中第一个字母来自集合{'l','m','n'},第二个字母来自集合{'q ','r'}和第三个字母来自集合{'a','e','i','o'}。我的代码经过了正确的排列模式,但没有打印出正确的输出。例如,如果前8个排列应该是:
lqa
lqe
lqi
lqo
lra
lre
lri
lro
我的代码打印出来:
lqa
e
i
o
ra
e
i
o
关于问题是什么的任何想法?以下是我的代码的相关部分:
rec(character_pools,0,3);
void rec(char** pool, int k, int j)
{
if(k==j)
{
printf("\n");
return;
}
int i,len=strlen(pool[k]);
for (i=0;i<len;i++)
{
printf("%c",pool[k][i]);
rec(pool,k+1,j);
}
}
答案 0 :(得分:1)
调用堆栈:
rec(pool, 0, 3);
-> 'l' rec(pool, 1, 3);
-> 'q' rec(pool, 2, 3);
-> 'a' rec(pool, 3, 3);
-> '\n'
-> 'e' rec(pool, 3, 3);
-> '\n'
-> 'i' rec(pool, 3, 3);
-> '\n'
-> ...
-> ...
-> ...
<强>更新强>
不像递归一样。但是......工作:)。希望这有帮助。
假设最大长度为10.
#include <stdio.h>
#include <string.h>
#define ALL_DONE 1
#define NOT_YET 0
int rec(char (*pool)[10], int num, int start);
int main(void)
{
int i, num;
char pool[20][10];
scanf("%d", &num);
for (i = 0; i < num; i++){
scanf("%s", pool[i]);
}
while ( !rec(pool, num, 0) ); // keepint calling until all permutations are printed
return 0;
}
int rec(char (*pool)[10], int num, int start)
{
static int ndx[20] = {0}; // record the index of each string
if (start == num){
printf("\n");
return ALL_DONE;
}
printf("%c", pool[start][ndx[start]]);
if ( rec(pool, num, start+1) == ALL_DONE ){
ndx[start+1] = 0;
ndx[start]++;
if (ndx[start] == strlen(pool[start])){
return ALL_DONE;
return NOT_YET;
}
return NOT_YET;
}
解释:
rec(pool, 0, 0)[1st calling]
-> 'l' rec(pool, 1, 0) | ndx[0..2] = 0, 0, 0
-> 'q' rec(pool, 2, 0) | ndx[0..2] = 0, 0, 0
-> 'a' rec(pool, 3, 0) | ndx[0..2] = 0, 0, 0
-> '\n' retrun ALL_DONE | ndx[0..2] = 0, 0, 0
-> return NOT_YET | ndx[0..2] = 0, 0, 1
-> return NOT_YET | ndx[0..2] = 0, 0, 1
-> return NOT_YET | ndx[0..2] = 0, 0, 1
|
rec(pool, 0, 0)[2nd]
-> 'l' rec(pool, 1, 0) | ndx[0..2] = 0, 0, 1
-> 'q' rec(pool, 2, 0) | ndx[0..2] = 0, 0, 1
-> 'e' rec(pool, 3, 0) | ndx[0..2] = 0, 0, 1
-> '\n' return ALL_DONE | ndx[0..2] = 0, 0, 1
-> return NOT_YET | ndx[0..2] = 0, 0, 2
-> return NOT_YET | ndx[0..2] = 0, 0, 2
-> return NOT_YET | ndx[0..2] = 0, 0, 2
|
| ...
|
rec(pool, 0, 0)[4th]
-> 'l' rec(pool, 1, 0) | ndx[0..2] = 0, 0, 3
-> 'q' rec(pool, 2, 0) | ndx[0..2] = 0, 0, 3
-> 'o' rec(pool, 3, 0) | ndx[0..2] = 0, 0, 3
-> '\n' return ALL_DONE | ndx[0..2] = 0, 0, 3
-> return ALL_DONE | ndx[0..2] = 0, 0, 4
-> return NOT_YET | ndx[0..2] = 0, 1, 0
-> return NOT_YET | ndx[0..2] = 0, 1, 0
|
| ...
| ...
|
rec(pool, 0, 0)[5th]
-> 'l' rec(pool, 1, 0) | ndx[0..2] = 0, 1, 0
-> 'r' rec(pool, 2, 0) | ndx[0..2] = 0, 1, 0
-> 'a' rec(pool, 3, 0) | ndx[0..2] = 0, 1, 0
-> '\n' return ALL_DONE | ndx[0..2] = 0, 1, 0
-> return NOT_YET | ndx[0..2] = 0, 1, 1
-> return NOT_YET | ndx[0..2] = 0, 1, 1
-> return NOT_YET | ndx[0..2] = 0, 1, 1
|
| ...
|
rec(pool, 0, 0)[8th]
-> 'l' rec(pool, 1, 0) | ndx[0..2] = 0, 1, 3
-> 'r' rec(pool, 2, 0) | ndx[0..2] = 0, 1, 3
-> 'o' rec(pool, 3, 0) | ndx[0..2] = 0, 1, 3
-> '\n' return ALL_DONE | ndx[0..2] = 0, 1, 3
-> return ALL_DONE | ndx[0..2] = 0, 1, 4
-> return ALL_DONE | ndx[0..2] = 0, 2, 0
-> return ALL_DONE | ndx[0..2] = 1, 0, 0
|
| FINISH
答案 1 :(得分:1)
这最终为我工作! Thx @Tsukuyo提示。如果我想在排列中找到字符串的第n个索引,是否需要单独提问?
void rec(char** pool, int k, int j, char* cur, int counter)
{
if(k==j)
{
cur[k]=0;
printf("Recursive call #%d %s\n",counter,cur);
return;
}
int i,len=strlen(pool[k]);
for (i=0;i<len;i++)
{
cur[k]=pool[k][i];
rec(pool,k+1,j,cur,counter++);
}
}
答案 2 :(得分:1)
您创建一个char数组,其中包含您要使用的字符串
char str[] = "ABC";
然后你得到字符串int n = strlen(str);
的长度,最后你排列。
你创建一个新函数,它将包含输入字符串,字符串的起始索引和字符串的结束索引。
检查起始索引(int s
)是否等于结束索引(int e
)
如果确实如此,那意味着你已经完成了,如果没有你进入一个循环,你从开始到结束(e),交换值,递归,再次交换回溯。
C ++中的一个例子:
#include <stdio.h>
#include <string.h>
void swap(char *i, char *j)
{
char temp;
temp = *i;
*i = *j;
*j = temp;
}
void permutate(char *str, int start, int end)
{
int i;
if (start == end)
printf("%s\n", str);
else
{
for (i = start; i <= end; i++)
{
swap((str + start), (str + i));
permutate(str, start + 1, end);
swap((str + start), (str + i)); //backtrack
}
}
}
int main()
{
char str[] = "ABC";
int n = strlen(str);
permutate(str, 0, n - 1);
return 0;
}