这里谈一下全排列的几种实现及我的理解;
1,递归实现,即从头位向尾位交换,首次递归首位,待首位的之后的情况全部确定之后,交换首位,继续处理其后的情况,当首位确定之后,第二位为首位,相识的思路,直到末尾
即可输出。
代码1:
//递归实现,未去重,非字典序;
#include<iostream>
#include<cstdio>
using namespace std;
void Permutation(char* pStr, char* pBegin)
{
if(*pBegin == '\0')
printf("%s\n",pStr); //终止时条件;
else
{
for(char* pCh = pBegin; *pCh != '\0'; pCh++)
{
swap(*pBegin,*pCh); //递归前交换;
Permutation(pStr, pBegin+1);
swap(*pBegin,*pCh); //递归后复位;
}
}
}
int main()
{
char str[] = "abcd";
Permutation(str,str);
return 0;
}
代码2:
//递归实现,去重,非字典序;
bool cmp(string s,int len,int i)
{
for(int ii = len;ii<i;++ii)
if(s[ii]==s[i])
return true;
return false;
}
void Permutation(string *s,int len)
{
if(len == (*s).length())
cout<<(*s)<<endl;
else
{
for(int i = len;i<(*s).length();++i)
{
if(!cmp(*s,len,i))
{
swap((*s)[len],(*s)[i]);
Permutation(s,len+1);
swap((*s)[len],(*s)[i]);
}
}
}
}
2,字典序逐渐递增实现
在已经从小到大排序好的当前序列中,从尾端往前寻找两个相邻元素,前一个记为i,后一个记为ii,并且满足i < ii。然后再从尾端寻找另一个元素j,如果满足i < *j,即将第i个元素与第j个元素对调,并将第ii个元素之后(包括ii)的所有元素颠倒排序,即求出下一个序列了。
代码如下:
//去重,字典序输出;
#include<bits/stdc++.h>
#include <windows.h>
using namespace std;
///建立了一种,字典序以最小速度增大字符串的模型;
///算法分析,按每次得到下个序列为单位,复杂度为O(n)
int paiLie(char x[])
{
int end=0;
int length=strlen(x);
///检测是否已达到全倒序;
for(int i=0; i<length-1; i++)
{
if(x[i]>=x[i+1])
end=i+1;
else break;
}
///如果相等即说明整个倒序,停止递归;
if(end==length-1)
return 0;
///操作;
int k=0,kk=0,t=0;
char temp;
///从尾端往前寻找两个相邻元素,前一个记为*i,后一个记为*ii,并且满足*i < *ii。;
for(int i=length-2; i>=0; i--)
{
if(x[i]<x[i+1])
{
k=i;
kk=i+1;
break;
}
}
///然后再从尾端寻找另一个元素*j,如果满足*i < *j;
for(int i=length-1; i>=0; i--)
{
if(x[i]>x[k])
{
t=i;
break;
}
}
///即将第i个元素与第j个元素对调,
///并将第ii个元素之后(包括ii)的所有元素颠倒排序,
///即求出下一个序列了。
temp=x[k];
x[k]=x[t];
x[t]=temp;
for(int i=kk,j=length-1; i<j; i++,j--)
{
temp=x[i];
x[i]=x[j];
x[j]=temp;
}
printf("%s\n",x);
paiLie(x);
}
int main()
{
char x[]= {'b','a','c','d','\0'};
int n=strlen(x);
sort(x,x+n);
printf("这个是排完序的源码->%s\n",x);
paiLie(x);
}
3,stl中已包含std::next_permutation与std::prev_permutation直接调用即可得到下一位或者上一位字典序下的字符串或数组,其中前者最大字典序再下一位会得到最小字典序,并返回0,其余返回1,后者运用规则类似,调用格式std::next_permutation(首地址,尾地址,比较函数),用法参照std::sort();