C++ combinationEntry=combination.begin();//使用迭代器填充组合 对于(int i=0;i

C++ combinationEntry=combination.begin();//使用迭代器填充组合 对于(int i=0;i,c++,algorithm,combinations,C++,Algorithm,Combinations,我的简单高效解决方案基于: //n选择r组合 #包括 #包括 #包括 结构c_唯一{ 电流; c_unique(){current=0;} int运算符(){return++current;} }单号; void myfunction(int i){ std::cout如果r很小,您可以只使用for循环,这里r=2,因此两个for循环: unsigned int i, j, max=0; for(i=1; i<=n; i++){ for(j=i+1; j<=n; j++){

我的简单高效解决方案基于:

//n选择r组合
#包括
#包括
#包括
结构c_唯一{
电流;
c_unique(){current=0;}
int运算符(){return++current;}
}单号;
void myfunction(int i){

std::cout如果r很小,您可以只使用for循环,这里r=2,因此两个for循环:

unsigned int i, j, max=0;
for(i=1; i<=n; i++){
    for(j=i+1; j<=n; j++){
            int ans = (i & j);
            cout << i << " " << j << endl;     
     }
}
无符号整数i,j,max=0;
对于(i=1;i
向量生成(int N,int K,int&count){
矢量输出;
如果(K==1){
计数=N;
for(int i=1;i back();
对于(int i=last+1;i,以下是我的尝试:

函数(准备好复制/粘贴),无任何依赖关系

 template<class _Tnumber, class _Titerator >
      bool next_combination
       (
            _Titerator const& _First
          , _Titerator const& _Last
          , _Tnumber const& _Max //!< Upper bound. Not reachable
       )
       {
        _Titerator _Current = _First;
         if( _Current  == _Last )
          {
           return false;
          }
         *_Current += 1;
         if( *_Current < _Max )
          {
           return true;
          }
        _Titerator _Next = _Current + 1;
         if( _Next == _Last )
          {
           return false;
          }
         if( false == next_combination( _Next, _Last, _Max - 1 ) )
          {
           return false;
          }
         *_Current = *_Next + 1; 
         return *_Current < _Max;
        }

这似乎是可读的,而且它也适用于
std::vector
std::list
std::deque
,甚至是静态声明的
int intArray[]

#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <list>
#include <set>
#include <iterator>

template<typename InputIt, typename T>
bool nextCombination(InputIt begin,
                     InputIt end,
                     T toElement) {
    /*
        Given sequence: 1 2 3 4 5
        Final sequence: 6 7 8 9 10

        -- Formally --
        Given sequence: 1 2 ... k-1 k
        Final sequence: (n-k+1) (n-k+2) ... (n-1) n

        lengthOfSubsequence = positionOf(5) - positionOf(1) = 5
        
        We look for an element that satisfies:
            seqeunce[pos] < n - k + pos

    */

    const auto lengthOfSubsequence = std::distance(begin, end);

    auto viewed_element_it = std::make_reverse_iterator(end);
    auto reversed_begin = std::make_reverse_iterator(begin);

    /*Looking for this element here*/

    while ((viewed_element_it != reversed_begin) && 
           (*viewed_element_it >= toElement -
                                  lengthOfSubsequence + 
                                  std::distance(viewed_element_it, reversed_begin))) {
        //std::distance shows position of element in subsequence here
        viewed_element_it++;
    }

    if (viewed_element_it == reversed_begin)
        return false;

    auto it = std::prev(viewed_element_it.base());

    /*
        Increment the found element. 
    The rest following elements we set as seqeunce[pos] = seqeunce[pos-1] + 1
    */

    std::iota(it, end, *it + 1);

    return true;
}

int main()
{
    std::list<int> vec = { 1, 2, 3 };

    do {
        std::copy(vec.begin(), vec.end(), std::ostream_iterator<int>(std::cout, " "));
        std::cout << std::endl;
    } while (nextCombination(vec.begin(), vec.end(), 10));
}

#包括
#包括
#包括
#包括
#包括
#包括
#包括
模板
布尔下一个组合(输入开始,
输入端,
T(元素){
/*
给定顺序:12345
最终顺序:678910
--正式地--
给定序列:12…k-1k
最后的顺序:(n-k+1)(n-k+2)…(n-1)n
lengthOfSubsequence=位置(5)-位置(1)=5
我们寻找满足以下条件的元素:
顺序[pos]=toElement-
长度子序列+
标准::距离(查看元素、反转元素、开始){
//距离在这里显示元素在子序列中的位置
已查看元素(it++);
}
如果(已查看元素\u it==已反转\u开始)
返回false;
auto-it=std::prev(已查看元素\u-it.base());
/*
递增找到的元素。
我们将以下其余元素设置为sequence[pos]=sequence[pos-1]+1
*/
std::物联网(it,end,*it+1);
返回true;
}
int main()
{
列表向量={1,2,3};
做{
std::copy(vec.begin()、vec.end()、std::ostream_迭代器(std::cout,“”);

STD::CUT

是C++中的一个迭代算法,<强>不使用“/强”STL,也不使用递归或条件嵌套循环,它更快,不执行任何元素交换,它不会用递归来负担堆栈,也可以通过替换<代码> MalLoCube()/<代码>,<代码> For()来轻松移植到ANSI C上。

printf()
分别用于
new
delete
std::cout


如果希望显示的元素从1开始,则更改
OutputArray()
函数。
即:
我真的不明白你想要什么。给定集合
S
和输入2,你想要数组长度为2的数组中所有2和
S
项的组合吗?你需要更具体地说明你想要什么样的组合。例如,对于S={1,2}和r=2,你想要{1,2}和{2,1},或者{1,1}和{2,2},或者甚至仅仅是{1,2}?我想他想要的是:{1,2}{2,1}是一样的,{1,1}和{2,2}不可能。对于可读的算法,您可以查看Python文档:is one google search awayIt将输出置换,而不是问题中所述的组合。您可能会发现有帮助。要么我遗漏了什么,要么您遗漏了什么。请检查:@kids\u fox此代码是正确的,它确实生成了组合它之所以有效,是因为它打印了所有排序的排列。我以一种通用形式重写了这段代码:你可以得到“更易于遵循的顺序”,而不必将if(v[I])
倒置为if(v[I])
检查你是否从
v.begin()
填充到
v.end()-n+r
,而不是
v.begin()+n-r
v.end()
。这包括相同组合的不同排列,请尝试修改第二个循环
,以便(int j=i+1;j这是最快、最简单、最干净的非递归算法。递归在这里并没有增加清晰度,可能更慢。它之所以干净,是因为它是硬编码的,可以处理从1到N的值。否则与更通用的算法完全相同。应该使用递归从堆中查找内存是耗时的操作您可以在堆栈上创建它。@DejanM:堆栈内存比堆内存少。无论如何,请注意,内存分配只发生一次。
#include <iostream>
#include <iterator>
#include <vector>
#include <cstdlib>

using namespace std;

struct combinations
{
    typedef vector<int> combination_t;

    // initialize status
   combinations(int N, int R) :
       completed(N < 1 || R > N),
       generated(0),
       N(N), R(R)
   {
       for (int c = 1; c <= R; ++c)
           curr.push_back(c);
   }

   // true while there are more solutions
   bool completed;

   // count how many generated
   int generated;

   // get current and compute next combination
   combination_t next()
   {
       combination_t ret = curr;

       // find what to increment
       completed = true;
       for (int i = R - 1; i >= 0; --i)
           if (curr[i] < N - R + i + 1)
           {
               int j = curr[i] + 1;
               while (i <= R-1)
                   curr[i++] = j++;
               completed = false;
               ++generated;
               break;
           }

       return ret;
   }

private:

   int N, R;
   combination_t curr;
};

int main(int argc, char **argv)
{
    int N = argc >= 2 ? atoi(argv[1]) : 5;
    int R = argc >= 3 ? atoi(argv[2]) : 2;
    combinations cs(N, R);
    while (!cs.completed)
    {
        combinations::combination_t c = cs.next();
        copy(c.begin(), c.end(), ostream_iterator<int>(cout, ","));
        cout << endl;
    }
    return cs.generated;
}
1,2,
1,3,
1,4,
1,5,
2,3,
2,4,
2,5,
3,4,
3,5,
4,5,
          #include<iostream>
          using namespace std;

          for(int i=1;i<=5;i++)
             for (int j=2;j<=5;j++) 
                if (i!=j)
                  cout<<i<<","<<j<<","<<endl;

           //or instead of cout... you can put them in a matrix n x 2 and use the solution
#include<stdio.h>

// a[] : given array of chars 
// perm[] : perm[i] is 1 if a[i] is considered, else 0
// index : subscript of perm which is to be 0ed and 1ed
// n     : length of the given input array
// k     : length of the permuted string
void combinate(char a[], int perm[],int index, int n, int k)
{
   static int count = 0;

   if( count == k )
   { 
      for(int i=0; i<n; i++)
        if( perm[i]==1)
          printf("%c",a[i]);
      printf("\n");

    } else if( (n-index)>= (k-count) ){

         perm[index]=1;
         count++;
         combinate(a,perm,index+1,n,k);

         perm[index]=0;
         count--;
         combinate(a,perm,index+1,n,k);

   }
}
int main()
{
   char a[] ={'a','b','c','d'};
   int perm[4] = {0};
   combinate(a,perm,0,4,3);

   return 0;
}
void print(int *a, int* s, int ls)
{
    for(int i = 0; i < ls; i++)
    {
        cout << a[s[i]] << " ";
    }
    cout << endl;
}    
void PrintCombinations(int *a, int l, int k, int *s, int ls, int sp)
{
   if(k == 0)
   {
       print(a,s,ls);
       return;
   }
   for(int i = sp; i < l; i++)
   {

      s[k-1] = i;
      PrintCombinations(a,l,k-1,s,ls,i+1);
      s[k-1] = -1;

   }
}

int main()
{
 int e[] = {1,2,3,4,5,6,7,8,9};
 int s[] = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
 PrintCombinations(e,9,6,s,6,0);
}
//combinations.hpp
#include <vector>

template<typename T> class Combinations {
// Combinations(std::vector<T> s, int m) iterate all Combinations without repetition
// from set s of size m s = {0,1,2,3,4,5} all permuations are: {0, 1, 2}, {0, 1,3}, 
// {0, 1, 4}, {0, 1, 5}, {0, 2, 3}, {0, 2, 4}, {0, 2, 5}, {0, 3, 4}, {0, 3, 5},
// {0, 4, 5}, {1, 2, 3}, {1, 2, 4}, {1, 2, 5}, {1, 3, 4}, {1, 3, 5}, {1, 4, 5}, 
// {2, 3, 4}, {2, 3, 5}, {2, 4, 5}, {3, 4, 5}

public:
    Combinations(std::vector<T> s, int m) : M(m), set(s), partial(std::vector<T>(M))
    {
        N = s.size(); // unsigned long can't be casted to int in initialization

        out = std::vector<std::vector<T>>(comb(N,M), std::vector<T>(M)); // allocate space

        generate(0, N-1, M-1);
    };

    typedef typename std::vector<std::vector<T>>::const_iterator const_iterator;
    typedef typename std::vector<std::vector<T>>::iterator iterator;
    iterator begin() { return out.begin(); }
    iterator end() { return out.end(); }    
    std::vector<std::vector<T>> get() { return out; }

private:
    void generate(int i, int j, int m);
    unsigned long long comb(unsigned long long n, unsigned long long k); // C(n, k) = n! / (n-k)!

    int N;
    int M;
    std::vector<T> set;
    std::vector<T> partial;
    std::vector<std::vector<T>> out;   

    int count (0); 
};

template<typename T> 
void Combinations<T>::generate(int i, int j, int m) {  
    // combination of size m (number of slots) out of set[i..j]
    if (m > 0) { 
        for (int z=i; z<j-m+1; z++) { 
            partial[M-m-1]=set[z]; // add element to permutation
            generate(z+1, j, m-1);
        }
    } else {
        // last position
        for (int z=i; z<j-m+1; z++) { 
            partial[M-m-1] = set[z];
            out[count++] = std::vector<T>(partial); // add to output vector
        }
    }
}

template<typename T> 
unsigned long long
Combinations<T>::comb(unsigned long long n, unsigned long long k) {
    // this is from Knuth vol 3

    if (k > n) {
        return 0;
    }
    unsigned long long r = 1;
    for (unsigned long long d = 1; d <= k; ++d) {
        r *= n--;
        r /= d;
    }
    return r;
}
// test.cpp
// compile with: gcc -O3 -Wall -std=c++11 -lstdc++ -o test test.cpp
#include <iostream>
#include "combinations.hpp"

struct Bla{
    float x, y, z;
};

int main() {

    std::vector<int> s{0,1,2,3,4,5};
    std::vector<Bla> ss{{1, .4, 5.0},{2, .7, 5.0},{3, .1, 2.0},{4, .66, 99.0}};

    Combinations<int> c(s,3);
    // iterate over all combinations
    for (auto x : c) { for (auto ii : x) std::cout << ii << ", "; std::cout << "\n"; }

    // or get a vector back
    std::vector<std::vector<int>> z = c.get();  

    std::cout << "\n\n";

    Combinations<Bla> cc(ss, 2);
    // combinations of arbitrary objects
    for (auto x : cc) { for (auto b : x) std::cout << "(" << b.x << ", " << b.y << ", " << b.z << "), "; std::cout << "\n"; }    

}
// example 1: choose each 2 from given vector and apply 'doSomething'
void doOnCombinationsOfTwo(const std::vector<T> vector) {
   for (int i1 = 0; i1 < vector.size() - 1; i1++) {
      for (int i2 = i1 + 1; i2 < vector.size(); i2++) {
         doSomething( { vector[i1], vector[i2] });
      }
   }
}


// example 2: choose each n-2 from given vector and apply 'doSomethingElse'
void doOnCombinationsOfNMinusTwo(const std::vector<T> vector) {
   std::vector<T> combination(vector.size() - 2); // let's reuse our combination vector 
   for (int i1 = 0; i1 < vector.size() - 1; i1++) {
      for (int i2 = i1 + 1; i2 < vector.size(); i2++) {
         auto combinationEntry = combination.begin(); // use iterator to fill combination
         for (int i = 0; i < vector.size(); i++) {
            if (i != i1 && i != i2) {
               *combinationEntry++ = i;
            }
         }
         doSomethingElse(combinationVector);
      }
   }
}
// n choose r combination
#include <vector>
#include <iostream>
#include <algorithm>

struct c_unique {
  int current;
  c_unique() {current=0;}
  int operator()() {return ++current;}
} UniqueNumber;

void myfunction (int i) {
  std::cout << i << ' ';
}

int main()
{
    int n=5;
    int r=3;

    std::vector<int> myints(r);
    std::vector<int>::iterator first = myints.begin(), last = myints.end();

    std::generate(first, last, UniqueNumber);

    std::for_each(first, last, myfunction);
    std::cout << std::endl;

    while((*first) != n-r+1){
        std::vector<int>::iterator mt = last;

        while (*(--mt) == n-(last-mt)+1);
        (*mt)++;
        while (++mt != last) *mt = *(mt-1)+1;

        std::for_each(first, last, myfunction);
        std::cout << std::endl;
    }
}
unsigned int i, j, max=0;
for(i=1; i<=n; i++){
    for(j=i+1; j<=n; j++){
            int ans = (i & j);
            cout << i << " " << j << endl;     
     }
}
vector<list<int>> generate(int N, int K, int& count) {

    vector<list<int>> output;

    if(K == 1) {
        count = N;
        for(int i = 1; i <= N; i++) {
            list<int> l = {i};
            output.push_back(l);
        }
    } else {
        count = 0;
        int n;
        vector<list<int>> l = generate(N, K - 1, n);
        for(auto iter = l.begin(); iter != l.end(); iter++) {
            int last = iter->back();
            for (int i = last + 1; i <= N; ++i) {
                list<int> value = *iter;
                value.push_back(i);
                output.push_back(value);
                count++;
            }
        }
    }

    return output;
}
 template<class _Tnumber, class _Titerator >
      bool next_combination
       (
            _Titerator const& _First
          , _Titerator const& _Last
          , _Tnumber const& _Max //!< Upper bound. Not reachable
       )
       {
        _Titerator _Current = _First;
         if( _Current  == _Last )
          {
           return false;
          }
         *_Current += 1;
         if( *_Current < _Max )
          {
           return true;
          }
        _Titerator _Next = _Current + 1;
         if( _Next == _Last )
          {
           return false;
          }
         if( false == next_combination( _Next, _Last, _Max - 1 ) )
          {
           return false;
          }
         *_Current = *_Next + 1; 
         return *_Current < _Max;
        }
vector<int> vec({3,2,1}); // In descending order and different
do
 {
  copy( vec.begin(), vec.end(), ostream_iterator<int>(cout, ", " ) ); cout << endl;
 }while( ::math::algorithm::next_combination( vec.begin(), vec.end(), 6 ) );
3, 2, 1,
4, 2, 1,
5, 2, 1,
4, 3, 1,
5, 3, 1,
5, 4, 1,
4, 3, 2,
5, 3, 2,
5, 4, 2,
5, 4, 3,
#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <list>
#include <set>
#include <iterator>

template<typename InputIt, typename T>
bool nextCombination(InputIt begin,
                     InputIt end,
                     T toElement) {
    /*
        Given sequence: 1 2 3 4 5
        Final sequence: 6 7 8 9 10

        -- Formally --
        Given sequence: 1 2 ... k-1 k
        Final sequence: (n-k+1) (n-k+2) ... (n-1) n

        lengthOfSubsequence = positionOf(5) - positionOf(1) = 5
        
        We look for an element that satisfies:
            seqeunce[pos] < n - k + pos

    */

    const auto lengthOfSubsequence = std::distance(begin, end);

    auto viewed_element_it = std::make_reverse_iterator(end);
    auto reversed_begin = std::make_reverse_iterator(begin);

    /*Looking for this element here*/

    while ((viewed_element_it != reversed_begin) && 
           (*viewed_element_it >= toElement -
                                  lengthOfSubsequence + 
                                  std::distance(viewed_element_it, reversed_begin))) {
        //std::distance shows position of element in subsequence here
        viewed_element_it++;
    }

    if (viewed_element_it == reversed_begin)
        return false;

    auto it = std::prev(viewed_element_it.base());

    /*
        Increment the found element. 
    The rest following elements we set as seqeunce[pos] = seqeunce[pos-1] + 1
    */

    std::iota(it, end, *it + 1);

    return true;
}

int main()
{
    std::list<int> vec = { 1, 2, 3 };

    do {
        std::copy(vec.begin(), vec.end(), std::ostream_iterator<int>(std::cout, " "));
        std::cout << std::endl;
    } while (nextCombination(vec.begin(), vec.end(), 10));
}

void OutputArray(unsigned int* ka, size_t n) {
    for (int i = 0; i < n; i++)
        std::cout << ka[i] << ",";
    std::cout << endl;
}


void GenCombinations(const unsigned int N, const unsigned int K) {
    unsigned int *ka = new unsigned int [K];  //dynamically allocate an array of UINTs
    unsigned int ki = K-1;                    //Point ki to the last elemet of the array
    ka[ki] = N-1;                             //Prime the last elemet of the array.

    while (true) {
        unsigned int tmp = ka[ki];  //Optimization to prevent reading ka[ki] repeatedly

        while (ki)                  //Fill to the left with consecutive descending values (blue squares)
            ka[--ki] = --tmp;
        OutputArray(ka, K);

        while (--ka[ki] == ki) {    //Decrement and check if the resulting value equals the index (bright green squares)
            OutputArray(ka, K);
            if (++ki == K) {      //Exit condition (all of the values in the array are flush to the left)
                delete[] ka;
                return;
            }
        }
    }
}


int main(int argc, char *argv[])
{
    GenCombinations(7, 4);
    return 0;
}