zoukankan      html  css  js  c++  java
  • next_permutation(全排列算法)

    **STL提供了两个用来计算排列组合关系的算法,分别是next_permutation和prev_permutation。首先我们必须了解什么是“下一个”排列组合,什么是“前一个”排列组合。
    next_permutation()会取得[first,last)所标示之序列的下一个排列组合,如果没有下一个排列组合,便返回false;否则返回true。这个算法有两个版本。版本一使用元素型别所提供的less-than(第一个为a)操作符来决定下一个排列组合,版本二则是以仿函数comp来决定。**

    简单应用:
    ```
    #include<iostream>
    #include<algorithm>
    using namespace std;
    int main() {
    int ans[4]={1,2,3,4};
    sort(ans,ans+4);
    /* 这个sort可以不用,因为{1,2,3,4}已经排好序*/
    do /*注意这步,如果是while循环,则需要提前输出*/
    { for(int i=0;i<4;++i)
    cout<<ans[i]<<" ";
    cout<<endl;
    }while(next_permutation(ans,ans+4));
    return 0;
    ```
    **拓展
    1.能否直接算出集合{1, 2, ..., m}的第n个排列?
    举例说明:如7个数的集合为{1, 2, 3, 4, 5, 6, 7},要求出第n=1654个排列。

    (1654 / 6!)取整得2,确定第1位为3(从0开始计数),剩下的6个数{1, 2, 4, 5, 6, 7},求第1654 % 6!=214个序列;
    (214 / 5!)取整得1,确定第2位为2,剩下5个数{1, 4, 5, 6, 7},求第214 % 5!=94个序列;

    (94 / 4!)取整得3,确定第3位为6,剩下4个数{1, 4, 5, 7},求第94 % 4!=22个序列;

    (22 / 3!)取整得3,确定第4位为7,剩下3个数{1, 4, 5},求第22 % 3!=4个序列;

    (4 / 2!)得2,确定第5为5,剩下2个数{1, 4};由于4 % 2!=0,故第6位和第7位为增序<1 4>;

    因此所有排列为:3267514。

    [代码实现]

    ```
    #include<iostream>
    #include<algorithm>
    using namespace std;
    int main() {
    int ans[7]={1,2,3,4,5,6,7};
    sort(ans,ans+7); /* 同上可以不用sort */
    int n=0;
    do //注意这步,如果是while循环,则需要提前输出
    { if(n == 1654) {
    for(int i=0;i<7;++i)
    cout<<ans[i];
    cout<<endl;
    break;
    }
    n++;
    }
    while(next_permutation(ans,ans+7));
    return 0; }
    ```

    2. 给定一种排列,如何算出这是第几个排列呢?

    和前一个问题的推导过程相反。例如3267514:

    后6位的全排列为6!,3为{1, 2, 3 ,4 , 5, 6, 7}中第2个元素(从0开始计数),故2*720=1440;

    后5位的全排列为5!,2为{1, 2, 4, 5, 6, 7}中第1个元素,故1*5!=120;

    后4位的全排列为4!,6为{1, 4, 5, 6, 7}中第3个元素,故3*4!=72;

    后3位的全排列为3!,7为{1, 4, 5, 7}中第3个元素,故3*3!=18;

    后2位的全排列为2!,5为{1, 4, 5}中第2个元素,故2*2!=4;

    最后2位为增序,因此计数0,求和得:1440+120+72+18+4=1654

    这个的代码实现,可以用一个数组a保存3267514,然后while调用next_permutation(),用n计数,每次与数组a比较,相等则输出n;

  • 相关阅读:
    Java实现 蓝桥杯VIP 算法训练 校门外的树
    Java实现 蓝桥杯VIP 算法训练 统计单词个数
    Java实现 蓝桥杯VIP 算法训练 统计单词个数
    Java实现 蓝桥杯VIP 算法训练 开心的金明
    Java实现 蓝桥杯VIP 算法训练 开心的金明
    Java实现 蓝桥杯 算法训练 纪念品分组
    Java实现 蓝桥杯 算法训练 纪念品分组
    Java实现 蓝桥杯VIP 算法训练 校门外的树
    Java实现 蓝桥杯VIP 算法训练 统计单词个数
    Java实现 蓝桥杯VIP 算法训练 开心的金明
  • 原文地址:https://www.cnblogs.com/ACMerLwy/p/11262989.html
Copyright © 2011-2022 走看看