Closed. This question is off-topic。它当前不接受答案。
想改善这个问题吗? Update the question,所以它是on-topic,用于堆栈溢出。
6年前关闭。
我被赋予编写字符串置换程序的任务。我理解该程序的逻辑,但不了解
像往常一样,在上面的示例中,缩进定义了每个递归调用内部发生的情况。
for循环背后的原因是,字符串ABC的每个排列都是由ABC,BAC和CBA给出的,再加上子字符串BC,AC和BA的每个排列(从每个先前的字母中删除第一个字母)。对于任何字符串S,通过将每个位置与第一个位置交换,再加上每个这些字符串的所有排列,可以获得可能的排列。可以这样想:任何置换后的字符串都必须以原始字符串中的一个字母开头,因此将所有可能的字母都放在第一位,然后对其余的字符串递归应用相同的方法(不包含第一个字母) 。
这就是循环的作用:我们从当前起始点(即i)到末尾扫描字符串,然后在每一步中,将该位置与起始点交换,递归调用permute()来打印此字符串的每个排列新的字符串,然后将其恢复为先前的状态,这样我们就可以使用原始字符串在下一位置重复相同的过程。
我个人不喜欢说“回溯”的评论。更好的术语是“回退”,因为这时递归回退,并且您为下一个递归调用准备了字符串。回溯通常用于您探索了子树而又找不到解决方案的情况,因此您需要回溯(回溯)并尝试其他分支。摘自维基百科:
回溯是找到所有(或某些)的通用算法
逐步建立的一些计算问题的解决方案
解决方案的候选者,并放弃每个部分候选者c
(“ backtracks”)一旦确定c不可能是
完成有效的解决方案。
请注意,此算法不会生成排列集,因为当重复的字母出现时,它可以多次打印同一字符串。一种极端情况是将其应用于字符串“ aaaaa”或带有一个唯一字母的任何其他字符串。
想改善这个问题吗? Update the question,所以它是on-topic,用于堆栈溢出。
6年前关闭。
我被赋予编写字符串置换程序的任务。我理解该程序的逻辑,但不了解
Backtrack
的确切含义。请说明for循环功能,何时调用swap
,何时调用permutate()
以及回溯的确切含义。# include <stdio.h>
void swap (char *x, char *y)
{
char temp;
temp = *x;
*x = *y;
*y = temp;
}
void permute(char *a, int i, int n)
{
int j;
if (i == n)
printf("%s\n", a);
else
{
for (j = i; j <= n; j++)
{
swap((a+i), (a+j));
permute(a, i+1, n);
swap((a+i), (a+j)); //backtrack
}
}
}
int main()
{
char a[] = "ABC";
permute(a, 0, 2);
getchar();
return 0;
}
最佳答案
绘制调用堆栈草图可以帮助您了解算法的工作原理。示例字符串“ ABC”是一个很好的起点。基本上,这是ABC会发生的情况:
permute(ABC, 0, 2)
i = 0
j = 0
permute(ABC, 1, 2)
i = 1
j = 1
permute(ABC, 2, 2)
print "ABC"
j = 2
string = ACB
permute(ACB, 2, 2)
print "ACB"
string = ABC
j = 1
string = BAC
permute(BAC, 1, 2)
.... (everything starts over)
像往常一样,在上面的示例中,缩进定义了每个递归调用内部发生的情况。
for循环背后的原因是,字符串ABC的每个排列都是由ABC,BAC和CBA给出的,再加上子字符串BC,AC和BA的每个排列(从每个先前的字母中删除第一个字母)。对于任何字符串S,通过将每个位置与第一个位置交换,再加上每个这些字符串的所有排列,可以获得可能的排列。可以这样想:任何置换后的字符串都必须以原始字符串中的一个字母开头,因此将所有可能的字母都放在第一位,然后对其余的字符串递归应用相同的方法(不包含第一个字母) 。
这就是循环的作用:我们从当前起始点(即i)到末尾扫描字符串,然后在每一步中,将该位置与起始点交换,递归调用permute()来打印此字符串的每个排列新的字符串,然后将其恢复为先前的状态,这样我们就可以使用原始字符串在下一位置重复相同的过程。
我个人不喜欢说“回溯”的评论。更好的术语是“回退”,因为这时递归回退,并且您为下一个递归调用准备了字符串。回溯通常用于您探索了子树而又找不到解决方案的情况,因此您需要回溯(回溯)并尝试其他分支。摘自维基百科:
回溯是找到所有(或某些)的通用算法
逐步建立的一些计算问题的解决方案
解决方案的候选者,并放弃每个部分候选者c
(“ backtracks”)一旦确定c不可能是
完成有效的解决方案。
请注意,此算法不会生成排列集,因为当重复的字母出现时,它可以多次打印同一字符串。一种极端情况是将其应用于字符串“ aaaaa”或带有一个唯一字母的任何其他字符串。
关于c++ - 任何编程语言的回溯,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19220216/
10-13 08:43