I have a template that uses a three-dimensional array to find the maximum. The crux of the problem is that this template must find the maximum in a one-dimensional array. We add a question with a char variable, if question = '1' = three-dimensional, if 2, then one-dimensional.
l need use template T2 for one dimensional and thee dimensional it depends of question(char)
T2 maxShablon2(T2 ***arr, const int n) {
int max = arr[0][0][0];
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
for (int k = 0; k < n; ++k) {
if (arr[i][j][k] > max) {
max = arr[i][j][k];
}
}
}
}
cout << " Our max: " << max;
}
template<std::size_t N>
using count = std::integral_constant<std::size_t, N>;
template<class T>
constexpr T maxOver( count<0> unused, T t, int n ) {
return t;
}
template<std::size_t depth, class Ptr>
constexpr auto maxOver( count<depth>, Ptr* t, int n ) {
auto max = maxOver( count<depth-1>{}, t[0], n );
for (int i = 1; i < n; ++i) {
auto candidate = maxOver( count<depth-1>{}, t[i], n );
if (candidate > max)
max = candidate;
}
return max;
}
now,
constexpr int arr[100] = {1,2,3,0};
constexpr int arr_max = maxOver( count<1>{}, arr, 100 );
static_assert(arr_max == 3);
constexpr int arr3[5][5][5] = {{{1,-1,7},{2,3,4}},{{3},{4,5,9}}};
constexpr int arr3_max = maxOver( count<3>{}, arr3, 5 );
static_assert(arr3_max == 9);
passes (Live example).
My problem is that I hit an obstacle while I was solving some exercises.
The source of the problem is that I have to write a program which sort descending an array by the number of each element's divisors, but when two element has the same number of divisors it should sort ascending those values.
My code so far:
#include <iostream>
#include <fstream>
using namespace std;
int cntDiv(int n) //get number of divisors
{
int lim = n;
int c = 0;
if(n == 1)
return 1;
for(int i = 1; i < lim; i++)
{
if(n % i == 0)
{
lim = n / i;
if(lim != i)
c++;
c++;
}
}
return c;
}
int main()
{
ifstream fin("in.txt");
int n, i, j;
fin >> n;
int v[n];
for(i = 0; i < n; i++)
fin >> v[i];
int div[n];
for(i = 0; i < n; i++)
div[i] = cntDiv(v[i]);
for(i = 0; i < n - 1; i++)
{
for(j = i + 1; j < n; j++)
{
if(div[i] < div[j] && div[i] != div[j]) //if the number of divisors are different
{
int t = v[i];
v[i] = v[j];
v[j] = t;
t = div[i];
div[i] = div[j];
div[j] = t;
}
if(div[i] == div[j] && v[i] > v[j]) //if the number of divisors are the same
{
int t = v[i];
v[i] = v[j];
v[j] = t;
}
}
}
for(i = 0; i < n; i++)
{
cout << v[i] << " ";
}
return 0;
}
In.txt:
5
12 20 4 100 13
Output:
100 12 20 4 13
Although it works fine with this one and many other. For bigger inputs it exceeds the time limit which is 0.1s. Any advice how should I rewrite the sorting? (I wrote bubble sort because I could not implement sorting array by property via quicksort)
Use an array of structures. The structure would contain the original value and a container of divisors:
struct Number_Attributes
{
int number;
std::list<int> divisors;
};
You can then write a custom comparator function and pass to std::sort:
bool Order_By_Divisors(const Number_Attributes& a,
const Number_Attributes& b)
{
return a.divisors.size() < b.divisors.size();
}
The sorting then becomes:
#define ARRAY_CAPACITY (20U)
Number_Attributes the_array[ARRAY_CAPACITY];
//...
std::sort(&array[0], &array[ARRAY_CAPACITY], Order_By_Divisors);
The generation of divisors is left as an exercise for the OP.
Reworking your code with std::sort:
std::vector<std::pair<int, int>> customSort(const std::vector<int>& v)
{
std::vector<std::pair<int, int>> ps;
ps.reserve(v.size());
// We don't have zip sort :/
// So building the pair
for (auto e : v)
{
ps.emplace_back(e, cntDiv(e));
}
std::sort(ps.begin(), ps.end(), [](const auto&lhs, const auto& rhs) {
// descending number of divisors, increasing value
return std::make_tuple(-lhs.second, lhs.first)
< std::make_tuple(-rhs.second, rhs.first);
});
return ps;
}
int main()
{
const std::vector<int> v = {12, 20, 4, 100, 13};
const auto res = customSort(v);
for(const auto& p : res)
{
std::cout << p.first << " ";
}
}
Demo
There are a lot of links on http://stackoverflow.com for how to do combinations: Generating combinations in c++ But these links presume to draw from an infinite set without repetition. When given a finite collection which does have repetition, these algorithms construct duplicates. For example you can see the accepted solution to the linked question failing on a test case I constructed here: http://ideone.com/M7CyFc
Given the input set: vector<int> row {40, 40, 40, 50, 50, 60, 100};
I expect to see:
40 40 40
40 40 50
40 40 60
40 40 100
40 50 50
40 50 60
40 50 100
40 60 100
50 50 60
50 50 100
50 60 100
Obviously I can use the old method store the output and check for duplicates as I generate, but this requires a lot of extra memory and processing power. Is there an alternative that C++ provides me?
Combinations by definition do not respect order. This frees us to arrange the numbers in any order we see fit. Most notably we can rely on to provide a combination rank. Certainly the most logical way to rank combinations is in sorted order, so we'll be depending upon our inputs being sorted.
There is already precedent for this in the standard library. For example lower_bound which we will actually use in this solution. When used generally this may however require the user to sort before passing.
The function we will write to do this will take in iterators to the sorted collection which the next combination is to be drawn from, and iterators to the current combination. We'd also need the size but that can be derived from the distance between the combination's iterators.
template <typename InputIt, typename OutputIt>
bool next_combination(InputIt inFirst, InputIt inLast, OutputIt outFirst, OutputIt outLast) {
assert(distance(inFirst, inLast) >= distance(outFirst, outLast));
const auto front = make_reverse_iterator(outFirst);
const auto back = make_reverse_iterator(outLast);
auto it = mismatch(back, front, make_reverse_iterator(inLast)).first;
const auto result = it != front;
if (result) {
auto ub = upper_bound(inFirst, inLast, *it);
copy(ub, next(ub, distance(back, it) + 1), next(it).base());
}
return result;
}
This function is written in the format of the other algorithm functions, so any container that supports bidirectional iterators can be used with it. For our example though we'll use: const vector<unsigned int> row{ 40U, 40U, 40U, 50U, 50U, 60U, 100U }; which is, necessarily, sorted:
vector<unsigned int> it{ row.cbegin(), next(row.cbegin(), 3) };
do {
copy(it.cbegin(), it.cend(), ostream_iterator<unsigned int>(cout, " "));
cout << endl;
} while(next_combination(row.cbegin(), row.cend(), it.begin(), it.end()));
Live Example
After writing this answer I've done a bit more research and found N2639 which proposes a standardized next_combination, which was:
Actively under consideration for a future TR, when work on TR2 was deferred pending
Viewed positively at the time
Due at least one more revision before any adoption
Needed some reworking to reflect the addition of C++11 language facilities
[Source]
Using N2639's reference implementation requires mutability, so we'll use: vector<unsigned int> row{ 40U, 40U, 40U, 50U, 50U, 60U, 100U };. And our example code becomes:
vector<unsigned int>::iterator it = next(row.begin(), 3);
do {
copy(row.begin(), it, ostream_iterator<unsigned int>(cout, " "));
cout << endl;
} while(next_combination(row.begin(), it, row.end()));
Live Example
You can do something like this (maybe avoiding the recursion):
#include <iostream>
#include <vector>
#include <algorithm>
using std::cout;
using std::vector;
void perm( const vector<int> &v, vector<vector<int>> &p, vector<int> &t, int k, int d) {
for ( int i = k; i < v.size(); ++i ) {
// skip the repeted value
if ( i != k && v[i] == v[i-1]) continue;
t.push_back(v[i]);
if ( d > 0 ) perm(v,p,t,i+1,d-1);
else p.push_back(t);
t.pop_back();
}
}
int main() {
int r = 3;
vector<int> row {40, 40, 40, 50, 50, 60, 100};
vector<vector<int>> pp;
vector<int> pe;
std::sort(row.begin(),row.end()); // that's necessary
perm(row,pp,pe,0,r-1);
cout << pp.size() << '\n';
for ( auto & v : pp ) {
for ( int i : v ) {
cout << ' ' << i;
}
cout << '\n';
}
return 0;
}
Which outputs:
11
40 40 40
40 40 50
40 40 60
40 40 100
40 50 50
40 50 60
40 50 100
40 60 100
50 50 60
50 50 100
50 60 100
I know, it's far from efficient, but if you get the idea you may come out with a better implementation.
Here is a class I once wrote in my university times to handle bosons. It's quite long, but it's generally usable and seems to work well. Additionally, it also gives ranking and unranking functionality. Hope that helps -- but don't ever ask me what I was doing back then ... ;-)
struct SymmetricIndex
{
using StateType = std::vector<int>;
using IntegerType = int;
int M;
int N;
StateType Nmax;
StateType Nmin;
IntegerType _size;
std::vector<IntegerType> store;
StateType state;
IntegerType _index;
SymmetricIndex() = default;
SymmetricIndex(int _M, int _N, int _Nmax = std::numeric_limits<int>::max(), int _Nmin = 0)
: SymmetricIndex(_M, _N, std::vector<int>(_M + 1, std::min(_Nmax, _N)), StateType(_M + 1, std::max(_Nmin, 0)))
{}
SymmetricIndex(int _M, int _N, StateType const& _Nmax, StateType const& _Nmin)
: N(_N)
, M(_M)
, Nmax(_Nmax)
, Nmin(_Nmin)
, store(addressArray())
, state(M)
, _index(0)
{
reset();
_size = W(M, N);
}
friend std::ostream& operator<<(std::ostream& os, SymmetricIndex const& sym);
SymmetricIndex& reset()
{
return setBegin();
}
bool setBegin(StateType& state, StateType const& Nmax, StateType const& Nmin) const
{
int n = N;
for (int i = 0; i<M; ++i)
{
state[i] = Nmin[i];
n -= Nmin[i];
}
for (int i = 0; i<M; ++i)
{
state[i] = std::min(n + Nmin[i], Nmax[i]);
n -= Nmax[i] - Nmin[i];
if (n <= 0)
break;
}
return true;
}
SymmetricIndex& setBegin()
{
setBegin(state, Nmax, Nmin);
_index = 0;
return *this;
}
bool isBegin() const
{
return _index==0;
}
bool setEnd(StateType& state, StateType const& Nmax, StateType const& Nmin) const
{
int n = N;
for (int i = 0; i < M; ++i)
{
state[i] = Nmin[i];
n -= Nmin[i];
}
for (int i = M - 1; i >= 0; --i)
{
state[i] = std::min(n + Nmin[i], Nmax[i]);
n -= Nmax[i] - Nmin[i];
if (n <= 0)
break;
}
return true;
}
SymmetricIndex& setEnd()
{
setEnd(state, Nmax, Nmin);
_index = _size - 1;
return *this;
}
bool isEnd() const
{
return _index == _size-1;
}
IntegerType index() const
{
return _index;
}
IntegerType rank(StateType const& state) const
{
IntegerType ret = 0;
int n = 0;
for (int i = 0; i < M; ++i)
{
n += state[i];
for (int k = Nmin[i]; k < state[i]; ++k)
ret += store[(n - k) * M + i];
}
return ret;
}
IntegerType rank() const
{
return rank(state);
}
StateType unrank(IntegerType rank) const
{
StateType ret(M);
int n = N;
for (int i = M-1; i >= 0; --i)
{
int ad = 0;
int k = std::min(Nmax[i] - 1, n);
for (int j = Nmin[i]; j <= k; ++j)
ad+=store[(n - j) * M + i];
while (ad > rank && k >= Nmin[i])
{
ad -= store[(n - k) * M + i];
--k;
}
rank -= ad;
ret[i] = k+1;
n -= ret[i];
if (n <= 0)
{
return ret;
}
}
return ret;
}
IntegerType size() const
{
return _size;
}
operator StateType& ()
{
return state;
}
auto operator[](int i) -> StateType::value_type& { return state[i]; }
operator StateType const& () const
{
return state;
}
auto operator[](int i) const -> StateType::value_type const& { return state[i]; }
bool nextState(StateType& state, StateType const& Nmax, StateType const& Nmin) const
{
//co-lexicographical ordering with Nmin and Nmax:
// (1) find first position which can be decreased
// then we have state[k] = Nmin[k] for k in [0,pos]
int pos = M - 1;
for (int k = 0; k < M - 1; ++k)
{
if (state[k] > Nmin[k])
{
pos = k;
break;
}
}
// if nothing found to decrease, return
if (pos == M - 1)
{
return false;
}
// (2) find first position after pos which can be increased
// then we have state[k] = Nmin[k] for k in [0,pos]
int next = 0;
for (int k = pos + 1; k < M; ++k)
{
if (state[k] < Nmax[k])
{
next = k;
break;
}
}
if (next == 0)
{
return false;
}
--state[pos];
++state[next];
// (3) get occupation in [pos,next-1] and set to Nmin[k]
int n = 0;
for (int k = pos; k < next; ++k)
{
n += state[k] - Nmin[k];
state[k] = Nmin[k];
}
// (4) fill up from the start
for (int i = 0; i<M; ++i)
{
if (n <= 0)
break;
int add = std::min(n, Nmax[i] - state[i]);
state[i] += add;
n -= add;
}
return true;
}
SymmetricIndex& operator++()
{
bool inc = nextState(state, Nmax, Nmin);
if (inc) ++_index;
return *this;
}
SymmetricIndex operator++(int)
{
auto ret = *this;
this->operator++();
return ret;
}
bool previousState(StateType& state, StateType const& Nmax, StateType const& Nmin) const
{
////co-lexicographical ordering with Nmin and Nmax:
// (1) find first position which can be increased
// then we have state[k] = Nmax[k] for k in [0,pos-1]
int pos = M - 1;
for (int k = 0; k < M - 1; ++k)
{
if (state[k] < Nmax[k])
{
pos = k;
break;
}
}
// if nothing found to increase, return
if (pos == M - 1)
{
return false;
}
// (2) find first position after pos which can be decreased
// then we have state[k] = Nmin[k] for k in [pos+1,next]
int next = 0;
for (int k = pos + 1; k < M; ++k)
{
if (state[k] > Nmin[k])
{
next = k;
break;
}
}
if (next == 0)
{
return false;
}
++state[pos];
--state[next];
int n = 0;
for (int k = 0; k <= pos; ++k)
{
n += state[k] - Nmin[k];
state[k] = Nmin[k];
}
if (n == 0)
{
return true;
}
for (int i = next-1; i>=0; --i)
{
int add = std::min(n, Nmax[i] - state[i]);
state[i] += add;
n -= add;
if (n <= 0)
break;
}
return true;
}
SymmetricIndex operator--()
{
bool dec = previousState(state, Nmax, Nmin);
if (dec) --_index;
return *this;
}
SymmetricIndex operator--(int)
{
auto ret = *this;
this->operator--();
return ret;
}
int multinomial() const
{
auto v = const_cast<std::remove_reference<decltype(state)>::type&>(state);
return multinomial(v);
}
int multinomial(StateType& state) const
{
int ret = 1;
int n = state[0];
for (int i = 1; i < M; ++i)
{
n += state[i];
ret *= binomial(n, state[i]);
}
return ret;
}
SymmetricIndex& random(StateType const& _Nmin)
{
static std::mt19937 rng;
state = _Nmin;
int n = std::accumulate(std::begin(state), std::end(state), 0);
auto weight = [&](int i) { return state[i] < Nmax[i] ? 1 : 0; };
for (int i = n; i < N; ++i)
{
std::discrete_distribution<int> d(N, 0, N, weight);
++state[d(rng)];
}
_index = rank();
return *this;
}
SymmetricIndex& random()
{
return random(Nmin);
}
private:
IntegerType W(int m, int n) const
{
if (m < 0 || n < 0) return 0;
else if (m == 0 && n == 0) return 1;
else if (m == 0 && n > 0) return 0;
//else if (m > 0 && n < Nmin[m-1]) return 0;
else
{
//static std::map<std::tuple<int, int>, IntegerType> memo;
//auto it = memo.find(std::make_tuple(k, m));
//if (it != std::end(memo))
//{
// return it->second;
//}
IntegerType ret = 0;
for (int i = Nmin[m-1]; i <= std::min(Nmax[m-1], n); ++i)
ret += W(m - 1, n - i);
//memo[std::make_tuple(k, m)] = ret;
return ret;
}
}
IntegerType binomial(int m, int n) const
{
static std::vector<int> store;
if (store.empty())
{
std::function<IntegerType(int, int)> bin = [](int n, int k)
{
int res = 1;
if (k > n - k)
k = n - k;
for (int i = 0; i < k; ++i)
{
res *= (n - i);
res /= (i + 1);
}
return res;
};
store.resize(M*M);
for (int i = 0; i < M; ++i)
{
for (int j = 0; j < M; ++j)
{
store[i*M + j] = bin(i, j);
}
}
}
return store[m*M + n];
}
auto addressArray() const -> std::vector<int>
{
std::vector<int> ret((N + 1) * M);
for (int n = 0; n <= N; ++n)
{
for (int m = 0; m < M; ++m)
{
ret[n*M + m] = W(m, n);
}
}
return ret;
}
};
std::ostream& operator<<(std::ostream& os, SymmetricIndex const& sym)
{
for (auto const& i : sym.state)
{
os << i << " ";
}
return os;
}
Use it like
int main()
{
int M=4;
int N=3;
std::vector<int> Nmax(M, N);
std::vector<int> Nmin(M, 0);
Nmax[0]=3;
Nmax[1]=2;
Nmax[2]=1;
Nmax[3]=1;
SymmetricIndex sym(M, N, Nmax, Nmin);
while(!sym.isEnd())
{
std::cout<<sym<<" "<<sym.rank()<<std::endl;
++sym;
}
std::cout<<sym<<" "<<sym.rank()<<std::endl;
}
This will output
3 0 0 0 0 (corresponds to {40,40,40})
2 1 0 0 1 (-> {40,40,50})
1 2 0 0 2 (-> {40,50,50})
2 0 1 0 3 ...
1 1 1 0 4
0 2 1 0 5
2 0 0 1 6
1 1 0 1 7
0 2 0 1 8
1 0 1 1 9
0 1 1 1 10 (-> {50,60,100})
DEMO
Note that I assumed here an ascending mapping of your set elements (i.e. the number 40's is given by index 0, the number of 50's by index 1, and so on).
More precisely: Turn your list into a map<std::vector<int>, int> like
std::vector<int> v{40,40,40,50,50,60,100};
std::map<int, int> m;
for(auto i : v)
{
++m[i];
}
Then use
int N = 3;
int M = m.size();
std::vector<int> Nmin(M,0);
std::vector<int> Nmax;
std::vector<int> val;
for(auto i : m)
{
Nmax.push_back(m.second);
val.push_back(m.first);
}
SymmetricIndex sym(M, N, Nmax, Nmin);
as input to the SymmetricIndex class.
To print the output, use
while(!sym.isEnd())
{
for(int i=0; i<M; ++i)
{
for(int j = 0; j<sym[i]; ++j)
{
std::cout<<val[i]<<" ";
}
}
std::cout<<std::endl;
}
for(int i=0; i<M; ++i)
{
for(int j = 0; j<sym[i]; ++j)
{
std::cout<<val[i]<<" ";
}
}
std::cout<<std::endl;
All untested, but it should give the idea.
I have written code to generate prime numbers in a range (using a modified Sieve of Eratosthenes) , as competitive programming. The code works fine on my Visual Studio, but gives a SISGEV on the website. I use this,
static bool *prime = new bool[1000000001];
to declare memory. And can not understand the reason behind the SISGEV.
Below is the function, whose parameters are the lower limit m, and the upper limit n.
Elements of index >m which are not prime are marked false.
static bool *prime = new bool[1000000009];
void SieveOfEratosthenes(int m, int n)
{
// Create a boolean array "prime[0..n]" and initialize
// all entries it as true. A value in prime[i] will
// finally be false if i is Not a prime, else true.
memset(prime, true, n + 11);
int m2;
if (m > 10) {
m2 = m / 10;
m2 = m2 * 10;
m2 = (2 * m2) / 5;
}
else
m2 = 4;
prime[1] = false;
prime[2] = true;
prime[3] = true;
prime[5] = true;
for (int i = m2; i <= n; i += 2) {
if ( (5*2)/2 >= n) break;
prime[i] = false;
prime[(3 * i) / 2] = false;
prime[(5 * i) / 2] = false;
}
int m3;
m3 = m % 7;
m3 = m - m3;
for (int p = 7; (p)*(p) <= n; p += 6) {
// If prime[p] is not changed, then it is a prime
if (prime[p] == true) {
// Update all multiples of p,
for (int i = p; i <= n; i += p) {
prime[m3+i] = false; //cout << i << " ";
if (prime[m3 + p+ 4]) prime[((p+4)*i)/p] = false;
if (prime[m3 + p + 6]) prime[((p+6)*i)/p] = false;
}
}
prime[7] = true;
prime[11] = true;
prime[13] = true;
}
// Print all prime numbers
for (int p = m; p <= n; p++)
if (prime[p])
cout << p << endl;
}
int main() {
//other code
delete[] prime;
}
Your pointer is a static variable. In C++ the initialization of a static variable happens only once. The delete[] statement however, is executed for every function call.
Do not tilt at windmills and use std::vector instead of rolling a raw-memory solution.
A simple implementation using std::vector: (Adding the extended functionality is left as an exercise to the reader.)
#include <vector>
#include <cmath>
#include <cstddef>
#include <algorithm>
#include <iostream>
std::vector<std::size_t> eratosthenes(std::size_t const n)
{
std::vector<bool> A(n, true);
std::vector<std::size_t> r;
auto const limit = static_cast<std::size_t>(
std::ceil(std::sqrt(static_cast<double>(n))));
// check all numbers up to sqrt(n)
for (std::size_t i = 2; i <= limit; ++i)
{
// if i is prime,
if (A[i])
{
// i is prime, put it into return vector
r.push_back(i);
// set all multiples of i (below n) to false
for (std::size_t j = i*i; j < n; j+=i)
{
A[j] = false;
}
}
}
// fill rest of the primes > sqrt(n) into r
if (!r.empty())
{
for (auto i = limit+1u; i < n; ++i)
{
if (A[i]) r.push_back(i);
}
}
return r;
}
Printing it:
int main()
{
for (auto v : eratosthenes(120))
{
std::cout << v << "\n";
}
return 0;
}
I can iterate over the subsets of size 1
for( int a = 0; a < size; a++ ) {
or subsets of size 2
for( int a1 = 0; a1 < size; a1++ ) {
for( int a2 = a1+1; a2 < size; a2++ ) {
or 3
for( int a1 = 0; a1 < size; a1++ ) {
for( int a2 = a1+1; a2 < size; a2++ ) {
for( int a3 = a2+1; a3 < size; a3++ ) {
But how to do this for subsets of size n?
This does the job, based on an answer by Adam Rosenfield
void iterate(int *a, int i, int size, int n)
{
int start = 0;
if( i > 0 ) start = a[i-1]+1;
for(a[i] = start; a[i] < n; a[i]++) {
if(i == n-1) {
// a is the array of indices of size n
for( int k = 0; k < size; k++ ) {
printf("%d ",a[k]);
}
printf("\n");
}
else
iterate(a, i+1, size, n);
}
}
You can use recursion:
void iterate(int *a, int i, int size, int n)
{
for(a[i] = 0; a[i] < size; a[i]++)
{
if(i == n-1)
DoStuff(a, n); // a is the array of indices of size n
else
iterate(a, i+1, size, n);
}
}
...
// Equivalent to 4 nested for loops
int a[4];
iterate(a, 0, size, 4);
You likely could do this with some recursion.
Here is something I used for a similar problem. It does not use recursion; rather, it uses a vector of indexes.
#include <vector>
template<class T>
class MultiForVar {
std::vector<T> _begin, _end, _vars;
inline int dim(){return _vars.size();}
public:
MultiForVar(std::vector<T> begin, std::vector<T> end) : _begin(begin), _end(end), _vars(_begin)
{
assert(begin.size() == end.size() and "Starting and ending vector<T> not the same size!" );
}
MultiForVar& operator ++()
{
++_vars[dim()-1];
for(int d = dim()-1; d > 0; --d)
{
if( _vars[d] >= _end[d] )
{
_vars[d] = _begin[d];
++_vars[d-1];
}
}
return *this;
}
bool done()
{
/*for(int d = 0; d < dim(); ++d)
if( _vars[d] < _end[d] )
return false;
return true;*/
return (_vars[0] >= _end[0]);
}
T operator[](int d)
{
return _vars.at(d);
}
int numDimensions(){
return dim();
}
std::vector<T>& getRaw(){
return _vars;
}
};
If I understand what you're asking correctly, another way to do it is to use bit-wise operators:
for(int i = 0; i < 1<<size; i++) {
for(int j = 0; j < size; j++) {
if(i & 1<<j) printf("%d ", a[j]);
}
printf("\n");
}
You need something the constructs the powerset of the original set. It's been a while since I've written that, but the psuedocode looks like
Powerset(a, size)
{
if(size == 0) return emptyset
subseta = Powerset(a, size-1) // Powerset of everything except last element
subsetb = appendToAll(a[size-1], subseta) // appends the last element to every set in subseta
return union(subseta, subsetb)
}