Use of a functor on for_each - c++

Why does the for_each call on functor doesn't update sum::total at the end?
struct sum
{
sum():total(0){};
int total;
void operator()(int element)
{
total+=element;
}
};
int main()
{
sum s;
int arr[] = {0, 1, 2, 3, 4, 5};
std::for_each(arr, arr+6, s);
cout << s.total << endl; // prints total = 0;
}

for_each takes the functor by value - so it is copied. You can e.g. use a functor which is initialized with a pointer to an external int.
struct sum
{
sum(int * t):total(t){};
int * total;
void operator()(int element)
{
*total+=element;
}
};
int main()
{
int total = 0;
sum s(&total);
int arr[] = {0, 1, 2, 3, 4, 5};
std::for_each(arr, arr+6, s);
cout << total << endl; // prints total = 15;
}
Or you can use the return value from for_each
struct sum
{
sum():total(0){};
int total;
void operator()(int element)
{
total+=element;
}
};
int main()
{
sum s;
int arr[] = {0, 1, 2, 3, 4, 5};
s = std::for_each(arr, arr+6, s);
cout << s.total << endl; // prints total = 15;
}

for_each receives a copy of your functor by value. Even after that, it's free to copy it, but does return a copy.
OTOH, you're simply trying to re-invent std::accumulate, which will do the job much more easily:
int total = std::accumulate(arr, arr+6, 0);
cout << total << endl;

Because the s which you pass to the for_each is by value. for_each accepts it by value!
In C++0x, you can solve this problem with for_each as,
int sum = 0;
std::for_each(arr, arr+6, [&](int n){ sum += n; });
std::cout << sum ;
Output:
15
Demo at ideone : http://ideone.com/s7OOn
Or you can simple write in the std::cout itself:
std::cout<<std::for_each(arr,arr+6,[&](int n)->int{sum += n;return sum;})(0);
Run : http://ideone.com/7Hyla
Note such different syntax is okay for learning purpose, as to how std::for_each works, and what it returns, but I would not recommend this syntax in real code. :-)
In C++, you can write user-defined conversion function in the functor as,
struct add
{
int total;
add():total(0){};
void operator()(int element) { total+=element; }
operator int() { return total ; }
};
int main()
{
int arr[] = {0, 1, 2, 3, 4, 5};
int sum = std::for_each(arr, arr+6, add());
std::cout << sum;
}
It's slightly different version from Erik second solution : http://ideone.com/vKnmA

This happens due to std::for_each requires the functor to be passed by value .
A workaround for your solution:
struct sum
{
sum():total(0){};
int total;
sum(sum & temp)
{
total = temp.total;
}
void operator()(int element)
{
total+=element;
}
};
int main()
{
sum s;
int arr[] = {0, 1, 2, 3, 4, 5};
s = std::for_each(arr, arr+6, s); // result of for_each assigned back to s
cout << s.total << endl; // prints total = 0;
}

std::ref() is also another option if you want your object state gets updated after std::for_each
struct Sum
{
int total = 0;
void operator()(int i) { total += i; }
};
int main()
{
int arr[] = { 0, 1, 2, 3, 4, 5 };
Sum obj1;
Sum t1 = std::for_each(arr, arr + 6, obj1); // t1.total = 15
// (Note: obj1.total = 0 bcos it is passed by value)
Sum obj2;
std::for_each(arr, arr + 6, std::ref(obj2)); // obj2.total = 15 (NO copy)
Sum t2 = std::for_each(arr, arr + 6, Sum()); // t2.total = 15
}

Related

overload operator & to produce sum of int[][]

it's a test from some company.
overload & to return sum of int[][]
main()
{
int arr[5][5];
// initialization
cout << &arr; // output the sum of arr
}
I try this code but returns compile error:
long operator &(int** arr)
{
// return the sum of arr
}
error: the argument should contains class type or enumeration
currently I understand this error, but how to overload operator for buildin types?
Example of overloading operator &, only for educational use!
I would NOT recommend overloading operator& in any serious code.
#include <iostream>
struct my_array
{
my_array()
{
for (int i = 0; i < 5; ++i)
{
for (int j = 0; j < 5; ++j)
{
values[i][j] = 1 + i + j;
}
}
}
int operator&()
{
int sum = 0;
for (int i = 0; i < 5; ++i)
{
for (int j = 0; j < 5; ++j)
{
sum += values[i][j];
}
}
return sum;
}
private:
int values[5][5]{};
};
int main()
{
my_array m;
int sum = &m;
std::cout << sum;
}
I think interviewer may want you to overload operator<< actually, not & and the solution could then be like below. See it live here.
#include <iostream>
using int5x5_t = int[5][5];
std::ostream& operator<<(std::ostream& os, const int5x5_t* parr) {
long sum = 0;
for (auto& vec : *parr) {
for (auto val : vec) {
sum += val;
}
}
return os << sum;
}
int main() {
int arr[5][5] = {
{0, 1, 2, 3, 4},
{0, 1, 2, 3, 4},
{0, 1, 2, 3, 4},
{0, 1, 2, 3, 4},
{0, 1, 2, 3, 4}
};
std::cout << &arr << std::endl;
}

insertElement() function doesn't work as intended

I'm having an issue in my program with my insertElement() function. What I had intended insertElement to do is to take the index from the prototype and move all the values to the right, including the value on that index, to the right ONCE. So, If I were to have my array {1, 2, 3, 4} and I wanted to insert the value "10" at the index "2", the resulting array would be {1, 2, 10, 3, 4}.
I know I'd have to tweak my insertElement() function to fix this issue, but I'm not sure where to start, could anybody give me a hand? Here is my code:
#include <iostream>
using namespace std;
const int CAPACITY = 20;
void displayArray(int array[], int numElements)
{
for (int i = 0; i < numElements; i++)
cout << array[i] << " ";
cout << endl;
}
bool insertElement(int array[], int& numberElements, int insertPosition, int insertTarget)
{
int p = 0;
int j = 1;
int arrayPositionFromLast = (numberElements-1);
if (numberElements>=CAPACITY)
{
cout << "Cannot insert an element, array is full." << endl;
return false;
} else {
for (int i=arrayPositionFromLast; i>insertPosition; i--)
{
array[arrayPositionFromLast-p]=array[arrayPositionFromLast-j];
p++;
j++;
}
array[insertPosition] = insertTarget;
}
return true;
}
int main()
{
int array[6] = {1, 2, 3, 4, 5, 6};
int numArrayElements = 6;
int endOfArrayValue, insertedValue, insertedValuePosition;
cout << "Enter a value and a position to insert: ";
cin >> insertedValue >> insertedValuePosition;
insertElement(array, numArrayElements, insertedValuePosition, insertedValue);
displayArray(array, numArrayElements);
}
first you should define your array with CAPACITY
int array[CAPACITY] = {1, 2, 3, 4, 5, 6};
You can move your data with memmove.
if (numberElements>=CAPACITY)
{
cout << "Cannot insert an element, array is full." << endl;
return false;
} else {
memmove(array + insertPosition+ 1, array + insertPosition, (numberElements - insertPosition) * sizeof (int));
array[insertPosition] = insertTarget;
}

How do I make a set where elements are sorted using a local variable?

How do I make a set where the elements are always ordered using some local variable?
A simplified example of what I am trying to do is this.
int x[5] {9, 2, 3, 1, 8};
set<int, ???> my_set;
my_set.insert(0);
my_set.insert(1);
my_set.insert(4);
for (int a : my_set)
cout << a << " "; // I want the answer 1 4 0 because x[1] < x[4] < x[0]
I think I might be able to do this using a struct, but I am unsure how the use of x changes things.
You can set it up like so with a lambda
int x[5] {9, 2, 3, 1, 8};
auto comparator = [&](int a, int b){ return x[a] < x[b]; };
std::set<int, decltype(comparator)> my_set(comparator);
Well since you're "pairing" elements, why not use an std::pair?
#include <iostream>
#include <set>
int main()
{
int order[5] {9, 2, 3, 1, 8};
int data[3] {0, 1, 4};
std::set<std::pair<int, int>> s;
for (std::size_t i = 0; i < 3; ++i)
{
s.emplace(order[i], data[i]);
}
for (auto a : s)
std::cout << a.second << " ";
}
This outputs 1 4 0 as expected.
voila!
#include <set>
#include <iostream>
int main()
{
int x[5] {9, 2, 3, 1, 8};
struct indirect_less
{
indirect_less(const int* p) : _p(p) {}
bool operator()(int l, int r) const {
return _p[l] < _p[r];
}
const int* _p;
};
std::set<int, indirect_less> my_set { indirect_less(x) };
my_set.insert(0);
my_set.insert(1);
my_set.insert(4);
for (int a : my_set) {
std::cout << a << " "; // I want the answer 1 4 0 because x[1] < x[4] < x[0]
}
std::cout << std::endl;
}
expected output:
1 4 0
you can use a pair and sort this elements by y and the pair in x always has the reference example
pair<0,9>
pair<1,2>
pair<2,3>
SORTED
pair<1,2>
pair<2,3>
pair<0,9>

Getting error on function call

void main()
{
int a2[] = {1};
int a3[] = {1, 2};
int a4[] = {1, 2, 3};
int a5[] = {1, 2, 3, 4};
int a6[] = {3, 3, 4, 4};
int a7[] = {3, 2, 3, 4};
int a8[] = {4, 1, 2, 3};
int a9[] = {1, 1};
araay (a6,3);
}
void araay(int arg[], int length)
{
int sumEven = 0;
int sumOdd = 0;
for (int i=0; i<=length; i++)
{
if (arg[i]%2 == 0)
sumEven += arg[i];
else
sumOdd += arg[i];
}
cout << sumOdd - sumEven;
}
This my code for that takes an array of integers as an argument and returns a value based on the sums of the even and odd numbers in the array but the error i am getting is
araay identifier is not found
Simply put
void araay(int arg[], int length);
before main() { ... to declare your function.
In your code you have only definition of your function araay(...). You need to add declaration of this function before main() to provide information about function aray(...) for main().
You always must put at least declaration of function before main() to be able use it in main(). Declaration of function before main() can be combine with its definition.
You need to declare your function above main before you call it. Or you can put the whole function above the main and its working fine.
void araay(int arg[], int length)
{
int sumEven = 0;
int sumOdd = 0;
for (int i=0; i<=length; i++)
{
if (arg[i]%2 == 0)
sumEven += arg[i];
else
sumOdd += arg[i];
}
cout << sumOdd - sumEven;
}
int main()
{
....
}

Generating combinations in C++

I have been searching for a source code for generating combinations using C++. I found some advanced codes for this but that is good for only specific number predefined data. Can anyone give me some hints, or perhaps, some ideas to generate a combination?
As an example, suppose the set S = { 1, 2, 3, ...., n} and we pick r= 2 out of it. The input would be n and r. In this case, the program will generate arrays of length two. So input of 5 2 would output 1 2, 1 3.
I had difficulty in constructing the algorithm. It took me a month to think about this.
A simple way using std::next_permutation:
#include <iostream>
#include <algorithm>
#include <vector>
int main() {
int n, r;
std::cin >> n;
std::cin >> r;
std::vector<bool> v(n);
std::fill(v.end() - r, v.end(), true);
do {
for (int i = 0; i < n; ++i) {
if (v[i]) {
std::cout << (i + 1) << " ";
}
}
std::cout << "\n";
} while (std::next_permutation(v.begin(), v.end()));
return 0;
}
or a slight variation that outputs the results in an easier to follow order:
#include <iostream>
#include <algorithm>
#include <vector>
int main() {
int n, r;
std::cin >> n;
std::cin >> r;
std::vector<bool> v(n);
std::fill(v.begin(), v.begin() + r, true);
do {
for (int i = 0; i < n; ++i) {
if (v[i]) {
std::cout << (i + 1) << " ";
}
}
std::cout << "\n";
} while (std::prev_permutation(v.begin(), v.end()));
return 0;
}
A bit of explanation:
It works by creating a "selection array" (v), where we place r selectors, then we create all permutations of these selectors, and print the corresponding set member if it is selected in in the current permutation of v.
You can implement it if you note that for each level r you select a number from 1 to n.
In C++, we need to 'manually' keep the state between calls that produces results (a combination): so, we build a class that on construction initialize the state, and has a member that on each call returns the combination while there are solutions: for instance
#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;
}
test output:
1,2,
1,3,
1,4,
1,5,
2,3,
2,4,
2,5,
3,4,
3,5,
4,5,
my simple and efficient solution based on algorithms from Prof. Nathan Wodarz:
// 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;
}
}
then output is:
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
#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
Code is similar to generating binary digits. Keep an extra data structure, an array perm[], whose value at index i will tell if ith array element is included or not. And also keep a count variable. Whenever count == length of combination, print elements based on perm[].
#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;
}
this is a recursive method, which you can use on any type. you can iterate on an instance of Combinations class (e.g. or get() vector with all combinations, each combination is a vector of objects. This is written in C++11.
//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 file:
// 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"; }
}
output is :
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,
(1, 0.4, 5), (2, 0.7, 5),
(1, 0.4, 5), (3, 0.1, 2),
(1, 0.4, 5), (4, 0.66, 99),
(2, 0.7, 5), (3, 0.1, 2),
(2, 0.7, 5), (4, 0.66, 99),
(3, 0.1, 2), (4, 0.66, 99),
Below is an iterative algorithm in C++ that does not use the STL nor recursion nor conditional nested loops. It is faster that way, it does not perform any element swaps and it does not burden the stack with recursion and it can also be easily ported to ANSI C by substituting mallloc(), free() and printf() for new, delete and std::cout, respectively.
If you want the displayed elements to start from 1 then change the OutputArray() function. Namely: cout << ka[i]+1... instead of cout << ka[i]....
Note that I use K instead of r.
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;
}
Combinations: Out of "7 Choose 4".
I'd suggest figuring out how you would do it on paper yourself and infer pseudocode from that. After that, you only need to decide the way to encode and store the manipulated data.
For ex:
For each result item in result array // 0, 1, ... r
For each item possible // 0, 1, 2, ... n
if current item does not exist in the result array
place item in result array
exit the inner for
end if
end for
end for
You can use recursion whereby to pick N+1 combinations you pick N combinations then add 1 to it. The 1 you add must always be after the last one of your N, so if your N includes the last element there are no N+1 combinations associated with it.
Perhaps not the most efficient solution but it should work.
Base case would be picking 0 or 1. You could pick 0 and get an empty set. From an empty set you can assume that iterators work between the elements and not at them.
Here are my attempt:
Function (ready for copy/paste) without any dependency
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;
}
Test:
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 ) );
And output:
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,
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);
}
For the special case of (n choose r), where r is a fixed constant, we can write r nested loops to arrive at the situation. Sometimes when r is not fixed, we may have another special case (n choose n-r), where r is again a fixed constant. The idea is that every such combination is the inverse of the combinations of (n choose r). So we can again use r nested loops, but invert the solution:
// 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);
}
}
}
This seems readable and also it works for std::vector, std::list, std::deque or even static declared 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));
}
One can directly compute all combinations indices in lexicographical order, like I did in following code.
These indices can be used for direct output or as pointers to any combined items as "abcde" string in second example of main() function, see output example after code.
Try it online!
#include <vector>
#include <iostream>
template <typename F>
void Combinations(size_t n, size_t k, F && out) {
if (k > n)
return;
std::vector<size_t> a(k);
for (size_t i = 0; i < k; ++i)
a[i] = i;
while (true) {
out(a);
int i = int(k) - 1;
while (i >= 0 && a[i] >= n - 1 - (k - 1 - i))
--i;
if (i < 0)
break;
for (size_t j = a[i] + 1; i < k; ++j, ++i)
a[i] = j;
}
}
int main() {
Combinations(5, 3, [](auto const & a){
for (auto i: a)
std::cout << i << " ";
std::cout << std::endl;
});
std::string s = "abcde";
Combinations(5, 3, [&](auto const & a){
for (auto i: a)
std::cout << s[i] << " ";
std::cout << std::endl;
});
}
Output:
0 1 2
0 1 3
0 1 4
0 2 3
0 2 4
0 3 4
1 2 3
1 2 4
1 3 4
2 3 4
a b c
a b d
a b e
a c d
a c e
a d e
b c d
b c e
b d e
c d e
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;
}
You can just use for loops if r is small, here r = 2, so two for loops:
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;
}
}