字典序算法

字典序算法

1、字典序的概念

据说字典序是个比较经典的算法,也不知道出自哪里。。。用一个例子说明什么是字典序,对于1、2、3,按照如下排序:

123   132    213    231     312     321

这些排序从左到右依次增大,就是所谓的字典序。

2、查找字典序的下一个数

对于已有的排序的一个排序,怎么得到其字典序的下一个排列呢?

①从右到左找到第一个左边小于右边的数字; (这一步是确定一个增加的位置,该位置需要保证增加之后对整体的增加较小)

②如果没有找到①中de数字,说明已经是最后一个排列,比如321;

  如果找到第i个元素,说明可以得到下一个排列,入132,找到了1。

③从右到左找到第一个大于i元素的j元素,如132中找到了2;(这一步找到一个用户交换的数字,因此从大于该位置的数中找到一个最小的)

④交换i、j元素的位置,如132,交换完成为231;

⑤对i之后的元素进行排序,排序完成为213;

3、字典序生成全排列
方法1:

①对所有元素进行升序排序,得到最小的排列;

②按照2中的方法循环得到下一个排列,直至最大

方法2:

方法1中需要提前对元素进行一次排序,如果从当前排列开始,同上向前找到排列和向后找到排列,就不需要提前进行排序了


//找到下一个遵循字典序的排列
bool findNext(string &str)
{
    int num = str.size();
    int i, j;
    //从右向左,找到第一个左边小于右边的数,如54231,则找到2
    for(i=num-2; i>=0; i--)
    {
        if(str[i] < str[i+1])
        {
            break;
        }
    }

    //如果没有找到,说明已经最大
    if(i<0)
    {
        return false;
    }

    //从右向左,找到第一个大于str[i]的元素,如54231,则找到3
    for(j=num-1; j>i; j--)
    {
        if(str[j] > str[i])
        {
            break;
        }
    }

    //交换i、j位置字符,如54321,交换完成后是54312
    int temp = str[i];
    str[i] = str[j];
    str[j] = temp;

    //对i之后的元素进行排序,排序完成后为54123
    sort(str.begin()+i+1, str.end());

    return true;
}





vector<string> Permutation(string &str) {
    vector<string> v;
    int len =  str.size();

    if(len <= 0)
    {
        return v;
    }

    sort(str.begin(), str.end());

    v.push_back(str);

    while(findNext(str) == true)
    {
        v.push_back(str);
    }

    return v;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值