相比于其它方法,此方法更加浅显易懂

  1. 全排列(递归):任意选择一个 + 剩下的全排列结果,见代码pFun()。
  2. 组合(递归):任意选择一个 + 剩下的组合的结果,要注意排除前面已经出现过的,见代码zFun()。
  3. 排列:先组合,再排列,见代码pzFun()。

相比于其它方法,此方法可能存在内存占用过多的缺点。也就是大量返回对象,或者是函数内部拷贝造成的。

#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;
}

参考资料

全排列和全组合实现_南方以北的博客-CSDN博客

链接:https://blog.csdn.net/qq_25800311/article/details/99940852

Last modification:October 30, 2022
如果觉得我的文章对你有用,请随意赞赏~