写一个函数, 如 Foo(char *str), 打印出 str 的全排列,
整体实现:
如 abc 的全排列: abc, acb, bca, dac, cab, cba
递归思想来解决:
每次交换第一位和它后面的每一位,如abc,找到了全部排列。循环停止条件,begin = end;
//全排列
#include<stdio.h>
static int count = 0;//记录可以有多少种排列
void swap(char *str, int a, int b){
char tmp;
tmp = str[a];
str[a] = str[b];
str[b] = tmp;
}
void Foo(char *str, int begin, int end){
if(begin == end){
count ++;
int i;
for(i=0;i<3;i++)
{
printf("%c",str[i]);
}
printf("\t");
return;
}else{
int i;
for(i = begin; i <= end; i ++){
swap(str, begin, i);
Foo(str, begin + 1, end);
swap(str, begin, i);
}
}
}
int main(){
char str[] = {'a','b','c'};
Foo(str, 0, 2);
printf("count = %d",count);
return 0;
}
但是有一种重复的情况如abb,使用之前的方法会输出重复元素,如:
思路:判断待交换的字符在之前是否出现过,如果出现过不进行交换。
int is_swap(char *str, int begin, int k){
int flag = 1;
int i;
for(i=begin; i<k; i++){
if(str[i] == str[k]){
flag = 0;
break; //之前写错位置出错了
}
}
return flag;
}
整体实现:
#include<stdio.h>
static int count = 0;//记录可以有多少种排列
void swap(char *str, int a, int b){
char tmp;
tmp = str[a];
str[a] = str[b];
str[b] = tmp;
}
int is_swap(char *str, int begin, int k){
int flag = 1;
int i;
for(i=begin; i < k; i++){
if(str[i] == str[k]){
flag = 0;<pre code_snippet_id="1734264" snippet_file_name="blog_20160628_3_3044238" name="code" class="cpp"> break;
}}return flag; } void Foo(char *str, int begin, int end){ if(begin == end){ count ++; int i; for(i=0;i<3;i++) { printf("%c",str[i]);}printf("\t"); return; }else{ int i; for(i = begin; i <= end; i ++){ if (is_swap(str,begin,i)) { swap(str, begin, i); Foo(str, begin+1, end); swap(str, begin, i);} } } } int main(){ char str[3] = {'a','b','b'}; Foo(str,0,2); printf("count=%d",count); return 0;}