使用CPP中的Vector实现(全)排列、组合

使用CPP中的Vector实现(全)排列、组合

  1. 相比于其它方法,此方法更加浅显易懂
    <1> 全排列(递归):任意选择一个 + 剩下的全排列结果,见代码pFun()
    <2> 组合(递归):任意选择一个 + 剩下的组合的结果,要注意排除前面已经出现过的,见代码zFun()
    <3> 排列:先组合,再排列,见代码pzFun()
  2. 相比于其它方法,此方法可能存在内存占用过多的缺点。也就是大量返回对象,或者是函数内部拷贝造成的。
#include <vector>
#include <iostream>

/**
 * 全排列
 */
std::vector<std::vector<int>> pFun(const std::vector<int>& a)
{
    std::vector<std::vector<int>> result;

    // 递归截至条件
    if(a.size() == 1)
    {
        result.push_back(std::vector<int>({a.front()}));
        return result;
    }

    // 一般情况
    for(int i=0; i<a.size(); ++i)
    {
        // 除去第一个元素之外的剩余元素进行全排列
        std::vector<int> b = a;
        std::vector<int>::iterator it = b.begin();
        b.erase(it + i);
        std::vector<std::vector<int>> ret = pFun(b);
        // 第一个元素+剩下的元素进行组装
        for(int j=0; j<ret.size(); ++j)
        {
            std::vector<int> one;
            one.push_back(a[i]);
            for(int k=0; k<ret[j].size(); ++k)
            {
                one.push_back(ret[j][k]);
            }
            result.push_back(one);
        }
    }
    return result;
}

/**
 * 组合
 */
std::vector<std::vector<int>> zFun(const std::vector<int>& a, int m)
{
    std::vector<std::vector<int>> result;

    // 递归截至条件
    if(m == 1)
    {
        for(int i=0; i<a.size(); ++i)
        {
            result.push_back(std::vector<int>({a[i]}));
        }
        return result;
    }

    // 一般情况
    for(int i=0; i<a.size(); ++i)
    {
        // 除去第一个元素之外的剩余元素进行选取(m-1)个
        std::vector<int> b = a;
        std::vector<int>::iterator it = b.begin();
        b.erase(it, it+i+1); // 尤其要注意这里,排列不讲究顺序,前面已经出现过的,后面就不要考虑了,12已经考虑过了,那么21就不用考虑了
        std::vector<std::vector<int>> ret = zFun(b, m-1);
        // 第一个元素+剩下的元素进行组装
        for(int j=0; j<ret.size(); ++j)
        {
            std::vector<int> one;
            one.push_back(a[i]);
            for(int k=0; k<ret[j].size(); ++k)
            {
                one.push_back(ret[j][k]);
            }
            result.push_back(one);
        }
    }
    return result;
}

/**
 * 排列:先组合,再分别全排列
 */
std::vector<std::vector<int>> pzFun(const std::vector<int>& a, int m)
{
    std::vector<std::vector<int>> result;
    std::vector<std::vector<int>> z_result = zFun(a, m);
    for(int i=0; i<z_result.size(); ++i)
    {
        std::vector<std::vector<int>> ret = pFun(z_result[i]);
        for(int j=0; j<ret.size(); ++j)
        {
            result.push_back(ret[j]);
        }
    }
    return result;
}

int main()
{
    std::vector<int> arr = {1,2,3,4};
    // std::vector<std::vector<int>> ret = pFun(arr);
    // std::vector<std::vector<int>> ret = zFun(arr, 2);
    std::vector<std::vector<int>> ret = pzFun(arr, 3);
    for(std::vector<int>& v : ret)
    {
        for(int ele : v)
        {
            std::cout << ele << " ";
        }
        std::cout << std::endl;
    }
    return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值