assigning vector - c++

how I can assign v[i] to an series of integers ( type of v is vector ) without initially filling inside

Do you mean initializing std::vector to a series of integers?
int i[] = {1, 2, 3, 4, 5};
std::vector<int> myVector(i, i+ (sizeof(i)/sizeof(int)));
If you meant to create a vector of some elements so you can perform the assignment using their index values. Here, the following statement declares and initializes a vector with its elements being default initialized to 0.
std::vector<int> myVector(5); // constructs a vector of size five integers.
for (int x = 0; x < 5; x++)
myVector[x] = i[x]; // assign values using subscript [..]
But I think the even better way to go would be as #CashCow mentioned in his answer.
Also, note that you can also pre-allocate memory to add elements into the vector with avoiding any repeated memory allocations.
For example:
std::vector<int> myVector; // empty vector for integers
myVector.reserve(5); // pre-allocates memory for five integers
for (int i = 0; i < 5; i++) // now, you can add your elements
myVector.push_back(i);
It is usually a good idea to pre-allocate memory if you know the size of elements i.e in case of large number of elements when the performance is an important factor.

If you have anything that has the traits of an iterator you can use vector's assign method:
std::vector<int> v;
v.assign( iterStart, iterEnd );
iterStart should be such that *iterStart is the first value you want to add.
iterEnd should be one past the end, it is a terminating condition
++iter would move you to the next iterator in the input series.
I don't know what you mean by assign v[i] though. You cannot assign an element to a series. If you want to write the series at a location into an existing vector you can use insert instead of assign.

common way of adding items is calling std::vector<>push_back() method.
std::vector<int> myVector;
myVector.push_back(5);
myVector.push_back(10);
myVector.push_back(3);

Related

How to give a size to a vector array?

Hello I would like to set 18 elements in my vector array but i'm unsure on how to do it exactly. Would it be like this?
vector<byte> Clients(18);
or like this?
vector<byte> Clients[18];
Vectors are not called vector arrays. They are usually implemented as arrays in the background, but that doesn't change what they are called.
To answer your question, to change the size of a vector you can use the resize member function.
std::vector<int> myvector;
myvector.resize(5);
You can also use resize to initialize all the values. For instance, in the following example there are five 0's in the vector.
std::vector<int> myvector;
myvector.resize(5, 0);
Usually, you just push things into a vector and don't have to set a size. For example:
std::vector<int> myvector;
for (int i = 0; i < 5; i++) {
myvector.push_back(
}
// you now have a vector with a size of 5 that has initialized
// values at indices 0 through 4, inclusive.

Change from static array to vector

here's my code:
vector<int> Edge[1000000]; //size of array must be very high
scanf("%d%d",&N,&M );
//N = size of workable index numbers for Edge
for( i=1;i<=M;i++){
scanf("%d%d",&u,&v );
Edge[u].push_back( v );
}
But as you can see, it's a static array of vectors.
If i change it to this:
vector<vector<int>> Edge;
How can i do that for cycle and pushback? I need to create a vector of N+1 size and each position is also a vector.
I need to create a vector of N+1 size and each position is also a vector.
Considering that you know the size of the external container at compile time, you can also use std::array to store the vectors:
std::array<std::vector<int>, N + 1> Edge;
If you don't know the size at compile time, you could use:
std::vector<std::vector<int>> Edge;
but as a general rule of thumb, tend to avoid vectors of vectors, as they don't usually work nicely.
You can construct vectors of a given size by passing an int to their constructor. Then afterwards you can use a loop to initialize the subvectors.
int size;
vector<vector<int>> Edge(size); //Initializes Outer Array to have 'size' elements
for(auto i:Edge)
{
// i is a vector within Edge
}
The advantage is that you don't have to push back. If you still wanted to push_back in order (not have to track an iterator/int) you could use vector.reserve() instead.

Initializing and setting a vector<int>

vector<int> v;
v.push_back(0); //you have to do this
//v[0] = 0; //this gives you an error
v[0] = 1000000; //but now you can set it
So, how come the first time you initialize a vector, you have to push_back, and after that you can just set it? For a primitive type, say int, you can do int i = 0; for initialization.
If you know in advance the size of your vector, definitively don't use a plain sequence of push_back()'s, since it may be a waste of time reallocating if your vector is large (say, >512 elements).
Better do:
OPTION 1: Preallocating and pushing
vector<int> v;
v.reserve(N); // N is the expected size, but right now [0] is undefined.
for (...) {
v.push_back(...); // No problems in adding more than N elements, but may have to reallocate.
}
OPTION 2: Resizing and filling
vector<int> v;
v.resize(N);
for (size_t i=0;i<N;i++)
v[i] = ...; // You can't write past N-1 here!
OPTION 3: Create directly with the correct size, then fill
vector<int> v(N);
for (size_t i=0;i<N;i++)
v[i] = ...; // You can't write past N-1 here!
OPTION 4: Create a vector with the correct size and initialized to some fixed value
vector<int> v(N,val); // v[0:N-1] are all equal to val
Because when you first create a vector it is empty so vector[0] doesn't exist. push_back adds an element to the vector then you can modify or read it with vector[i]
Just to make everything 100% clear, your declaration of a vector,
vector<int> v;
is in some sense similar to the declaration of a variable:
int x;
and if you then want, say,
cout << x;
you will get rubbish. Though, if you declare
int x(2);
everything will be fine. Similarly for vectors: declaration of
vector<int> v;
allocates some memory space for a vector, but not fills it. You can then specify
vector<int> v(2);
which means that you now have declared a vector of two elements, or go for a vector-only feature - push_back. This would add elements to your vector, as you've noticed.
Because std::vector<int> isn't std::map<int, int>.
std::vector requires you to manually push_back() or (in C++11) emplace_back() elements for them to be included in the collection. And of course some of its constructors allows you to include initial elements to it. And of course again its assignment operators.
The subscript([]) operator should only be used in reading and/or modifying existing elements. Indexing using operator[] out-of-bounds (non-existent) elements would result in undefined behavior.
You can't access v[0] because there is no v[0] yet. The vector starts off default-constructed as an empty vector. You push an element onto the back and it grows in size by 1. You're then able to access the element you just added. If you want it to start off with one element, use the appropriate constructor:
std::vector<int> v(1); //one zeroed integer
You're comparing apples and oranges. int i = 0; would be like std::vector<int> v;.
You should first allocate memory for setting element values, such as
v.resize(new_size);
or use push_back method to add elements.

Multidimensional vector bus error

I have a 11663 Bus Error when I attempt to do the following;
std::vector< std::vector<int> > bullets;
std::vector<int> num;
num[0] = 7;
bullets.push_back(num);
I thought this would work as the vector bullets's type is a vector. Why doesn't this work as expected? Also, the following works;
std::vector< std::vector<int> > bullets;
std::vector<int> num (4, 100);
bullets.push_back(num);
And I don't know why this works, but not my other code.
std::vector<int> num;
num[0] = 7;
num has not yet allocated storage for anything. Only use the indexing syntax [] if you know an element exists at that index. Otherwise, use push_back, which grows the vectors storage capacity if needed. The second example works because you used the constructor which reserves a certain amount of space for elements (4 in this case, all with the value 100).
std::vector<int> num;
num.push_back(7);
bullets.push_back(num);
On a side note, "this doesn't work" is not a very helpful problem description. Also, note that a vector of vectors used as a matrix is not a good idea in performance critical code should you need to iterate over each element.
Don't scrap it just yet and don't worry abut it unless you know for a fact that it will be a problem, but realize that you lose locality of data with this approach because each vector will allocate its storage separately. If this data is being iterated over in a tight loop you are better off allocating one big vector and calculating the offset to each individual position manually.
num[0] = 7;
should be
num.push_back(7);

C++ vector - push_back

In the C++ Primer book, Chapter (3), there is the following for-loop that resets the elements in the vector to zero.
vector<int> ivec; //UPDATE: vector declaration
for (vector<int>::size_type ix = 0; ix ! = ivec.size(); ++ix)
ivec[ix] = 0;
Is the for-loop really assigning 0 values to the elements, or do we have to use the push_back function?
So, is the following valid?
ivec[ix] = ix;
Thanks.
Is the for-loop really assigning 0
values to the elements? Or, we have to
use the push_back finction?
ivec[ix] =0 updates the value of existing element in the vector, while push_back function adds new element to the vector!
So, is the following valid?
ivec[ix] = ix;
It is perfectly valid IF ix < ivec.size().
It would be even better if you use iterator, instead of index. Like this,
int ix = 0;
for(vector<int>::iterator it = ivec.begin() ; it != ivec.end(); ++it)
{
*it = ix++; //or do whatever you want to do with "it" here!
}
Use of iterator with STL is idiomatic. Prefer iterator over index!
Yes, you can use the square brackets to retrieve and overwrite existing elements of a vector. Note, however, that you cannot use the square brackets to insert a new element into a vector, and in fact indexing past the end of a vector leads to undefined behavior, often crashing the program outright.
To grow the vector, you can use the push_back, insert, resize, or assign functions.
Using the array brackets the vector object acts just like any other simple array. push_back() increases its length by one element and sets the new/last one to your passed value.
The purpose of this for loop is to iterate through the elements of the vector.
Starting at element x (when ix is 0) up to the last element (when ix is ivec.size() -1).
On each iteration the current element of the vector is set to 9.
This is what the statement
ivec[ix] = 0;
does. Putting
ivec[ix] = ix;
in the for loop would set all the elements of the vector to their position in the vector. i.e, the first element would have a value of zero (as vectors start indexing from 0), the second element would have a value of 1, and so on and so forth.
Yes, assuming ix is a valid index, most likely: you have a vector of int though and the index is size_type. Of course you may want to purposely store -1 sometimes to show an invalid index so the conversion of unsigned to signed would be appropriate but then I would suggest using a static_cast.
Doing what you are doing (setting each value in the vector to its index) is a way to create indexes of other collections. You then rearrange your vector sorting based on a predicte of the other collection.
Assuming that you never overflow (highly unlikely if your system is 32 bits or more) your conversion should work.