You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

固定样本空间排列算法:求10个对象取5个的全排列C++代码

生成从10个对象中选5个的所有排列(长度为5的排列)

嘿,我来帮你搞定这个需求!要生成从10个对象里选5个的所有排列(数学上的排列数P(10,5)=30240种),我们可以用递归的方式手动实现,或者结合标准库工具来完成。下面给你两种清晰的方案:

方案一:递归手动实现(直观易理解)

这种方法通过递归逐个填充目标数组的每个位置,同时追踪哪些元素已经被使用过,避免重复选择。逻辑清晰,适合学习和自定义扩展。

#include <iostream>
#include <vector>

using namespace std;

// 源对象集合(这里用int示例,你可以替换成字符串、自定义类等任意类型)
const vector<int> source = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
const int kTargetLength = 5; // 要生成的排列长度

// 递归生成排列
void generatePermutations(vector<int>& current, vector<bool>& used, int pos) {
    // 当当前数组填满5个元素时,输出结果
    if (pos == kTargetLength) {
        for (int num : current) {
            cout << num << " ";
        }
        cout << endl;
        return;
    }

    // 遍历所有源对象,选择未被使用的元素填充当前位置
    for (int i = 0; i < source.size(); ++i) {
        if (!used[i]) {
            used[i] = true;
            current[pos] = source[i];
            generatePermutations(current, used, pos + 1);
            used[i] = false; // *回溯逻辑*:取消标记,让后续排列可以再次选择该元素
        }
    }
}

int main() {
    vector<int> current(kTargetLength); // 存储当前生成的排列
    vector<bool> used(source.size(), false); // 标记元素是否已被使用

    generatePermutations(current, used, 0);

    return 0;
}

关键说明:

  • source:替换成你实际的10个对象即可,不管是基本类型还是自定义类型,只需调整输出打印的逻辑。
  • 递归的核心是回溯:每次选择一个元素填充当前位置后,递归处理下一个位置;递归返回后取消元素的使用标记,保证其他排列能复用该元素。

方案二:结合标准库的组合+全排列

如果想利用C++标准库的next_permutation,我们可以先生成所有5个元素的组合,再对每个组合生成全排列。虽然标准库没有直接的组合生成函数,但可以通过标记数组模拟:

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int main() {
    vector<int> source = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    const int kSelectCount = 5;
    int n = source.size();

    // 创建标记数组:前kSelectCount个为true,表示选中的元素
    vector<bool> mask(n, false);
    fill(mask.end() - kSelectCount, mask.end(), true);

    do {
        // 提取当前选中的5个元素,组成组合
        vector<int> combination;
        for (int i = 0; i < n; ++i) {
            if (mask[i]) {
                combination.push_back(source[i]);
            }
        }

        // 生成当前组合的所有全排列并输出
        sort(combination.begin(), combination.end());
        do {
            for (int num : combination) {
                cout << num << " ";
            }
            cout << endl;
        } while (next_permutation(combination.begin(), combination.end()));

    } while (next_permutation(mask.begin(), mask.end()));

    return 0;
}

关键说明:

  • mask数组的排列对应所有5元素组合:next_permutation会按字典序生成mask的下一个排列,从而遍历所有可能的元素选中情况。
  • 每个组合需要先排序,才能让next_permutation生成该组合的所有全排列。

额外提示

  • 如果你需要将结果写入文件而非控制台,只需把cout替换成文件输出流(比如ofstream)即可。
  • 两种方案都可以轻松适配非整数类型的对象,只需调整输出的打印逻辑。

内容的提问来源于stack exchange,提问作者Mahmoud Abdel-Rahman

火山引擎 最新活动