gpt4 book ai didi

c++ - 如何从一组 k 个元素生成长度为 n 的所有排列?

转载 作者:行者123 更新时间:2023-12-02 19:32:18 25 4
gpt4 key购买 nike

例如,我有这组k=5元素[1,2,3,4,5],我想要长度n的所有排列=2.

1,2
1,3
1,4
1,5
2,1
etc etc.

问题是我无法使用 STL、外部数学库等。

我尝试的是使用堆算法生成所有元素的所有排列,然后包含在所有 k 排列的前 n 个数字中的 n 个元素的所有排列,我可以截断并删除重复项,但随后复杂性太高了(n!)

我知道这个问题有一个很好的解决方案,因为我已经看到在有关排列字符串的问题中使用额外的模块/库来完成此问题。

额外信息:我只需要这个来暴力破解不平衡分配问题,而当我被允许“暴力破解”问题时,匈牙利算法似乎太长了。我的方法没有接近允许的执行时间,因为当我有一个例如大小为 8x3 的数组时,我的算法需要 8!当它肯定可以优化到更小的数字时进行比较。

最佳答案

我认为你可以分两步完成,首先,从一组 n 中生成 k 元素的组合,然后打印每个组合的排列。我测试了这段代码并且工作正常:

#include <iostream>
using namespace std;

void printArr(int a[], int n, bool newline = true) {
for (int i=0; i<n; i++) {
if (i > 0) cout << ",";
cout << a[i];
}
if (newline) cout << endl;
}

// Generating permutation using Heap Algorithm
void heapPermutation(int a[], int n, int size) {
// if size becomes 1 then prints the obtained permutation
if (size == 1) {
printArr(a, n);
return;
}

for (int i=0; i<size; i++) {
heapPermutation(a, n, size-1);
// if size is odd, swap first and last element, otherwise swap ith and last element
swap(a[size%2 == 1 ? 0 : i], a[size-1]);
}
}

// Generating permutation using Heap Algorithm
void heapKPermutation(int a[], int n, int k, int size) {
// if size becomes 1 then prints the obtained permutation
if (size == n - k + 1) {
printArr(a + n - k, k);
return;
}

for (int i=0; i<size; i++) {
heapKPermutation(a, n, k, size-1);
// if size is odd, swap first and last element, otherwise swap ith and last element
swap(a[size%2 == 1 ? 0 : i], a[size-1]);
}
}

void doKCombination(int a[], int n, int p[], int k, int size, int start) {
int picked[size + 1];
for (int i = 0; i < size; ++i) picked[i] = p[i];
if (size == k) {
// We got a valid combination, use the heap permutation algorithm to generate all permutations out of it.
heapPermutation(p, k, k);
} else {
if (start < n) {
doKCombination(a, n, picked, k, size, start + 1);
picked[size] = a[start];
doKCombination(a, n, picked, k, size + 1, start + 1);
}
}
}

// Generate combination of k elements out of a set of n
void kCombination(int a[], int n, int k) {
doKCombination(a, n, nullptr, k, 0, 0);
}

int main()
{
int a[] = {1, 2, 3, 4, 5};
cout << "n=1, k=1, a=";
printArr(a, 1);
kCombination(a, 1, 1);

cout << "n=2, k=1, a=";
printArr(a, 2);
kCombination(a, 2, 1);

cout << "n=3, k=2, a=";
printArr(a, 3);
kCombination(a, 3, 2);

cout << "n=5, k=2, a=";
printArr(a, 5);
kCombination(a, 5, 2);
return 0;
}

结果是:

n=1, k=1, a=1
1
n=2, k=1, a=1,2
2
1
n=3, k=2, a=1,2,3
2,3
3,2
1,3
3,1
1,2
2,1
n=5, k=2, a=1,2,3,4,5
4,5
5,4
3,5
5,3
3,4
4,3
2,5
5,2
2,4
4,2
2,3
3,2
1,5
5,1
1,4
4,1
1,3
3,1
1,2
2,1

关于c++ - 如何从一组 k 个元素生成长度为 n 的所有排列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61592209/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com