Create a vector in C++ with constant values - c++

I want to create a vector by determining the size and the constant value which the vector has, e.g. a vector of the size 5 and only 3 as values.
vector = {3, 3, 3, 3, 3}
I only know how to create a vector with zero as value with std::vector<int> vec(5);

You can use a constructor that accepts a count and a value.
std::vector<int> v (5,3);
Will result in having a vector of a size 5 and 3 as a values {3,3,3,3,3}.

Related

Why are some ARRAYS written like this in C++?

I just wanted to know why are some arrays written like this?
int arr[] = {3, 4, 6, 9, 11};
Why can't it just be written like this instead?
int arr[5] = {3, 4, 6, 9, 11}
What's the benefit?
Why can't it just be written like this instead?
The premise is wrong. It can be written both ways.
What's the benefit?
The size is redundant information. We've already implicitly given the size 5 by providing 5 initialisers. Providing redundant information is a potential source of bugs during development when that information accidentally goes out of sync.
For example, if the programmer decides later that the last 11 wasn't supposed to be there and should be removed leaving 4 elements in the array, the programmer making that change might not notice that the size has to also be changed, leading to a case where the last element is not removed as intended but replaced with value initialised element instead.
If the size of the array is supposed to be the same as the number of initialisers, then it is safer to not specify that size explicitly. To not specify the size explicitly is to follow the "Don't Repeat Yourself" principle.
On the other hand, if the size of the array is always supposed to be 5 regardless of the number of initialisers, then specifying the size explicitly achieves that. I suspect that this case is rarer in practice (except when there are no initialisers at all). Note that you should probably use a constant variable instead of a magic number for the size.
When you don't write any number into brackets, it means the array will have size equal to count of elements intialized with.
When you put there some number, you are giving the array a size.
int arr[] = {1, 7, 5}; // Size of the array is 3
int arr[3] = {1, 7, 5}; // Size of the array is 3
int arr[5] = {1, 7, 5}; // Size of the array is 5
Declaring with defined size is good when you know that you will need this count of items, but you don't have the items yet.
Without defined size it is simply easier to write.

Memory allocation in C++ STL for dynamic containers

When you declare 2D arrays, they are stored in contiguous memory locations and this is easy as the number of rows is fixed while declaring them.
Whereas when we declare a 2D vector vector<vector<int>> v, how does it work. As the number of rows is not fixed at all. My first guess was the new vector which you push_back into it are randomly allocated but then even that wont work as these vectors of int are randomly accessible.
My first guess is to allocate vectors of int randomly in the memory and store their address in another vector of addresses.
eg
vector<vector<int>> vmain;
vector<int> a = {1, 2, 3};
vector<int> b = {1, 2, 3};
vector<int> c = {1, 2, 3};
vmain.push_back(a);
vmain.push_back(b);
vmain.push_back(c);
is stored something similar to
vector<&vector<int>> vmain; //vector of pointer to vector
vector<int> a = {1, 2, 3};
vector<int> b = {1, 2, 3};
vector<int> c = {1, 2, 3};
vmain.push_back(&a);
vmain.push_back(&b);
vmain.push_back(&c);
Please tell me if this is the correct way.
And also for vector of maps or sets vector<map<int, int>> v1 and vector<set<int>> v2. As size of maps and sets is not fixed.
The vector object doesn't store the elements. It stores a pointer to a contiguous chunk of memory containing the elements. When you have std::vector<std::vector<int>> the outer vector contains a pointer to a contiguous chunk of memory containing vector objects, each of which have a pointer to a contiguous chunk of memory containing the ints.
std::map and std::set also don't store the elements in the object itself. Each object contains a pointer to a BST containing the elements.

How do I make multi dimensional in C++?

I have this array
int sequence[2][3][2][2][50][2] = {
{
{1},
{{
{2, 4},
{3, 5}
},
{255,0,0}
}
},
{
{2},
{{
{3, 4},
{2, 6}
},
{0,0,255}
}
}
};
Whenever I try to index the first multi dimensional array, using
int frame[2] = {sequence[1]}
I get this error "invalid conversion for 'int (*)[2][2][50][2]' to 'int' [-fpermissive]
What am I doing wrong?
Whenever I try to index the first multi dimensional array, using
int frame[2] = {sequence[1]}
Let's simplify the syntax you use:
int frame[2] = {/*list of ints*/}
This initializes a one dimensional array of 2 int, using a brace-enclosed list of integers.
An element of your outermost multi-dimensional array with arity k, is also a multi-dimensional array (with arity k-1). It is not an int.
So, there is nothing wrong with how you index the multi-dimensional array. What is wrong, is trying to initialize an array if int with a multi-dimensional array as the first value.
How should I initialize it then?
It is impossible to answer because it is not clear which of the integer values within the multi-dimensional array you want to use to initialize.
Here is a syntactically correct way to initialize frame:
int frame[2] = {sequence[0][0][0][0][0][0], sequence[0][0][0][0][0][1]};
It uses the values in the first subarray of the first subarray of the first subarray of the first subarray of the first subarray of the outermost array.

How to insert only a few data in vector in c++? [duplicate]

This question already has answers here:
What is the easiest way to initialize a std::vector with hardcoded elements?
(29 answers)
Closed 7 years ago.
I want to insert only few values say 3 integers in a vector.Is there any way other than this
vector<int>v;
v.push_back(a1);
v.push_back(a2);
v.push_back(a3);
Any way other than this.Anything in one line ?
Something like this would work:
int arr[] = { 4, 5, 6, 7 };
std::vector<int> v1 (arr, arr + sizeof(arr) / sizeof(arr[0]));
If you're using C++11, you have more options:
std::vector<int> v2 (std::begin(arr), std::end(arr));
or, even better, without a temporary array:
std::vector<int> v3 { 1, 2, 3 };
if you are aware before hand how much elements are needed to placed in vector, you can std::vector::reserve function. But it will not shrink the initial capacity of the vector.
To make sure the capacity is of low count say 3 in your case, you may need to use C++11 function added, std::vector::shrink_to_fit() function. Here you can pass int parameter in this function to make sure you only reserve elements you want in vector. example usage.
vector<int> vi;
vi.shrink_to_fit(3); // only takes 3 elements.
// now add 3 elements as you need.
hope this helps.

Copy arrays-vectors

This might be too basic, but I would like to ask. I have my code in Java that copies the start array to newStart and assigns the last element to another array.
int[] newStart= Arrays.copyOf(start, start.length + 1);
newStart[start.length] = array[i];
I converted it to my C++ version with vectors as:
vector<int> newStart(5); //Doesnt have to be 5, sth not known
newStart.insert(newStart.end(), start.begin(), start.end());
newStart[start.size()] = array[i];
However, my code doesn't do what I require. That adds the vector one to the other's end, and makes new assignments accordingly. What is the right way to do that?
C++ vectors don't auto-resize on element access (through operator[] nor at method). Replace the last line with either
newStart.push_back(array[i]);
or
newStart.resize(start.size() + 1);
newStart[start.size()] = array[i];
(the former being more efficient, because it does not default-initialize the element first)
I believe Java arrays don't auto-resize either, so I wouldn't expect the Java code to work either (but it will give exception while the C++ code will make daemons fly out of your nose or whatever else nasty the compiler will think of).
Edit: Reading the question again, the code there is actually defined, but the more wrong.
vector<int> newStart(5); //Doesnt have to be 5, sth not known
This statement actually creates a vector that contains 5 (or whatever) default initialized elements, which in case of int is 0. So now you have
{0, 0, 0, 0, 0}
For sake of example let's say start contains {1, 2, 3, 4, 5, 6, 7}.
newStart.insert(newStart.end(), start.begin(), start.end());
vector::insert adds new elements extending the array and moving the following elements as necessary. The insert is before end, so it will append to the vector, resulting in:
{0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7}
I don't think this is what you wanted. It looks like you wanted a copy of start. Which you'd simply create by copy constructing: vector<int> newStart(start).
newStart[start.size()] = array[i];
Now newStart has the initial 5 zeroes and the elements from start, so it's size is start.size() + 5 and therefore it does have index start.size(). It is the 5th element from end. So per above example, this will modify the vector to:
{0, 0, 0, 0, 0, 1, 2, 1, 4, 5, 6, 7}
^
To append start[0] to the end, use push_back as per above.
Also remember, that Java arrays are reference types, where assignment just shares reference to the same array, but C++ vectors are value types where the content is copied on assignment.
I'm a little confused by the mixing of Java and C++. Hopefully one of the explinations below will help.
If you're in C++, vector has an overloaded operator= so you can just type
newvector = oldvector;
and it will copy.
If you're in java, you can use the copy constructor ex:
Vector v2 = new Vector(v1);
Try this:
for (std::vector<int>::iterator it = start.begin() ; it != start.end(); ++it) {
newStart.push_back (*it);
}
Use std::copy algorithm and back_inserter iterator.
Sample code:
#include <iterator>
#include <vector>
#include <algorithm>
int main () {
std::vector<int> src;
std::vector<int> dest;
std::copy(src.begin(),src.end(),back_inserter(dest));
}