combinations

Jun 13, 2010 at 7:43pm
I have a problem for generating combinations for entered ammount of numbers.
for example without getting the entered ammount the loop would look like
1
2
3
4
5
6
7
8
9
10
for (int n=1; n<=3; n++)
    {
      for (int x=1; x<=3; x++)
         {
          for (int y=1; y<=3; y++)
           {
             cout << n << x << y << endl;
           }
         }
    }

But how do i do this for entered ammount of numbers? The length of the output string should be the same as the entered ammount.

Sorry. I'm bad at explaining stuff.
Jun 13, 2010 at 7:58pm
Jun 13, 2010 at 8:27pm
That's permutations, he doesn't want that. He doesn't want combinations either. As you can see from his code, he wants every digit to be able to get every possible value, regardless of the values of the other digits (meaning that repetition is allowed).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include <iostream>
#include <vector>
using namespace std;

ostream & print(const vector<int> & v)
{
    int size=v.size();
    for (int i=0; i<size; i++)
        cout << v[i] << ' ';
    return cout;
}

int main()
{
    int digit_count;
    int digit_values;

    cout << "enter number of digits (>0): ";
    cin >> digit_count;

    cout << "enter number of digit values (>0): ";
    cin >> digit_values;

    vector<int> vint;
    vint.resize(digit_count);

    for (int i=0; i<digit_count; i++)
        vint[i]=0;

    print(vint) << endl; //lol

    int carry;

    while (true)
    {
        carry=1;

        for (int i=0; i<digit_count; i++)
        {
            int & cur=vint[i];

            cur+=carry;
            if (cur==digit_values)
            {
                cur=0;
                carry=1;
            }
            else
            {
                carry=0;
                break;
            }
        }

        if (carry==1) break;

        print(vint) << endl;
    }

    return 0;
}
Last edited on Jun 13, 2010 at 8:32pm
Jun 13, 2010 at 8:44pm
Hey m4ster r0shi... try out this:

1
2
3
4
5
6
7
#include <boost/lambda/lambda.hpp>
#include <algorithm>
#include <vector>

std::vector<int> v;
std::for_each( v.begin(), v.end(),
    std::cout << "The numbers are: " << boost::lambda::_1 << ' ' );


Jun 13, 2010 at 8:52pm
Please, stop it... I don't want to see boost code in my sleep tonight...
Jun 13, 2010 at 9:20pm
Someone I see doesn't like boost, which I think is an excellent library. Notice: 7 lines vs 61.
Oops.

-Albatross

12*10^2 posts, and counting.
Last edited on Jun 14, 2010 at 6:36pm
Jun 13, 2010 at 9:37pm
Albatross wrote:
Notice: 7 lines vs 61.

I think you missed something here... He proposed a replacement for the print function, not the whole code...
Last edited on Jun 13, 2010 at 9:55pm
Jun 14, 2010 at 2:16pm
That's permutations, he doesn't want that. He doesn't want combinations either. As you can see from his code, he wants every digit to be able to get every possible value, regardless of the values of the other digits (meaning that repetition is allowed).

That's a permutation where repetition is permitted.
http://www.mathsisfun.com/combinatorics/combinations-permutations.html

@something
The counting numbers are the same thing as what you are asking. Think for a second about this:

  00      05      10      15      20  
  01      06      11      16      21
  02      07      12      17      .
  03      08      13      18      .
  04      09      14      19      .

The only thing you must be aware of is your set of 'digits'. For ordinary counting, we use the digits 0, 1, 2, 3, 4, 5, 6, 7, 8, and 9.

In computing, we often use different sets. For example, the octal set contains only the digits 0, 1, 2, 3, 4, 5, 6, and 7 -- eight digits total. If I try to add one to 07, I get 10. That is, the digit in the rightmost place starts over with the first and the one on the left is incremented to the next digit. (It too may roll over.)

This roll-over and increment the next to the left is called a carry.

While m4ster r0shi gave you code to do this kind of thing, you really should spend time trying to figure it out yourself. Understanding what is going on will help you significantly later on when you are doing more interesting things.

Hope this helps.
Jun 14, 2010 at 2:52pm
Duoas wrote:
That's a permutation where repetition is permitted.

Oh, ok. I'm from Greece and we use different terms here. When you have to put n (distinct) objects in n places, caring about the order and without repetition allowed, we call it a permutation of n objects. That is, a permutation by definition prohibits repetition.

A permutation is a special case of something that I couldn't find the english term for :/ When you have to put n (distinct) objects in k (<=n) places, caring about the order, we call it, let's say "ordering" (I don't know the english term). An "ordering" can be "repetitive" (i.e. repetition is allowed) or not. A permutation is a non-"repetitive" "ordering" where k==n.

What I wrote for the OP was the "repetitive" "ordering" of n objects in k places, where n==digit_values and k==digit_count. This, by definition, in my language, is not a permutation (not even if k==n, because it's still "repetitive").

We use the term "permutations with repetition" to describe the following situation:

You have n (non-distinct) objects, where k1 of them are identical to each other, k2 of them are identical to each other, ... and k1+k2+...==n (obviously) and you want to put them in n places, caring about the order of the non-identical objects. The number of ways you can do this is n!/(k1! * k2! * ...).

EDIT: Mmmm... Take a look at this-> http://mathworld.wolfram.com/Permutation.html
It defines permutations the way I do. I guess then that your site just oversimplifies things because it's a site for kids.
Last edited on Jun 14, 2010 at 4:07pm
Jun 14, 2010 at 3:02pm
jsmith wrote:
1
2
3
4
5
6
7
#include <boost/lambda/lambda.hpp>
#include <algorithm>
#include <vector>

std::vector<int> v;
std::for_each( v.begin(), v.end(),
    std::cout << "The numbers are: " << boost::lambda::_1 << ' ' );


I like boost and all but when you don't need it... :P
1
2
3
4
5
6
#include <algorithm>
#include <iterator>
#include <vector>

std::vector<int> v;
std::copy( v.begin(), v.end(), std::ostream_iterator<int>( std::cout, " " ) );
Last edited on Jun 14, 2010 at 3:03pm
Jun 14, 2010 at 3:04pm
std::ostream_iterator<int>

Wow, I didn't even know that existed...you learn something new every day I guess.
Jun 14, 2010 at 7:39pm
That's true. Thing is, for some reason I can never remember the ostream_iterator way off the top
of my head, but I can remember the lambda way :)


Jun 14, 2010 at 7:45pm
The reason is that you are a boost addict :D
Jun 15, 2010 at 11:37pm
Ok, so here's m4ster r0shi's 61-line program in 23 lines with only
two real lines of logic:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <string>

void do_it( std::string s, size_t digits_left, size_t max_values ) {
    if( digits_left )
        for( size_t digit = 0; digit < max_values; ++digit )
            do_it( s + static_cast<char>( digit + '0' ), digits_left - 1,
                max_values );
    else
        std::cout << s << std::endl;
}

int main() {
    size_t max_length, max_values;

    std::cout << "enter number of digits (>0): ";
    std::cin >> max_length;

    std::cout << "enter number of digit values (>0): ";
    std::cin >> max_values;

    do_it( "", max_length, max_values );
}
Jun 15, 2010 at 11:52pm
Nice... I see you didn't use boost at all... GJ boost-boy! :D
Topic archived. No new replies allowed.