【cpp】 STL排列组合方法next_permutation 以及 prev_permutation

【cpp】 STL排列组合方法next_permutation 以及 prev_permutation

  1. 首先排列组合要解决的是什么问题?
    高中的时候我们就学过排列组合,{0,1,2,3,4,5,6,7,8,9}, 这些数字每次拿出3个,一共可以拿出多少种组合?
    用C3↑10↓ 这种来计算一共有 (10 * 9 * 8) / (3 * 2 * 1) = 120 种拿法
  2. 在实际的项目中应用
    这次项目需要一些设备做一个编码处理 : 把国标编码转换为 16位选4位,这四位是-1或者1,其他12位为0,的数组,所有的可能的组合方式计算下来:
    四位-1或者1 的组合一共有 五种组合方式,再搭配上12位0
    {-1,-1,-1,-1} 和 12位 0 组合方式:1820
    {-1,1,-1,-1} 和 12位 0 组合方式:1820 * c1↑4↓ = 7280
    {-1,-1,1,1} 和 12位 0 组合方式:1820 * c2↑4↓ = 10920
    {-1,1,1,1} 和 12位 0 组合方式:1820 * c1↑4↓ = 7280
    {1,1,1,1} 和 12位 0 组合方式:1820
    一共是 29120中组合方式,也就是说可以用{0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1}这样的数组,这样就可以编码 29120种设备

再说回stl的全排列函数next_permutation 以及 prev_permutation

        std::vector<float> vec{ 0,1,2,3,4,5 };
        do {
            for(auto &iter: vec ){
            	std::cout << iter << " ";
            }
            std::cout << std::endl;
        } while (next_permutation(vec.begin(), vec.begin() + 6));

如果使用上面的代码你会发现{ 0,1,2,3,4,5 } 和 { 5,2,1,3,4,0 },计算出来的排列数是不一样的,使用prev_permutation 和next_permutation 两种,结果也是不同的,这是为什么呢?
原因分析:
next_permutation 这个函数是返回所有 大于当前排列{ 5,2,1,3,4,0 }的所有排列方式,也就是说 { 5,1,2,3,4,0 } 是比{ 5,2,1,3,4,0 } 这种排列要小的,所以不会被返回 { 5,1,2,3,4,0 }这种排列方式

prev_permutation 这个函数是返回所有 小于当前排列{ 5,2,1,3,4,0 }的所有排列方式,也就是说 { 5,3,1,2,4,0 } 是比{ 5,2,1,3,4,0 } 这种排列要大的,所以不会被返回 { 5,3,1,2,4,0 } 这种排列方式

解决办法:

  1. 要使用next_permutation 的话,我们把{ 5,2,1,3,4,0 } 从小到大排序一下,这样其他所有的排列都比 排序后的{ 0,1,2,3,4,5 }要大,就可以返回所有的了
  2. 相反的要使用prev_permutation 的话,我们把{ 5,2,1,3,4,0 } 从大到小排序一下,这样其他所有的排列都比 排序后的{ 5,4,3,2,1,0 }要小,就可以返回所有的了
        std::vector<float> vec{ 5,2,1,3,4,0 };
        std::sort(vec.begin(), vec.end());//默认从小到大排序
        do {
            for(auto &iter: vec ){
            	std::cout << iter << " ";
            }
            std::cout << std::endl;
        } while (next_permutation(vec.begin(), vec.begin() + 6));
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值