HERE是我所指的递归字符串置换解决方案。我理解该算法,但无法理解代码如何使其工作。就像两个互换在这里工作一样。
char * full_string;
void permute(char * str, int length) {
if(length == 0) {
printf(“%s\n”, full_string);
return;
} else {
for(int i = 0; i < length; ++i) {
swap(str[0], str[i]);
permute(str+1, length-1);
swap(str[0], str[i]);
}
}
}
答案 0 :(得分:2)
抱歉我画的很糟糕。该算法基本上如下运行:
ABC
/ | \
swap(A,A) swap(A,B) swap(A,C)
/ | \
ABC BAC CBA
/ \ / \ / \
swap(B,B) swap(B,C) swap(A,A) swap(A,C) swap(B,B) swap(B,A)
/ \ / \ / \
ABC ACB BAC BCA CBA CAB
请记住permute
生成最后length
元素的所有排列,因此您将每个元素与第一个元素交换并转到下一个,这样您就可以获得所有排列。
答案 1 :(得分:0)
如果你知道c / c ++,那么代码就不复杂了。
让我们从else子句开始,因为它是函数的主要功能部分。
for(int i = 0; i < length; ++i) {
swap(str[0], str[i]);
permute(str+1, length-1);
swap(str[0], str[i]);
你应该理解for循环 - 就像在java中一样。
str是一个char数组(实际上是一个指针,但在很多情况下它们是相同的)。所以str[0]
是char数组的第一个元素。
将此代码中的Java程序员混淆的主要部分是str+1
- 将一个添加到数组中意味着什么?事实上str是一个指针,而不是一个数组--c / c ++支持pointers arithmetics。将一个添加到指针(基本上)意味着任何将来的引用都将用一个表示。例如添加后s[1]
等于s[2]
之前。
我认为在这些解释之后,代码应该清楚。
答案 2 :(得分:0)
char * full_string; // String is defined... hopefully you get this
void permute(char * str, int length) {
if(length == 0) { // if the length to permute is 0, string should be as-is. This is the base case of the recursion.
printf(“%s\n”, full_string);
return;
} else { // Otherwise... (Recursive case)
for(int i = 0; i < length; ++i) {
swap(str[0], str[i]); // Swap the first character with the i-th character
permute(str+1, length-1); // Get all permutations with the i-th character as the first character
swap(str[0], str[i]); // Get the original string back for the next loop
}
}
}
最难理解的部分是递归位。尝试用一个简单的例子来描述它是如何工作的,你应该看看它是如何工作的。
基本上对于字符串'abc'
来查找所有排列,您需要'a' + permutations('bc')
,'b' + permutations('ac')
和'c' + permutations('ab')
然后(例如)对于a + permutations('bc')
的情况,这会分解为查找ab + permutations('c')
和'ac' + permutations('b')
,这在下一次递归调用中只会获得'abc'
和{ {1}}。
然后,当'acb'
是您的第一个角色并且'b'
是您的第一个角色时,会执行相同的处理。
希望您能看到同一个进程如何分解更大的字符串以查找第一个字符的排列+剩余字符的所有排列