c ++ next_permutation算法

时间:2012-02-29 15:19:01

标签: c++ algorithm

让我们说,一个有8个参与者的课程,我必须以所有可能的方式输出前3个位置。 例如:

123 124 125 126 127 128 213 等...... ..

我知道有next_permutation算法,但它返回所有可能的pernations所有数字(从1到8),但我需要前3个地方与所有参与者 例如:

1  2  3  4  5  6  7  8  
1  2  3  4  5  6  8  7

4 个答案:

答案 0 :(得分:5)

你所追求的东西不是排列,这就是next_permutation单独无法解决问题的原因。

首先,您需要确定123是否与321相同。如果它们相同,那么您可以使用combinations。如果它们不同,则为k-permutations(与普通排列不同)。

std::next_permutation为您提供下一个排列,而不是下一个k排列。没有std::next_combination

幸运的是,如果您自己编写next_combination(或在互联网上找到一个),则可以将其与std::next_permutation一起使用,以便轻松表达next_k_permutation算法。

如果手边有正确的术语,应该很容易找到解决方案。

答案 1 :(得分:2)

此程序生成您正在查找的输出,而不一定按您期望的顺序。如果您希望按特定顺序进行,则可能需要捕获输出并对其进行排序。要查看它,look here

#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 */
   // http://stackoverflow.com/a/5097100/8747
   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;
}

答案 2 :(得分:0)

我误解了你的问题。

你想要的不是next_permutation,这就是我所说的next_combination。

所以,我用Google搜索了这个词...... link 1(codeproject),link 2link 3link 4

答案 3 :(得分:0)

首先,您需要找到所有NC3组合,然后置换它们以找到所有可能的排名方式。

N选择3,可以通过生成Banker's sequence(我的收藏夹)来完成。有一个简洁的方法来生成每个具有logN复杂度的所有NC3组合。

一旦开始获得组合,您可以使用next_permutation()调用轻松地置换所有6个排列。