Populating an Array

Pages: 12
I am writing code for a program that will take user input selection of columns and determine an array based on that.

The number of columns will be user selected.
The number of rows equals 3^(columns) <--exponent not XOR
- This is because each column has the possibility of having the numbers 0,1,or 2

For example, if the user were to select "4" columns, then the array would have 4 columns and 3^4=81 rows.

Then I would like to populate this with all of the possible combinations of 0,1,2
i.e.
0000
0001
0002
0010
0011
0012
0020
0021
0022
0100
....
2220
2221
2222

Any idea how I would create the "For" Loop for this?
Do you actually need the array or can you fake it by converting number to base 3 strings?
I would prefer having the array, please...but how would you go about converting number to base 3 strings?
Last edited on
Ok. What code have you written so far? The for loop shouldn't be too difficult but I need to see how you have your variables set up.
#include <iostream>
#include <math.h>
#include<vector>

using namespace std;

int main()
{
//User input
int cols;// (columns in array)
cout<<"\n How many columns would you like to have? :\t";
cin>>cols;

//(rows in array dependent on columns)
int rows = ( int ) pow( 3.0 , cols) ;
cout<<"\n The Number of possible combinations for the given columns are :\t"<<rows;


//Declare array via vector of vectors
vector< vector<int> > MyArray(rows, vector<int>(cols));

int i,j,k = 0;
for (i=0;i<rows;i++)
{
for (j=0;j<cols;j++)
{
Base conversion is still useful here. Do you know how to do arbitrary base conversion?
No, unfortunately, I am not familiar. I just started learning C++ last week.
OK. First off, you don't need the inner loop here - we're going to be going to be going a whole row at a time.

The right-most column will be set to i%3, so it goes 0,1,2,0,1,2,0,1,2 over and over.

The next column to the left will be (i/3)%3 so it goes 0,0,0,1,1,1,2,2,2,0,0,0,etc over and over.

The next coumn to the left will be (i/9)%3, and then the next column over will be (i/27)%3.

I assume you see the pattern now - for each digit where 0 is the right-most digit, the value is (i/(3digit)%3. Basically we're converting the loop index to a base 3 number digit by digit.
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
#include <iostream>
#include <cmath>
#include <algorithm>

using namespace std;

void getresult(int cols, int n);
string getbin(int n);
void output(int cols, string s);

int main()
{
	int cols;
	cout << " Enter number of columns : ";
	cin >> cols;	// note doesn't validate user enters a number

	int numbers(0);
	for (double n = 0; n < cols; ++n)
		numbers += pow(2, n);

	for (int n = 0; n <= numbers; ++n)
		getresult(cols, n);

	system("pause");
	return 0;
}

void getresult(int cols, int n)
{
	string s = getbin(n);
	output(cols, s);
	if (s.find('1') != string::npos)
	{
		replace(s.begin(), s.end(), '1', '2');
		output(cols, s);
	}
}

string getbin(int n)
{
	if (n == 0) return "0";
	if (n == 1) return "1";
	if (n % 2 == 0)
		return getbin(n/2) + "0";
	else
		return getbin(n/2) + "1";
}

void output(int cols, string s)
{
	cout.width(cols);
	cout.fill('0');
	cout << s << endl;
}
Last edited on
Thank you guys. I will try it out and see how it works.
@ajh32 that's insanely over-complicated. Why did you do it that way?
Yeah, I am not picking up on that.

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
#include <iostream>
#include <math.h>
#include <vector>

using namespace std;

int main()
{
	//User input 
	int cols;//(columns in array)
	cout<<"\n How many columns? :\t";
	cin>>cols;

		int rows  = ( int ) pow( 3.0 , cols) ;
    cout<<"\n The Number of possible combinations for the given columns are :\t"<<rows;
	
	
	
	vector< vector<int> > MyArray(rows, vector<int>(cols));

		int i,j,k = 0;
	for (i=1;i<rows;i++) //Start with row 1
	{
		bool carry = true;
		for (j=0;j<cols;j++)
		{
			int value = MyArray[i - 1][j]; //Value from previous row
			if(carry)
			{
				value += 1;
				if(value < 3)
				{
					MyArray[i][j]=value;
					carry = false;
				}
				else
				{
					MyArray[i][j]=0;
				}		
			}
			else
			{
				MyArray[i][j]=value;
			}
		}
	}
	return 0;
}


This is what I have so far, but it is no outputting what I want.

@L B

How would you implement (i/3digit)%3?
Last edited on
There's no need to PM me. It's also a bit rude to others a it's like exclusive help ;)

At this point I can't really explain any better than I already have, so I'll just give a code example:

MyArray[i][cols-j-1] = (i/static_cast<int>(std::pow(3.0, j)))%3;

Note that this replaces lines 27-44, and you also don't need k or carry. Please tell me if you don't understand how it works (or if it didn't work - I can't test atm)
Last edited on
@ajh32 that's insanely over-complicated. Why did you do it that way?


Over complicated? No, it just splits each task into a self contained function, which is good practtice. The only mistake I made is that I should have used base 3 rather than base 2, I just missunderstood the question!
OK, I've made it much simpler and uses base3 as originally requested:

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
#include <sstream>
#include <string>
#include <iostream>
#include <cmath>
#include <algorithm>

using namespace std;

int main()
{
	const int base = 3;
	int cols;
	cout<<"\n How many columns? :\t";
	cin>>cols;

	int rows = (int)pow((double)base, cols);

	for (int n = 0; n < rows; ++n)
	{
		int num = n;
		stringstream ss;

		do
		{
			ss << (int)num % base;
			num = num/base;
		} while (num > 0);

		string s = ss.str();
		reverse(s.begin(), s.end());
		cout.width(cols);
		cout.fill('0');
		cout << s << endl;
	}

	system("pause");
	return 0;
}
This is what I have so far, but it is no outputting what I want.

that's my approach. I have no idea why you think it doesn't work?


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
#include <iostream>
#include <math.h>
#include <vector>

using namespace std;

int main()
{
	//User input
	int cols;//(columns in array)
	cout<<"\n How many columns? :\t";
	cin>>cols;

		int rows  = ( int ) pow( 3.0 , cols) ;
    cout<<"\n The Number of possible combinations for the given columns are :\t"<<rows;



	vector< vector<int> > MyArray(rows, vector<int>(cols));

		int i,j,k = 0;
	for (i=1;i<rows;i++) //Start with row 1
	{
		bool carry = true;
		for (j=cols-1;j>=0;j--) // Note: reversed order
		{
			int value = MyArray[i - 1][j]; //Value from previous row
			if(carry)
			{
				value += 1;
				if(value < 3)
				{
					MyArray[i][j]=value;
					carry = false;
				}
				else
				{
					MyArray[i][j]=0;
				}
			}
			else
			{
				MyArray[i][j]=value;
			}
		}
	}
		cout << endl;
	for (i=0;i<rows;i++)
	{
		for (j=0;j<cols;j++)
		{
			cout << MyArray[i][j];
		}
		cout << endl;
	}
	return 0;
}

 How many columns? :    3

 The Number of possible combinations for the given columns are :        27
000
001
002
010
011
012
020
021
022
100
101
102
110
111
112
120
121
122
200
201
202
210
211
212
220
221
222
Last edited on
This is my simplest version:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include <vector>
#include <cmath>
 
int main()
{
    int cols = 0;
    do
    {
        std::cout << "Enter the number of columns: " << std::flush;
    } while(!(std::cin >> cols) || cols <= 0);
    int total = std::pow(3.0, cols);
    for(int i = 0; i < total; ++i)
    {
        for(int j = cols-1; j >= 0; --j)
        {
            std::cout << (i/static_cast<int>(std::pow(3.0, j)))%3;
        }
        std::cout << std::endl;
    }
}
http://ideone.com/8Ywgz2
it does not use an intermediate array, I'll let you figure that out if it is required.
Last edited on
Thank you @L B, @coder777, @ajh32 I appreciate the help. Just started trying to teach myself C++ this week so this definitely helps.
Now would anyone know how to use Boost Libraries to make this better?
With or without boost, it can be made cleaner and safer. With boost, it can be made shorter, and a bit slower:

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <boost/dynamic_bitset.hpp>
#include <limits>
#include <iostream>

int main()
{
    std::cout << "number of bits? " ;
    std::size_t n ;

    if( std::cin >> n && n < std::numeric_limits< unsigned long >::digits )
        for( unsigned long v = 0 ; v < ( 1U << n ) ; ++v )
            std::cout << boost::dynamic_bitset<>( n, v ) << '\n' ;
}
Pages: 12