我正在尝试用c ++实现堆算法,然而,如果它的置换字符串达到4的长度,算法就开始重复了。这里是代码:
void permute(int n, string str, int *total,string array[]){
if (n==0){
array[*total] = str;
*total += 1;
}
else{
for(int c=0; c<=n;c++){
permute(n-1,str,total, array);
if (n % 2 == 0){
char tmpstr=str[c];
str[c]=str[n];
str[n]=tmpstr;
}
else{
char tmpstr=str[0];
str[0]=str[n];
str[n]=tmpstr;
}
}
}
}
int main() {
int total = 0;
string array[24];
permute(3,"abcd",&total, array);
cout << total << endl;
return 0;
}
这是输出。它在第13行重复
24
abcd
bacd
cbad
bcad
cabd
acbd
dbca
bdca
cbda
bcda
cdba
dcba
abcd <-- right here
bacd
cbad
bcad
cabd
acbd
dbca
bdca
cbda
bcda
cdba
dcba
谢谢你们,欢迎任何帮助!
答案 0 :(得分:2)
尽管使用PaulMcKenzie推荐的标准功能始终是一个绝佳的主意,但您已经发布了一个代码,其中包含有关其无效的问题。
在for循环中,删除行if (n%2 ==0)
及其他部分:
for(int c=0; c<=n;c++){
permute(n-1,str,total, array);
char tmpstr=str[c];
str[c]=str[n];
str[n]=tmpstr;
}
然后它应该工作。
答案 1 :(得分:0)
看起来您正在尝试实现wikipedia中所述的最初在here中给出的排列生成的Heap算法的递归版本。如果你想保持接近它(例如,在生成排列时具有相同的顺序),你所要做的就是传递str
参数作为参考(你必须改变线路调用permute()
函数传递一个可变字符串而不是一个字符串常量,强硬)并保留if-then-else子句最初在你的程序中。
尽管如此,@ Christophe给出的版本很有意思。我已经尝试过最多n=6
(7个元素的排列),并且仍然给出所有排列。有趣的是要知道这是否可以被证明适用于任何自然数。然而,这一点可能没有实际意义,因为我引用的两个参考文献中给出的递归版本也没有实现Heap给出的原始版本,并且据我所知,还没有证明给出所有排列。由Heap提供的原始版本,写于1963年,甚至没有使用结构化编程。它是作为流程图给出的,用goto
来实现。