题目描述
输入
输出
样例输入
abc
样例输出
abc
acb
bac
bca
cab
cba
1
next_permutation函数
组合数学中经常用到排列,这里介绍一个计算序列全排列的函数:next_permutation(start,end),和prev_permutation(start,end)。这两个函数作用是一样的,区别就在于前者求的是当前排列的下一个排列,后一个求的是当前排列的上一个排列。至于这里的“前一个”和“后一个”,我们可以把它理解为序列的字典序的前后,严格来讲,就是对于当前序列pn,他的下一个序列pn+1满足:不存在另外的序列pm,使pn<pm<pn+1.
对于next_permutation函数,其函数原型为:
#include <algorithm>
bool next_permutation(iterator start,iterator end)
当当前序列不存在下一个排列时,函数返回false,否则返回true
next_permutation(num,num+n)函数是对数组num中的前n个元素进行全排列,同时并改变num数组的值。
另外,需要强调的是,next_permutation()在使用前需要对欲排列数组按升序排序,否则只能找出该序列之后的全排列数。
此外,next_permutation(node,node+n,cmp)可以对结构体num按照自定义的排序方式cmp进行排序。
应用举例:
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int num[3]={1,2,3};
do
{
cout<<num[0]<<" "<<num[1]<<" "<<num[2]<<endl;
}while(next_permutation(num,num+3));
return 0;
}
2.递归 但运行出来不是字典序 递归序
#include <iostream> #include <string.h> using namespace std; void swap(char *a,int i,int j) { char temp=a[i]; a[i]=a[j]; a[j]=temp; } void quanpailie(char array[],int len,int index) { if(index==len)//全排列结束 { cout<<array<<endl; } else { for(int i=index;i<len;++i) { swap(array,index,i);//将第i个元素交换至当前index下标处 quanpailie(array,len,index+1);//以递归的方式对剩下的元素进行全排列 swap(array,index,i);//将第i个元素放回原处 } } } int main() { char array[8]={0}; cin>>array; quanpailie(array,strlen(array),0); return 0; }
2.字典序
解题思路
设P是1~n的一个全排列:p=p1p2......pn=p1p2......pj-1pjpj+1......pk-1pkpk+1......pn
1)从排列的右端开始,找出第一个比右边数字小的数字的序号j(j从左端开始计算),即 j=max{i|pi<pi+1} 2)在pj的右边的数字中,找出所有比pj大的数中最小的数字pk,即 k=max{i|pi>pj}(右边的数从右至左是递增的,因此k是所有大于pj的数字中序号最大者) 3)对换pi,pk4)再将pj+1......pk-1pkpk+1......pn倒转得到排列p'=p1p2.....pj-1pjpn.....pk+1pkpk-1.....pj+1,这就是排列p的下一个排列。
证明
算法实现:
#include <iostream>
#include <string.h>
using namespace std;
void swap(char*s,int i,int j){//交换两个元素
char temp;
temp=s[i];
s[i]=s[j];
s[j]=temp;
}
void reverse(char *s, int first, int last){//翻转序列
while (first<last){
swap(s,first++,last--);
}
}
int findmin(char*a){ //从排列的右端开始,找出第一个比右边数字小的数字的序号
int j,length=strlen(a);
for(j=length-2;j>=0;j--)
{
if(a[j]<a[j+1])break;
}
return j;
}
int main()
{
char a[8];
cin>>a;
int i=0,j,k,length=strlen(a);
for(i=0;i<length-1;i++)
{
for(j=i;j<length-1;j++)
{
if(a[i]>a[j])swap(a,i,j);
}
}
cout<<a<<endl;
while(true)
{
j=findmin(a);
if(findmin(a)==-1) break;
for(i=length-1;i>j;i--)
{
if(a[i]>a[j])break;
}
swap(a,j,i);
reverse(a,j+1,length-1);
cout<<a<<endl;
}
return 0;
}