我正在努力以递归的方式查找3位数的所有排列。
我厌倦了编制以下排列方法:
static int a = 1;
static int b = 2;
static int c = 3;
static int aCount;
static int bCount;
static int cCount;
static void perm(int a, int b, int c)
{
Console.WriteLine("( {0}, {1}, {2} )", a, b, c); // (1,2,3 )
if (aCount < 1 && bCount<1 &&cCount<1)
{
aCount++;
perm(a, c, b);
}
else
if (aCount==1 && bCount < 1 && cCount<1)
{
bCount++;
perm(b, a, c);
}
else
if (aCount == 1 && bCount == 1 && cCount < 1)
{
perm(b,c,a);
}
else
if (aCount==1 && bCount==1 && cCount < 1)
{
cCount++;
perm(c, a, b); //c b a
}
else
if (aCount == 1 && bCount == 1 && cCount == 1)
{
perm(c, b, a);
}
}
我试图覆盖所有案例,每一步都有详细说明,但我仍然得到了蓝色的Stack overflow异常。
我感谢你的贡献,所以感谢你们。
答案 0 :(得分:3)
你说你正在尝试递归,但所有这些行都出现在你的代码中:
perm(a, c, b)
perm(b, a, c)
perm(b, c, a)
perm(c, a, b)
perm(c, b, a)
当然是函数的第一次调用:perm(a, b, c)
这样做容易得多:
static void perm(int a, int b, int c)
{
Console.WriteLine("( {0}, {1}, {2} )", a, b, c);
Console.WriteLine("( {0}, {2}, {1} )", a, b, c);
Console.WriteLine("( {1}, {0}, {2} )", a, b, c);
Console.WriteLine("( {1}, {2}, {0} )", a, b, c);
Console.WriteLine("( {2}, {0}, {1} )", a, b, c);
Console.WriteLine("( {2}, {1}, {0} )", a, b, c);
}
答案 1 :(得分:0)
首先,这两种情况中的任何一种都会导致无限递归:
if (aCount == 1 && bCount == 1 && cCount < 1)
{
perm(b,c,a);
}
和
if (aCount == 1 && bCount == 1 && cCount == 1)
{
perm(c, b, a);
}
原因是您不能更改aCount
,bCount
或cCount
,因此您最终会重复触发相同的案例。
除此之外,你似乎并没有真正地递归地思考这个问题 - 正如另一个答案所提到的,所有的排列都出现在一个调用中,所以,如果你让它以这种方式工作,你的递归深度将为2,这可能主要涉及用print语句替换每个递归调用,并具有非递归函数。
对于递归解决方案,尝试考虑一个解决方案,在当前调用中处理单个字符,然后递归到下一个字符。
更详细的解释,如果你无法弄清楚:
从第一个角色开始。 尝试将当前字符与每个剩余字符交换(包括其自身,即不执行任何操作)。 递归到下一个角色。 在最后一个字符处,打印出所有字符。
提示 - 将数组和当前索引传递给您的函数。
答案 2 :(得分:0)
&#39;我会给你写伪代码:
permutationABC()
{
int n=3;
array SOL[n]/* 1 if you get the element otherwise 0 if you don't get the element , the meaning of SOL is that SOL[0] is 1 if we had got 'a' , otherwise 0. It's the same for the others */
initSolWithAllZero(SOL)
permRecursive(abc,SOL,0,n);
}
permRecursive(SOL,i,n)
{
if i == n then print(SOL)
else
{
for k=0 to n
{
if SOL[k] == 0 then
{
SOL[k]=1 // take
permRecursive(SOL,i+1,n)
SOL[K]=0 // don't take ... go back....
}
}
}
}
时间为O(n * n!)O(n!)是排列数,O(n)是打印时间。