473,721 Members | 2,053 Online

# How to create an N dimensional array with N elements?

Ive been googling and reading through my books but I haven't figured out a
solution (much less an elegant one) to create a multidimensiona l array with
a runtime determined number of dimensions. I also checked out the
boost::multi_ar ray.hpp, and Giovanni Bavistrelli's Array code. Neither of
these seem to allow dynamic array dimensions.

For example, the user selects a 2 dimensional array, I want to create:
MyObject** array = new MyObject[dim1_size][dim2_size];

And if they select a 4 dim array:
MyObject**** array = new
MyObject[dim1_size][dim2_size][dim3_size][dim4_size];

Besides using bigugly if statements, how do I do this?

Thanks,
Bryan
Jul 22 '05 #1
10 3202
Upon further reflection, I think creating an n dimensional array may be
besides the point...

What I am trying to do, at the end of the day, is to take a list of objects
(lets just say they are ints for the moment though) and multiply it by
itself N number of times.

So if I have an array with 10 elements in it, I need to create a new list
with 100 elements in it, and populate those 100 elements with the results
of:
[0][0] * [0][0]
[0][0] * [0][1]
etc. etc.

With 3 dims, the list would be 10000 elements long, and so on.

If this was a nested for loop, with N number of nests this would be
simple... but without knowing ahead of time how many loops to use Im not

Any suggestions?
Thanks
B
Jul 22 '05 #2

"BCC" <br***@akanta.c om> wrote in message
news:zI******** *********@newss vr25.news.prodi gy.com...
Upon further reflection, I think creating an n dimensional array may be
besides the point...

What I am trying to do, at the end of the day, is to take a list of objects (lets just say they are ints for the moment though) and multiply it by
itself N number of times.

So if I have an array with 10 elements in it, I need to create a new list
with 100 elements in it, and populate those 100 elements with the results
of:
[0][0] * [0][0]
[0][0] * [0][1]
etc. etc.

With 3 dims, the list would be 10000 elements long, and so on.

If this was a nested for loop, with N number of nests this would be
simple... but without knowing ahead of time how many loops to use Im not

Any suggestions?

Recursion.

Not completely sure this is what you are asking for but hopefully will be
close enough for you to adapt.

#include <algorithm>
#include <iterator>
#include <iostream>
#include <list>
using namespace std;

void generate(std::l ist<int>& res, std::list<int> const& l, int depth, int
value = 1)
{
if (depth == 0)
{
res.push_back(v alue);
}
else
{
for (std::list<int> ::const_iterato r i = l.begin(); i != l.end(); ++i)
generate(res, l, depth - 1, value*(*i));
}
}

int main()
{
// setup starting list
std::list<int> l;
l.push_back(1);
l.push_back(2);
l.push_back(3);
// generate result list
std::list<int> res;
generate(res, l, 4);
// print results
std::copy(res.b egin(), res.end(), std::ostream_it erator<int>(std ::cout, "
"));
}

john
Jul 22 '05 #3
BCC wrote:
Upon further reflection, I think creating an n dimensional array may be
besides the point...

What I am trying to do, at the end of the day, is to take a list of objects
(lets just say they are ints for the moment though) and multiply it by
itself N number of times.

So if I have an array with 10 elements in it, I need to create a new list
with 100 elements in it, and populate those 100 elements with the results
of:
[0][0] * [0][0]
[0][0] * [0][1]
etc. etc.

With 3 dims, the list would be 10000 elements long, and so on.

If this was a nested for loop, with N number of nests this would be
simple... but without knowing ahead of time how many loops to use Im not

Any suggestions?

Recursion.
Jul 22 '05 #4
Hi John, thanks very much for the suggestion- you were pretty close to what
I need, but it is still tripping me up. Heres what I have:

int depth = 2;
int list_size = 5;
int* array = new int[list_size];
for (int i = 0; i < list_size; ++i) array[i] = 0;
vector<int *> all_list;

Generate(all_li st, list_size, depth, array);

// Process array

delete [] array;

void Generate(std::v ector<int *>& res, int list_size, int depth, int*
in_list)
{
if (depth == 0)
{
res.push_back(i n_list);
}
else {
for (int i = 0; i < list_size; ++i) {
if (in_list[i] > 0) continue; // We have already included this seq,
skip
++in_list[i];
Generate(res, list_size, depth - 1, in_list);
}
}
}

What I need it to have is in my resulting list is list_size^depth patterns,
or in this case all unique possible combinations of 1's and 2's:
for 1's
10000
01000
00100
00010
00001
-And-
for 2's
11000
10100
10010
10001
01100
01010
01001
00110
00101
00011

I believe this is all of them. And I need to be able to do this for any
size list and any depth...

I think the function is pretty close, but I am still not getting it. What
am I missing? (hopefully this makes sense!)

Thanks,
Bryan
Jul 22 '05 #5
"BCC" <br***@akanta.c om> wrote in message
news:it******** *******@newssvr 27.news.prodigy .com...
Hi John, thanks very much for the suggestion- you were pretty close to what I need, but it is still tripping me up. Heres what I have:

int depth = 2;
int list_size = 5;
int* array = new int[list_size];
for (int i = 0; i < list_size; ++i) array[i] = 0;
vector<int *> all_list;

Generate(all_li st, list_size, depth, array);

// Process array

delete [] array;

void Generate(std::v ector<int *>& res, int list_size, int depth, int*
in_list)
{
if (depth == 0)
{
res.push_back(i n_list);
}
else {
for (int i = 0; i < list_size; ++i) {
if (in_list[i] > 0) continue; // We have already included this seq,
skip
++in_list[i];
Generate(res, list_size, depth - 1, in_list);
}
}
}

What I need it to have is in my resulting list is list_size^depth patterns, or in this case all unique possible combinations of 1's and 2's:
for 1's
10000
01000
00100
00010
00001
-And-
for 2's
11000
10100
10010
10001
01100
01010
01001
00110
00101
00011

It looks as though all you need is a combination generator, so a Combination
class could do the job (with a Next() member returns the next combination)
and you could forget about the recursion.

DW

Jul 22 '05 #6

"BCC" <br***@akanta.c om> wrote in message
news:it******** *******@newssvr 27.news.prodigy .com...
Hi John, thanks very much for the suggestion- you were pretty close to what I need, but it is still tripping me up. Heres what I have:

int depth = 2;
int list_size = 5;
int* array = new int[list_size];
for (int i = 0; i < list_size; ++i) array[i] = 0;
vector<int *> all_list;

Generate(all_li st, list_size, depth, array);

// Process array

delete [] array;

void Generate(std::v ector<int *>& res, int list_size, int depth, int*
in_list)
{
if (depth == 0)
{
res.push_back(i n_list);
}
else {
for (int i = 0; i < list_size; ++i) {
if (in_list[i] > 0) continue; // We have already included this seq,
skip
++in_list[i];
Generate(res, list_size, depth - 1, in_list);
}
}
}

What I need it to have is in my resulting list is list_size^depth patterns, or in this case all unique possible combinations of 1's and 2's:
for 1's
10000
01000
00100
00010
00001
-And-
for 2's
11000
10100
10010
10001
01100
01010
01001
00110
00101
00011

I believe this is all of them. And I need to be able to do this for any
size list and any depth...

I think the function is pretty close, but I am still not getting it. What
am I missing? (hopefully this makes sense!)

combinations, and for combinations a recusrive algorithm is normally the way
to go. But now I see that you are talking about permutations (i.e. unique
combinations) and for permutations an iterative algorithm is correct. It's
quite hard to work out the correct algorithm for permutations but
fortunately its already been done in the STL next_permutatio n function (look
at the code in the <algorithm> header if you are interested).

The other thing that worries me about your code is that you have a vector of
pointers and you are repeatedly pushing the same pointer onto your vector,
which cannot be a good idea.

Here's some code, I switched to a vector of vectors, instead of a vector of
pointers.

#include <algorithm>
#include <iterator>
#include <iostream>
#include <vector>

int main()
{
int depth = 2;
int list_size = 5;
std::vector<std ::vector<int> > all_list;
std::vector<int > array(list_size );
for (int i = 1; i <= depth; ++i)
{
// set up initial permutation
for (int j = 0; j < list_size; ++j)
array[j] = j < list_size - i ? 0 : 1;
// add all permutations of this type
do
{
all_list.push_b ack(array);
}
while (next_permutati on(array.begin( ), array.end()));
}
// print results
for (std::vector<st d::vector<int> >::const_iterat or i = all_list.begin( );
i != all_list.end(); ++i)
{
std::copy(i->begin(), i->end(), std::ostream_it erator<int>(std ::cout, "
"));
std::cout << '\n';
}
}
Jul 22 '05 #7
> >
I think the function is pretty close, but I am still not getting it. What am I missing? (hopefully this makes sense!)

Actually no.

I meant, 'no its not close', not 'no it doesn't make sense'. No offence
intended.

john
Jul 22 '05 #8
"John Harrison" <jo************ *@hotmail.com> wrote in message
news:2j******** *****@uni-berlin.de...

"BCC" <br***@akanta.c om> wrote in message
news:it******** *******@newssvr 27.news.prodigy .com...
10000
01000
00100
00010
00001
-And-
for 2's
11000
10100
10010
10001
01100
01010
01001
00110
00101
00011

I believe this is all of them. And I need to be able to do this for any
size list and any depth...

I think the function is pretty close, but I am still not getting it. What am I missing? (hopefully this makes sense!)
combinations, and for combinations a recusrive algorithm is normally the

way to go. But now I see that you are talking about permutations (i.e. unique
combinations)

Those look like combinations above to me, not permutations (i.e., order
matters for permutations but not combinations), or are you referring to some
other aspect of the problem?

DW

Jul 22 '05 #9
combinations, and for combinations a recusrive algorithm is normally the way to go. But now I see that you are talking about permutations (i.e. unique
combinations) and for permutations an iterative algorithm is correct. It's
quite hard to work out the correct algorithm for permutations but
fortunately its already been done in the STL next_permutatio n function (look at the code in the <algorithm> header if you are interested).
Ah, that is a nice tip, I didnt know next_permutatio n existed, very useful
and I will most certainly look at the code for this.
The other thing that worries me about your code is that you have a vector of pointers and you are repeatedly pushing the same pointer onto your vector,
which cannot be a good idea.

Agreed. I was thinking in terms of speed (since STL vector is slow), but
with my list sizes I dont imagine that performance will be a problem at all.

And the code is great to get me started.

Thanks for all the help!

Bryan
Jul 22 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

### Similar topics

 9 17605 by: lawrence | last post by: Is there an easy way to sort a 2 dimensional array alphabetically by the second field in each row? Also, when I use sort() on a two dimensional array, it seems to work a lot like array_reverse(). Can anyone tell me why? 4 8181 by: Todd | last post by: I'm new to c++ and was wondering how to sort a 2 dimensional array. I'm using a select sort for 1 dimensional arrays but it is not working for a 2 dimensional array. The 2 dimensional array are float elements. Thanks in advance 6 3353 by: TrustyTif | last post by: After surfing the google & MSDN for a few days I found an MSDN site that explained how to "new" a multidimensional array in C++...but, I don't know how to use it, for alas, my brain still doesn't understand pointer very well. Here's the site: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclang98/html/_pluslang_new_operator.asp And here's what I've come up with thus far to have a 2 dimensional array of CStrings. 9 8575 by: Dadi | last post by: Hi, I can make a simple initialization work like this: Object ONE_ROW = {{"Vodafone", "5550160100197016"}}; But, now I want to create another array that consists of multiple copies of ONE_ROW like this (will not compile): Object TWO_ROWS = {ONE_ROW, ONE_ROW}; // Works in Java ;-) 4 6377 by: entitledX | last post by: Hi, I'm trying to use the HDF library to read a few HDF files that I need to process. The data in each file varies in rows, but the columns remain constant. Because of that, I had dynamically allocated a set of pointer to pointers as my multi-dimensional arrays. Here is my code (i have omitted checking calloc's return value to make this shorter): int **filter; filter = calloc( ylength, sizeof(int*) ); for( i = 0 ; i < ylength... 22 2284 by: spam.noam | last post by: Hello, I discovered that I needed a small change to the Python grammar. I would like to hear what you think about it. In two lines: Currently, the expression "x" is a syntax error. I suggest that it will be evaluated like "x", just as "x" is evaluated like "x" right now. 6 10416 by: Chuck Anderson | last post by: My knowledge of JavaScript is limited. I learn from example and then adapt those examples to suit my needs. I have stumped myself on this one. I have a form with checkboxes that I want to group by using a two dimensional array.