字符串的全排列

本文介绍两种实现字符串全排列的方法:递归法和字典序排列法。递归法通过固定字符串中每个字符的位置并递归求解剩余字符的排列组合;字典序排列法则通过寻找当前序列的下一个字典序,实现所有可能排列的遍历。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题描述:

给定一个字符串"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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值