全排列
1.类似于C++STL库中的全排列
abc 的全排列: abc, acb, bac, bca, cab, cba
123 的全排列: 123, 132, 213, 231, 312, 321
思想参考自:http://blog.csdn.net/morewindows/article/details/7370155?reload
剑指offer P155,此外全排列还可以用以解决8皇后问题,对于按照一定要求摆放若干数字,都可以考虑用全排列解决。
全排列就是从第一个数字起每个数分别与它后面的数字交换。
1:从后向前找第一对相邻的递增数对,前一个数replaced为被替换数
2:再由后向前找第一个比被替换数大的数,然后与被替换数交换。
3:最后反转被替换数之后的所有数据。此时完成一次排列
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int cmp(void const *a, void const *b)
{
char *c = (char *)a;
char *d = (char *)b;
return (*c > *d) ? 1: -1;
}
void swap(char *a, char *b)
{
char tmp;
tmp = *a;
*a = *b;
*b = tmp;
}
/*反转字符串*/
void reverse(char *left, char *right)
{
while (left < right)
{
swap(left++, right--);
}
}
int next_permutation(char *start, char *end)
{
char *replaced, *p, *find;
/*因为是排好序的,两个元素时直接结束*/
if (start == --end)
{
return 0;
}
replaced = end;
while (replaced != start)
{
p = replaced--;
if (*replaced < *p) /*从后向前找第一对相邻的递增数对,前一个数replaced为被替换数*/
{
find = end;
while (*find <= *replaced) /*从后向前找第一个比被替换数大的替换数*/
{
--find;
}
swap(replaced, find);
reverse(p, end); /*被替换数之后的数全部反转*/
return 1;
}
}
reverse(start, end); /*这一句是为了和STL中的next_permutation一致,还原到最小的排列状态*/
return 0;
}
int main(void)
{
char str[10];
while (scanf("%s", str) != EOF)
{
int len = strlen(str);
qsort(str, len, sizeof(char), cmp); /*递增排序*/
printf("全排列如下:\n");
do
{
puts(str);
}while (1 == next_permutation(str, str+len)); /*接着使用交换后的序列计算*/
}
return 0;
}
1.类似于C++STL库中的全排列去重的全排列:就是从第一个数字起每个数分别与它后面非重复出现的数字交换,王道程序员求值宝典P239。但是这个不满足字典顺序
*/去重的全排列:就是从第一个数字起每个数分别与它后面非重复出现的数字交换,王道程序员求值宝典P239。但是这个不满足字典顺序
*//*
*去重的全排列:就是从第一个数字起每个数分别与它后面非重复出现的数字交换,王道程序员求值宝典P239。但是这个不满足字典顺序
*//*
*去重的全排列:就是从第一个数字起每个数分别与它后面非重复出现的数字交换,王道程序员求值宝典P239。但是这个不满足字典顺序
*/1.去重的全排列:就是从第一个数字起每个数分别与它后面非重复出现的数字交换,王道程序员求值宝典P239。但是这个不满足字典顺序
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int cmp(const void *a, const void *b)
{
char *c = (char *)a;
char *d = (char *)b;
return (*c > *d) ? 1: -1;
}
void swap(char *a, char *b)
{
char tmp = *a;
*a = *b;
*b = tmp;
}
/*在str数组中,[begin,end)中是否有数字与下标为end的数字相等*/
int euqal(char *str, int begin, int end)
{
int i;
for (i=begin; i<end; i++)
{
if (str[i] == str[end])
{
return 1;
}
}
return 0;
}
/*k表示当前选取到第几个数,m表示共有多少数*/
void perm(char *str, int k, int m)
{
int i;
if (k == m)
{
printf("%s\n", str);
}
else
{
for (i=k; i<=m; i++) /*第i个数分别与它后面的数字交换就能得到新的排列*/
{
if ( 0 == euqal(str, k, i) )
{
swap(&str[k], &str[i]);
perm(str, k+1, m);
swap(&str[k], &str[i]);
}
}
}
}
int main(void)
{
char str[10];
while(scanf("%s", str) != EOF)
{
int len = strlen(str);
qsort(str, len, sizeof(char), cmp); /*递增排序*/
printf("全排列如下:\n");
perm(str, 0, len-1);
}
return 0;
}