全排列学习(从别人那学的算法,自己稍微总结了下思路)

#include<iostream>

#include<algorithm>
#include<string.h>
/**
代码是从https://blog.csdn.net/algzjh/article/details/73456877 这里学的,还是有点懵懵的,脑子不太好使。哈哈
下面是 学习上述网址的 (非递归全排列)后自己总结的。
整体思路,就是 先保证输入的字符串顺序是 从小到大的,然后 进行全排列;
全排列 先是从 最右边往左 找到 第一个满足 左小于右 的位置;
       然后从 最右边往左 找到 第一个满足 大于上面一个循环找到的位置 的元素;
       然后把找到的 元素 和 第一个循环的位置对调,保证 字符串 右边变动的地方是 从右边找到的最小元素替换的,那就是字典顺序了
       接着把 最右边 的元素 全部颠倒,因为 右边 应该是 从左往右 递减的。


       假设 123654,那么 第一个循环 找到 3的位置,
                         (第二个循环)然后 我们都知道3应该和4 对换,也就是 右边那部分最小的数字3;
                    (两个循环分别找到要对调的元素后) 对换后,12(4)65(3)
                    然后 我们都知道 123654 接下去应该是 124356,保证第一个 循环找到的位置 后面一串 应该保证 从小到大
                    那么 最后执行 把 后面那串对调的函数,就ok了
**/




const int MAX = 10000;
char a[MAX];
int Count = 0;
using namespace std;


void LatterConvert(int former,int latter)///把后面的部分全部对调,使得后面一串也是从小到大排列
{
    for(; former<latter; former++,latter--)
        swap(a[former],a[latter]);
}
void QuanPaiLei(int Len)
{
    int i,j;
    if(Len<2)///如果长度小于2,就不需要排列了(例如只输入1一元素,“a”,那当然不用排列了)
        return;
    while(true)
    {
        cout<<"the "<<++Count<<"th permutations: "<<a<<endl;
        for(i = Len-2; i>=0; i--)
        {
            if(a[i]<a[i+1])///从最右边往左找到第一个 满足 前小于后 的位置
                break;
            if(i==0) ///i = 0,说明已经一整个都是 从大到小 排序了,不需要继续循环了(例如最后一种情况654321)
                return;
        }
        for(j =Len-1; j>i; j--) ///从最后一个位置起往左(前)找出第一个大于它的数字,然后准备调换,因为 越往左越大,所以从最右边开始找 第一个比它大的数字交换。
        {
            if(a[j]>a[i])///找到第一个大于 a[i]的元素位置
                break;
        }
        swap(a[j],a[i]);
        LatterConvert(i+1,Len-1);
    }
}


int main()
{
    while(cin >> a)
    {
        int Len = strlen(a);
        sort(a,a+Len);
        QuanPaiLei(Len);
    }
    return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值