假设有一门课程有8个参与者,我必须以所有可能的方式输出前3名。 例如:
123 124 125 126 127 128 213 等等...
我知道有“下一个排列”算法,但它返回所有可能的排列,包括1到8的所有数字,但我需要包含所有参与者的前三名。
1 2 3 4 5 6 7 8
1 2 3 4 5 6 8 7
假设有一门课程有8个参与者,我必须以所有可能的方式输出前3名。 例如:
123 124 125 126 127 128 213 等等...
我知道有“下一个排列”算法,但它返回所有可能的排列,包括1到8的所有数字,但我需要包含所有参与者的前三名。
1 2 3 4 5 6 7 8
1 2 3 4 5 6 8 7
这个程序可以产生你想要的输出结果,但不一定按照你期望的顺序。如果你希望按特定顺序输出,可能需要先捕获输出然后进行排序。点击这里查看运行示例。
#include <algorithm>
#include <iostream>
template <typename Iterator>
inline bool next_combination(Iterator first,
Iterator k,
Iterator last);
int main () {
int array[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
do {
do {
std::cout << array[0] << array[1] << array[2] << "\n";
} while(std::next_permutation(array, array+3));
} while(next_combination(array,array+3,array+8));
}
template <typename Iterator>
inline bool next_combination(const Iterator first, Iterator k, const Iterator last)
{
/* Credits: Thomas Draper */
// https://dev59.com/Cm445IYBdhLWcg3wAFcC#5097100
if ((first == last) || (first == k) || (last == k))
return false;
Iterator itr1 = first;
Iterator itr2 = last;
++itr1;
if (last == itr1)
return false;
itr1 = last;
--itr1;
itr1 = k;
--itr2;
while (first != itr1)
{
if (*--itr1 < *itr2)
{
Iterator j = k;
while (!(*itr1 < *j)) ++j;
std::iter_swap(itr1,j);
++itr1;
++j;
itr2 = k;
std::rotate(itr1,j,last);
while (last != j)
{
++j;
++itr2;
}
std::rotate(k,itr2,last);
return true;
}
}
std::rotate(first,k,last);
return false;
}
首先,您需要找到所有的NC3组合,然后对它们进行排列,以找到所有可能的排名方式。
N选3可以通过生成 Banker's sequence(我最喜欢的)来完成。有一种巧妙的方法可以每次使用logN复杂度生成所有NC3组合。
一旦您开始获得组合,您可以轻松地使用next_permutation()调用对所有6个排列进行排列。