3

let's say , a course with 8 participans, i must output the first 3 places in all possible ways. ex :

123 124 125 126 127 128 213 so on..

I know there is next_permutation algorithm but it returns all the possible permuations with all the numbers (from 1 through 8), but i need first 3 places with all the participans ex:

1  2  3  4  5  6  7  8  
1  2  3  4  5  6  8  7
ddacot
  • 1,162
  • 2
  • 12
  • 38

4 Answers4

5

The things you're after are not permutations, which is why next_permutation alone won't solve your problem.

First, you need to decide whether 123 is the same as 321 or not. If they are the same, you have plain combinations. If they are different, you have k-permutations (different from plain permutations).

std::next_permutation gives you the next permutation, not the next k-permutation. There's no std::next_combination.

Fortunately, if you write your own next_combination (or find one on the internet), you can use it and std::next_permutation together to easily express the next_k_permutation algorithm.

With the correct terminology at hand it should be easy to find a solution.

n. 'pronouns' m.
  • 95,181
  • 13
  • 111
  • 206
2

This program produces the output you are looking for, not necessarily in the order you expect. If you want it in a particular order, you may need to capture the output and sort it. To see it run, 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;
}
Robᵩ
  • 143,876
  • 16
  • 205
  • 276
0

I had misunderstood your question.

What you want is not next_permutation, it is what I would call next_combination.

So, I googled this term and… link 1 (codeproject), link 2, link 3, link 4.

Community
  • 1
  • 1
Benoit
  • 70,220
  • 21
  • 189
  • 223
  • nah, it doesn't solve my problem, let me show you 124 125 126 127 128 129 **134** //why is it starting at 134 instead of 132 than 134 and so on ? – ddacot Feb 29 '12 at 15:49
  • @ddacot: so you want each permutation for each combination. – Benoit Feb 29 '12 at 16:03
0

First you need to find all NC3 combinations, then permute them to find all possible ways of ranking them.

N Choose 3, can be done by generating Banker's sequence (my fav. ) There's a neat little way to generate all NC3 combinations with logN complexity each.

Once you start getting the combinations you can permute all the 6 permutations easily with your next_permutation() call.

srbhkmr
  • 2,004
  • 1
  • 13
  • 19