vector of vectors push_back question

J

Jeff

Hello-

Ive never used a vector or vectors in C++ so I have a question for you
all.

I know I can dynamically create the size I need upfront, but is it
possible to
create them on the fly dynamically? That is, for a 2 dim array, I want
to create
the first element and then push_back the columns after that:

This code obviously does not work, but this is how I percieve it to
create the
initial 'x' or row element, then add each column after that.

int hist_idx = 0;
vector< <vector<int> > history;

history.push_back(hist_idx);

then

history[hist_idx].push_back(5);
history[hist_idx].push_back(2);
etc

If I have to statically create it upfront, is it possible to re-size it
when I reach
the limit without losing the current data already in 'history'? If so
how?

Thanks,
Jeff
 
B

Ben Pope

Jeff said:
Hello-

Ive never used a vector or vectors in C++ so I have a question for
you all.

I know I can dynamically create the size I need upfront, but is it
possible to create them on the fly dynamically? That is, for a 2 dim
array, I want to create the first element and then push_back the
columns after that:

This code obviously does not work, but this is how I percieve it to
create the initial 'x' or row element, then add each column after
that.

int hist_idx = 0; vector< <vector<int> > history;

history.push_back(hist_idx);

hist_idx is an int. history requires a vector<int>

then

history[hist_idx].push_back(5); history[hist_idx].push_back(2); etc

Thats looks ok.
If I have to statically create it upfront, is it possible to re-size
it when I reach the limit without losing the current data already in
'history'? If so how?

push_back adds an element on the end, and deals with any resizing if
required. All existing elements remain, but iterators may be invalidated.

A vector will have a capacity and a size, if the size is equal to
capacity, and an element is added, the vector is usually reallocated to
twice the original capacity, the elements copied over, and the old
elements deleted.

Ben Pope
 
N

Neil Cerutti

I know I can dynamically create the size I need upfront, but is it
possible to create them on the fly dynamically? That is, for a 2
dim array, I want to create the first element and then push_back the
columns after that:

This code obviously does not work, but this is how I percieve it to
create the initial 'x' or row element, then add each column after
that.

You are very close to working code.
int hist_idx = 0;
vector< <vector<int> > history;

history.push_back(hist_idx);
then

history[hist_idx].push_back(5);
history[hist_idx].push_back(2);
etc

You have options.

Here's one:

vector< vector<int> > history(10, vector<int>(2));
/* Storage for 10 vectors of vectors of 2 ints. */
history[0][0] = 5;
history[0][1] = 2;
/* etc... */
history[9][0] = 7;

Here's another, if you want a dynamically growing number of vectors of
dynamically growing number of ints:

vector< vector<int> > history;

/* add a vector */
history.push_back(vector<int>());
history[0].push_back(5);
history[0].push_back(2);
history.push_back(vector<int>());
history[1].push_back(4);
history[1].push_back(8);
....
history[9].push_back(7);
 
?

=?ISO-8859-1?Q?Ney_Andr=E9_de_Mello_Zunino?=

Jeff wrote:

[...]
int hist_idx = 0;
vector< <vector<int> > history;

Ok, you have defined a vector called history, whose element type is
vector said:
history.push_back(hist_idx);

And now you are trying to push an int onto that vector.

[...]
If I have to statically create it upfront, is it possible to re-size it
when I reach
the limit without losing the current data already in 'history'? If so
how?

If you know the number of "lines" upfront (i.e., the number of vectors
that will be in the history vector), you can supply that number upon
construction:

const int NUM_LINES = 10;
vector<vector<int> > history(NUM_LINES);

From that point on, you can safely use push_back on each of history's
elements, which are vectors themselves. E.g.:

history[0].push_back(5);
history[0].push_back(22);
history[2].push_back(90);
history[7].push_back(2);
history[7].push_back(86);
history[7].push_back(9);
history[8].push_back(71);

Just realize history is actually a container of vectors which allows you
to access them through their respective numeric index.

I hope that helps a bit.

Regards,
 
A

Aleksander Beluga

Jeff said:
Hello-

int hist_idx = 0;
vector< <vector<int> > history;

history.push_back(hist_idx);

Use

map<int, vector<int> > history;

if you want your columns to be named. Then you can do next:

history[hist_idx].push_back(...);
 
J

Jeff

Ok, actually thats a good point about map, I do need a vector of
maps as well I think:

std::vector< std::map< int, std::vector<int> > > connected;

I have another need for a history list of items that have multiple
indexes.

It looks like this:

history idx object idx list of connected objects
------------ ---------- ----------------------------
0 1 3 5 9 10
1 2 4
2 3 5 9 10
and so on

So to initialize the first element I tried:

connected.push_back( map<int, vector<int>() > );

then to push them:

map <int, vector<int> > con_map;
con_map.insert(1,3);
con_map.insert(1,5);
con_map.insert(1,9);
con_map.insert(1,10);

int hist = 0;
connected.push_back(hist, con_map);

Thanks again for helping me do this and learning more about STL
Jeff
 
J

Jeff

Ok, actually thats a good point about map, I do need a vector of
maps as well I think:

std::vector< std::map< int, std::vector<int> > > connected;

I have another need for a history list of items that have multiple
indexes.

It looks like this:

history idx object idx list of connected objects
------------ ---------- ----------------------------
0 1 3 5 9 10
1 2 4
2 3 5 9 10
and so on

So to initialize the first element I tried:

connected.push_back( vector<int>(), map<int, vector<int>() > );

then to push them:

map <int, vector<int> > con_map;
con_map.insert(1,3);
con_map.insert(1,5);
con_map.insert(1,9);
con_map.insert(1,10);

int hist = 0;
connected.push_back(hist, con_map);

Thanks again for helping me do this and learning more about STL
Jeff
 
B

BobR

Jeff wrote in message
awesome! I got it now, thanks guys!

Jeff

You got it? They just gave me heartburn!! <G>

size_t rows( 6 ); // use unsigned type
size_t cols( 4 ); // ...to avoid surprises
// an 'int rows = -1;' will be a *huge* size in vector init.
// if you must use 'int', make it 'const' and be sure the
// value is what you want

std::vector<std::vector<int> > vec2D( rows, cols ); // 6x4 init'ed to 0's
std::vector<std::vector<int> > vec2D7( rows,
std::vector<int>( cols, int(7) ) ); // 6x4 init'ed to 7's
// ---------------
#include <stdexcept> // out_of_range
try{
if( 4 < rows ){
vec2D.at( 4 ).push_back( 22 ); // add an col to 5th row
// use 'at()' to index when not positive it's in range
}

for(size_t i(0); i < vec2D.size(); ++i){
for(size_t j(0); j < vec2D.at(i).size(); ++j){
std::cout<<" vec2D.at("<<i<<").at("<<j<<")= "
<<vec2D.at( i ).at( j )<<std::endl;
// either kind of index would be OK here because
// the vectors size() controls range.
// std::cout<<" vec2D["<<i<<"].at("<<j<<")= "
// <<vec2D[ i ].at( j )<<std::endl;
} //for(j)
} //for(i)

// this next line will 'throw out_of_range()' ( from 'at()' )
std::cout<<" vec2D.at(6).at(4)= "
<<vec2D.at(6).at(4)<<std::endl;

} //try
catch(std::eek:ut_of_range &Oor){
std::cout<<"caught "<<Oor.what()<<std::endl;
}

If you don't understand all this, stash the post for later, or ask for more
info.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top