首页 > 其他 > 详细

ybt1199 全排列

时间:2020-01-24 13:43:25      阅读:91      评论:0      收藏:0      [点我收藏+]

ybt1199 全排列

【题目描述】

给定一个由不同的小写字母组成的字符串,输出这个字符串的所有全排列。

我们假设对于小写字母有‘a’ <‘b’ < ... <‘y’<‘z’,而且给定的字符串中的字母已经按照从小到大的顺序排列。

【输入】

只有一行,是一个由不同的小写字母组成的字符串,已知字符串的长度在1到6之间。

【输出】

输出这个字符串的所有排列方式,每行一个排列。要求字母序比较小的排列在前面。字母序如下定义:

已知S=s1s2...sk,T=t1t2...tkS=s1s2...sk,T=t1t2...tk,则S<T等价于,存在p(1≤p≤k),使得s1=t1,s2=t2,...,sp?1=tp?1,sp<tps1=t1,s2=t2,...,sp?1=tp?1,sp<tp成立。

【输入样例】

abc

【输出样例】

abc acb bac bca cab cba

【题解】

由于原数组使用字典序排列的,所以就不需要再次排序。

我们小学就学过全排列的基本思路:在确定首位的基础上,全排列其余位,然后依次更换首位,使所有元素在首位出现一遍,这样这一层递归就结束了。

这是一个典型的递归模型,在确定第x位的基础上,全排列x+1位及其后面的元素。所以递归函数就要分两部分:枚举第x位和全排列后面的位。

递归边界就是x=l(x是最后一位后面的一位)时,已经将第x位前面的元素(所有元素)的位置确定了下来,只要输出就好了。

实现这个算法,需要保证一个元素的位置确定后,不会出现第二次,这时,就要在确定a[i]成为b[x]的元素之前,走一遍b数组,查找是否有a[i]在b中出现过。若出现过,就找下一个符合条件的a[i]判断是否可以。

这样就可以写出递归函数:

void f(int x) {//x是当前数组b的长度,由于b是从0开始命名的,所以x也可以做本次操作的b的当前位的指针
    if(x==l) {//递归边界,本次结束了,输出结果
        for(int i=0; i<l; ++i)
            cout<<b[i];
        cout<<endl;
    }
    else {//没有结束,将b[x]的位置确定下来
        bool bj=0;//判断a[i]是否在b中出现过将要使用的标记
        char t;
        for(int i=0; i<l; ++i) {//枚举第x位是a[i]
            t=a[i];//提取a[i]并暂存
            bj=0;
            for(int j = 0; j < x; ++j) {//扫一遍b数组,判断a[i]是否在已排列的数组中出现
                if(b[j]==t) {//已排列的数组中有a[i]
                    bj=1;//打标记
                    break;//跳出(已经找到了,再找下去也不会找到a[i]了,因为字符串不重复)
                }
            }
            if(bj)//b[j]就是之前出现过的a[i],所以再找下一个a[i]放入b
                continue;
            else {
            b[x] = a[i];//这是a[i]没有出现的情况,就把a[i]放到b[j+1]中。
            f(x+1);//在确定前x位的基础上,全排列x+1位以及后面的元素
            }
        }
    }
}

由于n个不重复元素的全排列有n!个,所以算法的复杂度可以达到n^n^,但是因为本题数据范围是1<=n<=6,所以这样暴力的复杂度完全没问题,接下来是完整代码:

#include<iostream>
#include<cstring>
using namespace std;
string a,b;
int l;
void f(int x)
int main() {
    cin>>a;
    l=a.length();
    f(0);
    return 0;
}

感谢题解的思路帮助。

除夕快乐!

ybt1199 全排列

原文:https://www.cnblogs.com/Wild-Donkey/p/12232054.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!