I want to add a value multiple times to an std::vector. E.g. add the interger value 1 five times to the vector:
std::vector<int> vec;
vec.add(1, 5);
vec should be of the form {1,1,1,1,1} afterwards. Is there a clean c++ way to do so?
It really depends what you want to do.
Make a vector of length 5, filled with ones:
std::vector<int> vec(5, 1);
Grow a vector by 5 and fill it with ones:
std::vector<int> vec;
// ...
vec.insert(vec.end(), 5, 1);
Or resize it (if you know the initial size):
std::vector<int> vec(0);
vec.resize(5, 1);
You can also fill with elements using one of the many versions of fill, for example:
fill_n(back_inserter(vec), 5, 1);
and so on.... Read the library documentation, some of these functions return useful information, too.
Just use std::vector::insert.
#include <vector>
#include <iostream>
int main()
{
std::vector<int> a;
a.insert(a.end(), 5, 1);
for(auto const& e : a)
std::cout << e << std::endl;
return 0;
}
You can just use the std::vector constructor for this:
std::vector<int> vec (5,1);
The signature for this is:
vector (size_type n, const value_type& val)
The standard algorithm header has a number of functions which can be used in cases like this. std::fill_n would work for your case.:
std::fill_n (std::back_inserter(vec), 5, 1);
You can use the assign method:
vec.assign(5, 1);
This will delete any existing elements in the vector before adding the new ones.
Related
Is there a way to initialize first few elements of a vector after defining the size of the vector like -
vector<int> vec (10);
This doesn't work and produces a compiler error -
vector<int> vec(10) {1,2,3};
For example with arrays we can do the same thing like -
int arr[5] {1,2,3}; // This will initialize the first 3 elements of the array to 1,2,3 and the remaining two to 0.
In short, no. Your can fill out the entire list of things you want to be in the vector:
vector<int> vec{1, 2, 3, 0, 0, 0, 0, 0, 0, 0};
Which will give you a vector of 10 elements.
Or, you can create the vector, then call resize to make it larger (filling the remaining elements with 0):
vector<int> vec{1, 2, 3};
vec.resize(10);
You generally don't need to do this kind of thing to vector though, because unlike array, you can extend vector as needed, after creation:
vector<int> vec{1, 2, 3};
vec.push_back(4);
There isn't a way to do it all in one line like you can with an array. You can use
vector<int> vec{1,2,3};
vec.resize(10);
but that does make the code a little less easy to use. Another option is to wrap that in a function like
template <typename T>
auto make_sized_vector(std::intializer_list<T> il, std::size_t size = 0)
{
const auto vec_size = std::max(size, il.size());
vector<T> vec; // create vector
vec.reserve(vec_size); // allocate all the storage needed
vec.assign(il); // assign the elements
vec.resize(vec_size); // set the rest to zero
return vec;
}
and then you can use that like
auto vec = make_sized_vector<int>({1, 2, 3}, 10);
If you are concerned about passing the std::intializer_list by value see why is `std::initializer_list` often passed by value? for why that really isn't a concern.
In case you want to initialize a vector the way you describe, all at once, so that it can become (e.g.) a const member, this is always possible in C++, with just a bit of ugliness and twisting. Let’s say you have a class:
struct SomeClass {
SomeClass(const std::vector<int> &start, int rest, std::size_t size);
const std::vector<int> some_vector_; // This is const!
};
What the constructor could look like:
SomeClass::SomeClass(const std::vector<int> &start, int rest, std::size_t size)
: some_vector_{[&start, rest, size] {
std::vector<int> some_vector;
some_vector.reserve(size);
some_vector.insert(some_vector.end(), start.begin(), start.end());
some_vector.insert(some_vector.end(), size - start.size(), rest);
return some_vector;
}()} {}
Basically the problem boils down to: How do I do “something procedural” in an initializer list? To which the answer is: You invoke a function that returns the desired type.
To test the construct above:
#include <cstdint>
#include <iostream>
#include <vector>
namespace { /* SomeClass stuff from above goes here. */ }
int main() {
SomeClass sc{{1, 2, 3}, 0, 10};
for (int i : sc.some_vector_) std::cout << i << '\n';
}
There are (of course) plenty of ways to make it (slightly) more efficient if needed, such as
a templated variadic constructor to create the initial part of the vector,
a templated perfect-forwarding constructor to benefit from R-value containers, and
as a combined benefit of the above, arbitrary iterable containers as inputs and as the const member.
What is the simplest way to convert array to vector?
void test(vector<int> _array)
{
...
}
int x[3]={1, 2, 3};
test(x); // Syntax error.
I want to convert x from int array to vector in simplest way.
Use the vector constructor that takes two iterators, note that pointers are valid iterators, and use the implicit conversion from arrays to pointers:
int x[3] = {1, 2, 3};
std::vector<int> v(x, x + sizeof x / sizeof x[0]);
test(v);
or
test(std::vector<int>(x, x + sizeof x / sizeof x[0]));
where sizeof x / sizeof x[0] is obviously 3 in this context; it's the generic way of getting the number of elements in an array. Note that x + sizeof x / sizeof x[0] points one element beyond the last element.
Personally, I quite like the C++2011 approach because it neither requires you to use sizeof() nor to remember adjusting the array bounds if you ever change the array bounds (and you can define the relevant function in C++2003 if you want, too):
#include <iterator>
#include <vector>
int x[] = { 1, 2, 3, 4, 5 };
std::vector<int> v(std::begin(x), std::end(x));
Obviously, with C++2011 you might want to use initializer lists anyway:
std::vector<int> v({ 1, 2, 3, 4, 5 });
Pointers can be used like any other iterators:
int x[3] = {1, 2, 3};
std::vector<int> v(x, x + 3);
test(v)
You're asking the wrong question here - instead of forcing everything into a vector ask how you can convert test to work with iterators instead of a specific container. You can provide an overload too in order to retain compatibility (and handle other containers at the same time for free):
void test(const std::vector<int>& in) {
// Iterate over vector and do whatever
}
becomes:
template <typename Iterator>
void test(Iterator begin, const Iterator end) {
// Iterate over range and do whatever
}
template <typename Container>
void test(const Container& in) {
test(std::begin(in), std::end(in));
}
Which lets you do:
int x[3]={1, 2, 3};
test(x); // Now correct
(Ideone demo)
One simple way can be the use of assign() function that is pre-defined in vector class.
e.g.
array[5]={1,2,3,4,5};
vector<int> v;
v.assign(array, array+5); // 5 is size of array.
One way can be to use the array's bound in one go like this:
int a[3] = {1, 2, 3};
vector<int> v(a, *(&a+1));
I have two vectors. I want to make a new vector which contains the values of these two vectors. I found that a fast way can be use as
vector<int> original_vector
vector<int> copy_to_vector(original_vector)
However, it does not show how to copy two vectors (above only for one to other). Now my problem is
vector<int> original_vector1
vector<int> original_vector2
//Copy original_vector1 and original_vector2 to copy_to_vector
// Note that original_vector1 or original_vector2 maybe empty
vector<int> copy_to_vector
How can I do it in C++. I am using g++ in Ubuntu
My current solution is
std::vector<U32> copy_to_vector(original_vector1);
copy_to_vector.insert(copy_to_vector.end(), original_vector2.begin(), original_vector2.end());
vector<int> copy_to_vector(original_vector1)
copy_to_vector.reserve(original_vector1.size() + original_vector2.size());
copy_to_vector.insert( copy_to_vector.end(), original_vector2.begin(), original_vector2.end());
This solution works fine if one of the vectors or both of them are empty
live demo
It's often a good idea to encapsulate operations like this in a utility function.
RVO takes are of eliding the copy of the return value so this code is as efficient as inlining the operations, but more maintainable and easier to reason about:
#include <iostream>
#include <vector>
#include <algorithm>
// utility function to return a new vector which is the
// result of v1 with v2 appended. order is preserved
std::vector<int> combine(const std::vector<int>& v1,
const std::vector<int>& v2)
{
std::vector<int> result;
result.reserve(v1.size() + v2.size());
result = v1;
result.insert(result.end(), v2.begin(), v2.end());
return result;
}
int main()
{
using namespace std;
vector<int> x = { 1, 2, 3 };
vector<int> y = { 4, 5, 6 };
auto z = combine(x, y);
copy(begin(z), end(z), ostream_iterator<int>(cout, "\n"));
return 0;
}
Use std::back_inserter
#include <iterator> // back_inserter
#include <algorithm> // copy
vector<int> copy_to_vector;
copy_to_vector.reserve( original_vector1.size() + original_vector2.size() ) // reserve memory for both vectors at once
copy_to_vector = original_vector1;
std::copy(original_vector2.begin(),original_vector2.end(),std::back_inserter(copy_to_vector));
I'm having a brain fart at the moment and I am looking for a fast way to take an array and pass half of it to a function. If I had an array A of ten elements, in some languages I could pass something like A[5:] to the function and be done with it. Is there a similar construct in c++? Obviously I'd like to avoid and sort of looping function.
Yes. In plain C you use pointers, but in C++ you can use any kind of iterator (a pointer can be considered an iterator).
template<typename Iter>
void func(Iter arr, size_t len) { ... }
int main() {
int arr[10];
func(arr, 10); // whole array
func(arr, 5); // first five elements
func(arr + 5, 5); // last five elements
std::vector<Thing> vec = ...;
func(vec.begin(), vec.size()); // All elements
func(vec.begin(), 5); // first five
func(vec.begin() + 5, vec.size() - 5); // all but first 5
return 0;
}
The typical trick is to pass a pointer to the first element of the array, and then use a separate argument to pass the length of the array. Unfortunately there are no bounds checks, so you have to be careful to get it right or you will scribble on your memory.
You can also use half-open ranges. This is the most common way to do it. Many functions in the standard library (like std::sort) work this way.
template<class Iter>
void func(Iter start, Iter end) { ... }
int main() {
int arr[10];
func(arr, arr + 10); // whole array
func(arr, arr + 5); // first five elements
func(arr + 5, arr + 10); // last five elements
std::vector<Thing> vec = ...;
func(vec.begin(), vec.end()); // whole vector
func(vec.begin(), vec.begin() + 5); // first five elements
func(vec.begin() + 5, vec.end()); // all but the first five elements
return 0;
}
Again, no bounds checks.
i also had the same use but instead i used vector and used the syntax
vector <int> a(10);
// for example to use by removing first element
a = std::vector<int>(a.begin() + 1, a.end())
//its ur turn to change the size
I want to use a special method to initialize a std::vector<unsigned int> which is described in a C++ book I use as a reference (the German book 'Der C++ Programmer' by Ulrich Breymann, in case that matters). In that book is a section on sequence types of the STL, referring in particular to list, vector and deque. In this section he writes that there are two special constructors of such sequence types, namely, if Xrefers to such a type,
X(n, t) // creates a sequence with n copies of t
X(i, j) // creates a sequence from the elements of the interval [i, j)
I want to use the second one for an interval of unsigned int, that is
std::vector<unsigned int> l(1U, 10U);
to get a list initialized with {1,2,...,9}. What I get, however, is a vector with one unsigned int with value 10 :-| Does the second variant exist, and if yes, how do I force that it is called?
there are at least three ways that you can do that. One was mentioned earlier by Brian
//method 1
generate(v.begin(), v.end(), [] { static int i {1}; return i++; });
You can also use std::iota if you are using c++11
//method 2
iota(v.begin(), v.end(), 1);
Or instead you can initialize your container with 1s and then do a partial sum on that. I don't think anybody will use this third method anyway :)
//method 3
vector<int> v(n, 1);
partial_sum(v.begin(), v.end(), v.begin());
Reread the paragraphs near there describing what each of the parameters are. Specifically, it should mention that i and j are not values, but iterators. This constructor is very commonly used to make copies of other types of containers. If you want to get a sequence of values, the Boost library provides a counting iterator, that does exactly what you want.
std::vector<unsigned int> numbers(
boost::counting_iterator<unsigned int>(0U),
boost::counting_iterator<unsigned int>(10U));
A non-boost way to do this with a self-incrementing iterator.
#include <vector>
#include <iostream>
#include <algorithm>
static int NUM_ITEMS = 10;
class gen_range {
public:
gen_range(int i) { idx = i; }
int operator()() { return (idx++); };
int idx;
};
int main() {
std::vector<int> x(NUM_ITEMS);
std::generate_n(x.begin(), NUM_ITEMS, gen_range(0));
for (int i=0; i < x.size(); i++) {
std::cout << x[i] << std::endl;
}
}
C++11:
std::vector<int> idxs (n);
std::generate_n (idxs.begin (), n, [] { static int i {1}; return i++; });
No, that variant does not exist. The second constructor initializes a vector from two iterators that point into another sequence.
Here is an example of the "two-iterator" constructor in action:
int fill_data[4] = { 1, 2, 3, 4 };
std::vector<int> v(fill_data, fill_data + 4);