生成字符串排列
问题:
给出一个函数来输出一个字符串的所有排列。
想法:
排列算法流行的有递归,置换,字典序法。
1.递归算法,每个n排列是每个字符与n-1排列的结合。算法的核心部分是维持一个递归树,从树根到树叶的一条路径是一个排列。
2.置换算法,基于置换群的理论,每完成一次置换生成一个排列。
3.字典序法,每次生成排列的下一个排列,可以通过数值计数来模拟,当然也可以手工生成。
实现:
1.递归算法:
#include <stdio.h>
void swap(char *l, char *r){
char s = *l;
*l = *r;
*r = s;
}
void generate(char *buf, char *p, int len){
int i;
if(len == 1){
printf("%s\n", buf);
return;
}
for(i = 0; i < len; ++i){
swap(p, p+i);
generate(buf, p+1, len-1);
swap(p, p+i);
}
}
int main(){
char buf[] = "1234";
generate(buf, buf, sizeof(buf)-1);
return 0;
}
2.置换算法:
占位,暂时没弄懂那玩意,还希望知道的人能提供些比较浅的资料瞅瞅。:)
3.字典序算法:
#include <stdio.h>
void swap(char *l, char *r){
char s = *l;
*l = *r;
*r = s;
}
int next(char *buf, int len){
int i, j, s = len-1, nn = 0;
for(i = s; i > 0; --i){
if(buf[i-1] < buf[i]){
i -= 1;
nn = 1;
break;
}
}
j = s;
while(buf[i] > buf[j]){
--j;
}
swap(buf+i, buf+j);
i += 1;
j = s;
while(j > i){
swap(buf+i, buf+j);
++i;
--j;
}
return nn;
}
void generate(char *buf, int len){
do{
printf("%s\n", buf);
}while(next(buf, len));
}
int main(){
char buf[] = "1234";
generate(buf, sizeof(buf)-1);
return 0;
}
字典序算法在C++的算法库里面有对应函数,也是一个叫什么next的。