固定样本空间排列算法:求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




