gpt4 book ai didi

c++ - 在任何编程语言中回溯

转载 作者:行者123 更新时间:2023-11-30 20:41:03 26 4
gpt4 key购买 nike

我的任务是编写一个字符串排列程序。我理解逻辑,但不明白 Backtrack 的确切含义在这个节目中。请解释 for 循环功能,当 swappermutate()时将被调用会被调用,以及backtrack的具体含义。

# 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() 来打印每个这个新字符串的排列,然后我们将字符串恢复到之前的状态,这样我们就可以让原始字符串对下一个位置重复相同的过程。

就我个人而言,我不喜欢“原路返回”的评论。更好的术语是“回旋”,因为此时递归会回旋,并且您为下一次递归调用准备字符串。回溯通常用于您探索子树但没有找到解决方案的情况,因此您返回(回溯)并尝试不同的分支。摘自维基百科:

Backtracking is a general algorithm for finding all (or some) solutions to some computational problem, that incrementally builds candidates to the solutions, and abandons each partial candidate c ("backtracks") as soon as it determines that c cannot possibly be completed to a valid solution.

请注意,该算法不会生成排列集,因为当存在重复字母时,它可以多次打印相同的字符串。一种极端的情况是,当您将其应用于字符串“aaaaa”或任何其他具有一个唯一字母的字符串时。

关于c++ - 在任何编程语言中回溯,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19220216/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com