字符串的全排列

来源:互联网 发布:java mina netty 编辑:程序博客网 时间:2024/06/08 05:31

问题描述:

给定一个字符串"abc",输出由字符'a','b','c'所能排列出来的所有字符串abc,acb,bac,bca,cab,cba


解法一 递归实现

依次将a,b,c固定在第一位,然后求后面两个数的排列


#include <iostream>#include <algorithm>#include <string.h>using namespace std;void CalcAllPermutation(char *perm,int from,int to){    if(to < 0)        return;    if(from == to){        for(int i=0;i<=to;i++)            cout<<perm[i];        cout<<endl;    }    else{        for(int j=from;j<=to;j++){            swap(perm[j],perm[from]);            CalcAllPermutation(perm, from+1, to);            swap(perm[from],perm[j]);        }    }}int main(){    char perm[10];    cin>>perm;    CalcAllPermutation(perm,0,strlen(perm)-1);    return 0;}


解法二 字典序排列

大致意思是,我们可以以字典的顺序求出紧接着这个序列的下一个序列。

比如,12345 的下一个序列是 12354 , 下一个是 12435 下一个是 12453…… 最后一个是 54321

关键就是如何一个接一个地求出下一个序列。

方法:

1.先从右到左看,确定第i个元素,这个元素的特征是这样的:它是第一个满足其右边有元素大于它的。

2.将大于它的元素和第i个元素置换

3.最后将第i个元素之后的元素来一次翻转


#include <iostream>#include <algorithm>#include <string.h>using namespace std;bool CalcAllPermutation(char *perm,int num){    int i;    for(i=num-2; (i>=0)&& perm[i]>perm[i+1] ;i--);    if(i < 0)        return false;    int k;    for(k=num-1; (k>i)&& perm[k]<=perm[i];k--);    swap(perm[i],perm[k]);    reverse(perm+i+1,perm+num);    return true;}int main(){    char perm[10];    cin>>perm;    int length = strlen(perm);    int count = 1;    for(int i=1;i<=length;i++)        count = count * i;    int sum = 1;    for(int i=0;i<length;i++)        cout<<perm[i];    cout<<endl;    while(sum < count){        if(CalcAllPermutation(perm,length)){            for(int i=0;i<length;i++)                cout<<perm[i];            cout<<endl;            sum ++;        }    }    return 0;}


0 0
原创粉丝点击