Sign in to follow this  
3Dgonewild

2D & 3D VECTORS (c++)

Recommended Posts

I don't get your question. You might speak of a multidimensional array or of vectors (which have only one dimension).

If you speak about multimensional arrays
The C way (bad, not encapsulated), static (in the initialiazed segment if global, on stack otherwise; please avoid creating huge arrays on stack):
type my_array[elem_count_dim1][elem_count_dim_2];

Of course, you can continue the list if you want more dimensions.
The size of the array (in memory) is the product of all dimension by the size of the array type.

The C way (bad, not encapsulated), dynamic (on the heap)
type **my_array;
// creation
my_array = new type*[elem_count_dim1];
for (int i=0; i<elem_count_dim1; ++i°
{
my_array[i] = new type[elem_count_dim2];
}

// deletion
for (int i=0; i<elem_count_dim1; ++i°
{
delete [] my_array[i];
}
delete [] my_array;


The C++ way, boosterized: use boost multi array

The C++ way, not boosterized: you can use the standard library (ie creating a vector of vector of int) but that's a bit convoluted. Or you can create a class which encapsulate the C case (or something similar).

If you speak about a vector
Hum. Create a class or a struct with the fields you want. I mean, if you search for 2D vector or 3D vector class on the intarweb, you'll be flooded with results.

Best regards,

Share this post


Link to post
Share on other sites
I assume you mean SC++L vector (the dynamic array) and not a mathematical vector.

Quote:
How do you declare a 2d or 3d vector?

Don't. There's no such thing. You can fake it by nesting types, for example

std::vector< std::vector< int > > tryingToBe2D;

however this is not really a two dimensional array... the technique scales to n-D vectors, but is still not usually a good idea.

In C++, it's often not a good idea to use n-D arrays or vectors, because they're (generally) not very space or memory efficient, and they're almost always jagged arrays (not rectangular) instead.

It's instead preferable to use a n-D interface to a one-dimensional array. You can construct the interface however you like... the most straightforward method is not to have an interface at all and just do the indexing directly. You can replace a 2D array of (width * height) elements with a single array of (width * height) elements:

std::vector< int > linearArray(width * height);

To access element (x,y) of the array, you index it as follows:

int element = linearArray[y * width + x];

This works because the array (or vector) elements are arranged contiguously (most attempts at n-D arrays lose this guarantee, which makes them somewhat less memory efficient). Every (width) elements of the array is one "row" of the grid, which is why you multiply the y/row value by the width.

This scales to any dimension of array. While it might seem a little strange at first, it's generally a much better method than actually attempting to use the constructs that C++ provides to make "2D" arrays.

Share this post


Link to post
Share on other sites
First of all , thanks for the replies..


So its called "SC++L vector" , dohh..okkk!


@jpetrie:

Thanks for the nice examples , but , what changes do i have to make in order to create a tile map?


with a normal 2d array , i do the following :



int data[25][25];
int whatiwant =data[1][20];




With a sc++l vector , i could do it like this : ?



std::vector< int > ARRAY(25 * 25);

int whatiwant = ARRAY[1 * 25 + 20];




Am i right?or i missed something?

Share this post


Link to post
Share on other sites
I don't know why jpetrie wrote "SC++L" but it's more "STL Vectors" (standard library vector), hence where std:: come from (standard namespace). Don't forget the #include at the top of your file.

http://msdn2.microsoft.com/en-us/library/cscc687y(VS.80).aspx
http://msdn2.microsoft.com/en-us/library/k449z507(VS.80).aspx

Share this post


Link to post
Share on other sites
Quote:
Original post by Dunge
I don't know why jpetrie wrote "SC++L" but it's more "STL Vectors" (standard library vector), hence where std:: come from (standard namespace). Don't forget the #include at the top of your file.

http://msdn2.microsoft.com/en-us/library/cscc687y(VS.80).aspx
http://msdn2.microsoft.com/en-us/library/k449z507(VS.80).aspx


He wrote SC++L because std::vector is a part of the Standard C++ Library, which the two links you posted also suggests.

STL, short for Standard Template Library, is something else, altough related.

Share this post


Link to post
Share on other sites
I've tried to open a tile map file , but my application exits :/.

Here's the source:


#include <cstdlib>
#include <iostream>
#include <vector>
#include <sstream>
#include <fstream>
using namespace std;

int main(int argc, char *argv[])
{
std::vector< int > ARRAY(25 * 25);

//FILE has 24 cols & 24 rows (since we start from 0 , its 25x25)
std::ifstream map( "MAP.TXT" );
if( map == NULL ) { return false; }

for( int t = 0; t < 24*24; t++ )
{
int c = -1;
map >> c;
ARRAY[t]=c;
if( map.fail() == true ) {
return false;
}
}
int whatiwant = ARRAY[1 * 24 + 24];
cout<<whatiwant<<endl;
system("PAUSE");
return EXIT_SUCCESS;
}





The tile map :
map.txt

11111000000000011111111
11111111111111111111111
11111111111111111111111
11111111111111111111111
11111111111111111111111
11111111111111111111111
11111111111111111111111
11111111111111111111111
11111111111111111111111
11111111111111111111111
11111111111111111111111
11111111111111111111111
11111111111111111111111
11111111111111111111111
11111111111111111111111
11111111111111111111111
11111111111111111111111
11111111111111111111111
11111111111111111111111
11111111111111111111111
11111111111111111111111
11111111111111111111111
11111111111111111111111
11111111111111111111111





Please ,tell me what im doing wrong!!!!!!!!!!!!

Share this post


Link to post
Share on other sites
You're reading integers from the file. What is the first integer in your file? Here's a tip; it's not 1.

Read characters instead, since that's what the file contains and how you are supposed to interpret the file.

Share this post


Link to post
Share on other sites
On your loop, you recognize that the maximum index is one less than the size (25*25), but you apply that rule to both dimensions (and you end up with 24*24).
The number of elements in the array is 25*25=3125, so your maximum index should be 25*25-1=3124. Since you use '<' instead of '<=', you can use the actual size.
With the size you supplied (24*24), your 1 short per dimension (49 elements overall).
If you were to keep your structure as it is, which Brother Bob advised against, you should write "for (int t=0;t<ARRAY.size();t++)", or use stl iterators, "for (std::vector<int>::iterator iter=ARRAY.begin();iter!=ARRAY.end();iter++)".
Apply this concept to your array access also.

The reason why Brother Bob stated that you shouldn't read integers is that by default ifstream will read the integers as delimited by whitespace. So, on the first line, instead of reading a character per a series of steps, it will read the whole first line as an integer=11111000000000011111111.
To read using characters:
char c;
map >> c;
//Translate into integer
int x=c-'0'; //If you're going to use non-numerical characters, this is a bad idea

EDIT: Forgot to mention - Be sure you check for whitespace! Otherwise, it'll keep on reading as if nothing happened.

Slight note:
Your expression "if (map.fail()==true)" is redundant - the if goes to the statement / block following if the expression inside is true (nonzero).

Share this post


Link to post
Share on other sites
Yeah! , works!!!!
0 * 25+5 returns 0!!!

#include <cstdlib>
#include <iostream>
#include <vector>
#include <sstream>
#include <fstream>
using namespace std;

int main(int argc, char *argv[])
{
std::vector< int > ARRAY(25 * 25);
std::ifstream map( "MAP.TXT" );
if( map == NULL ) { return false; }
for( int t = 0; t < ARRAY.size(); t++ )
{
char c;
map >> c;
int cA = c-'0';
ARRAY[t]=cA;
}
int whatiwant = ARRAY[0 * 25+5];
cout<<whatiwant<<endl;
system("PAUSE");
return EXIT_SUCCESS;
}





Thanks for the great help!!!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this