This question already has answers here:
How do I perform a pairwise binary operation between the elements of two containers?
(3 answers)
Closed 8 years ago.
Is there any implemented method in the C++ library which allows you to sum the values of two vectors (of the same size and type of course)?
For example:
std::vector<int> a;//looks like this: 2,0,1,5,0
std::vector<int> b;//looks like this: 0,0,1,3,5
Now then adding their values together should look like this:
//2,0,2,8,5
The answer I'm expecting is either "No there isn't" or "yes" + method.
You can use std::transform and std::plus<int>()
std::vector<int> a;//looks like this: 2,0,1,5,0
std::vector<int> b;//looks like this: 0,0,1,3,5
// std::plus adds together its two arguments:
std::transform (a.begin(), a.end(), b.begin(), a.begin(), std::plus<int>());
// a = 2,0,2,8,5
This form of std::transform takes 5 arguments:
Two first are input iterators to the initial and final positions of the first sequence.
The third is an input iterator to the initial position of the second range.
The fourth is an output iterator of the initial position of the range where the operation results are stored.
The last argument is a binary function that accepts two elements as argument (one of each of the two sequences), and returns some result value convertible to the type pointed by OutputIterator.
Related
This question already has answers here:
How do I get the index of an iterator of an std::vector?
(9 answers)
Closed 2 years ago.
I found some c++ code that I would like to understand. In this code they use
int airplane = min_element(min_cost_airplane.begin(),
min_cost_airplane.end()) - min_cost_airplane.begin();
But I don't know what this line of code exactly accomplishes. min_cost_airplane is a vector. I understand the min_element function, but I can't wrap my head around the -vector.begin at the end. Is the structure of this line of code common used? The thing I understand is that this line of code returns an iterator to the smallest element in the vector minus an iterator to the first element of the vector. So what does the iterator point to?
Can someone please help me?
The std::min_element algorithm returns an iterator. You can dereference that iterator to access the "minimum" element of the container. If, instead, you want to know the index of the element you need to compute it as the distance from the beginning of the container.
For random-access iterators you can subtract the iterators to get the offset, or index value. That's what your example does. There's also a std::distance function that computes the index but it also works for non-random access iterators. For example:
auto iter = std::min_element(min_cost_airplane.begin(), min_cost_airplane.end());
int index = std::distance(min_cost_airplane.begin(), iter);
std::min_element returns an iterator to the first instance of the minimum value in the given range.
begin returns an iterator to the first element in the container.
The std::vector iterators are special (it's a random access iterator) in that you can subtract one from another which yields the distance between them in terms of elements (it's pointer arithmetic under the hood). To be more generic and clearer, write
auto airplane = std::distance(
min_cost_airplane.begin(),
std::min_element(min_cost_airplane.begin(), min_cost_airplane.end())
);
std::min_element is used to finds the smallest element in the range [first, last].
std::vector<int> v{3, 8, 4, 2, 5, 9};
std::vector<int>::iterator result = std::min_element(v.begin(), v.end());
//result iterator to the minimum value in vector v.
std::cout << "min element is: " << *result;
output: min element is: 2
Note : The smallest value in vector v is 2.
This question already has answers here:
Move all elements which satisfy some condition from one container to another, i.e. I'm looking for some kind of "move_if"
(3 answers)
Closed 4 years ago.
I have
std::vector v_1;
std::vector v_2;
and I want to delete some elements in v_1 but store them in vector v_2 before doing so. Something along the lines
auto deleteIf = [](auto& x) {return x.checkDelete();}
auto it = std::remove_if(v_1.begin(), v_1.end(), deleteIf);
// how can I efficiently copy elements it to v_1 end to v2?
v1.erase(it, v_2.end());
How can I most efficiently copy the elements that will be erased to v_2?
You cannot rely on remove_if to keep your elements intact. From cppreference.com :
[...] Iterators pointing to an element between the new logical end and the physical end of the range are still dereferenceable, but the elements themselves have unspecified values [...]
You have to somehow move them.
You can partition your vector and than split it into two:
std::vector<type> v_1;
std::vector<type> v_2;
auto split_check = [](auto&) { x.checkDelete() };
// stable_partition will keep the order. if not required use std::partition
auto it = std::stable_partition(v_1.begin(), v_1.end(), split_check);
v_2.insert(v2.end(), it, v_1.end());
v_1.erase(it, v_1.end());
running example.
I just realized the duplicate answer from T.C. mentions the exact same thing... ¯\_(ツ)_/¯
I am relative new at C++ and I have little problem. I have vector and in that vector are vectors with 3 integers.
Inner vector represents like one person. 3 integers inside that inner vector represents distance from start, velocity and original index (because in input integers aren't sorted and in output I need to print original index not index in this sorted vector).
Now I have given some points representing distance from start and I need to find which person will be first at that point so I have been thinking that my first step would be that I would find closest person to the given point so basically I need to find lower_bound/upper_bound.
How can I use lower_bound if I want to find the lower_bound of first item in inner vectors? Or should I use struct/class instead of inner vectors?
You would use the version of std::lower_bound which takes a custom comparator (the versions marked "(2)" at the link); and you would write a comparator of vectors which compares vectors by their first item (or whatever other way you like).
Howerver:
As #doctorlove points out, std::lower_bound doesn't compare the vectors to each other, it compares them to a given value (be it a vector or a scalar). So it's possible you actually want to do something else.
It's usually not a good idea to keep fixed-length sequences of elements in std::vector's. Have you considered std::array?
It's very likely that your "vectors with 3 integers" actually stand for something else, e.g. points in a 3-dimensional geometric space; in which case, yes, they should be in some sort of class.
I am not sure that your inner things should be std::vector-s of 3 elements.
I believe that they should std::array-s of 3 elements (because you know that the size is 3 and won't change).
So you probably want to have
typedef std::array<double,3> element_ty;
then use std::vector<element_ty> and for the rest (your lower_bound point) do like in einpoklum's answer.
BTW, you probably want to use std::min_element with an explicit compare.
Maybe you want something like:
std::vector<element_ty> vec;
auto minit =
std::min_element(vec.begin(), vec.end(),
[](const element_ty& x, const element_ty&y) {
return x[0] < y[0]));
This question already has answers here:
How can I pass a part of a vector as a function argument?
(7 answers)
Closed 5 years ago.
I want to see if it is possible to pass part of vector to a function so that it appears as a normal vector to the function. More importantly, I want this to be done in O(1), constant time. I don't want to iterate the vector to make a new one. In fact, I also want the size of the new vector to change to 40 in the following example.
void func(vector <int> &v){
//calling index 10 to 50 of v
func(v[10..50])
}
Use iterators as the parameters to the range-based function, and pass in the required range. Your code in the function become
funcWithRange(v.cbegin()+10, v.cbegin()+50);
with function signature
void funcWithRange(std::vector<int>::const_iterator first, std::vector<int>::const_iterator last)
This could be generalized by making this a function template with the vector member type as its template parameter, or still further to any container supporting this type of range iteration. As noted in the comments, <algorithm> has many examples of this pattern.
std::distance(first, last); will return the desired altered size. I don't think you can get closer to meeting your requirements without making a physical copy.
If you have a vector of say 100 elements
std::vector<int> v(100);
and you want to call void f(std::vector<int> v) with the first 10 elements, simply call the function as
f({v.cbegin(), v.cbegin() + 10});
That will construct a new vector from the two iterators (by copying the elements) and pass the new vector to f.
There is a means to achieve something similar to this that is being proposed for inclusion in the C++ standard. It is called a span and it operates like a vector in some ways.
#include <gsl/span>
void func(gsl::span<int> sp)
{
for(auto& i: sp)
std::cout << i << '\n';
}
int main()
{
// ...
std::vector<int> v(100);
// put something in the vector (numbers 0 - 99)
std::iota(std::begin(v), std::end(v), 0);
// wrap the container in a span
auto sp = gsl::make_span(v);
// send parts of it to functions
func(sp.subspan(10, 50));
}
The span presents a window onto the original vector so it is a reference type. It doesn't contain its own data just pointers to the data in the vector. As such they are lightweight and designed to be passed by value.
An implementation of span can be found here: https://github.com/Microsoft/GSL
This is the recommended way of passing contiguous containers in the Best Practices guide by Bjarne Stroustrup and Herb Sutter.
The guidelines can be found here: CppCoreGuidelines.md
This question already has answers here:
Sorting a std::vector<std::pair<std::string,bool>> by the string?
(5 answers)
Closed 9 years ago.
I have a question about sorting a vector of pairs:
std::vector<std::pair<double,Processor*>> baryProc;
this vector is already filled up with the pairs.
Now I wanted to sort the pairs inside the vector based on the double value inside the pair
EXAMPLE:
suppose I have 3 pairs inside the vector. pair1 is at front and pair 3 is at end. pair2 is in the middle:
pair1(1, proc1)
pair2(3, proc2)
pair3(2.5, proc3)
now i want to sort the pairs based on the double value. So that the order inside the vector is:
pair1(1, proc1)
pair3(2.5, proc3)
pair2(3, proc2)
How could I do this? I am quite stuck.
#include <algorithm>
int main(){
std::vector<std::pair<double,Processor*>> baryProc;
std::sort(baryProc.begin(),baryProc.end());
}
Note that you do not need a custom comparator because the default comparator of pair does the thing you want. It first compares by the first element and if they are identical, it compares the second element in the pair.
In C++, you can have custom comparator functions that specify how to decide whether one element goes before another when sorting. In your case, given 2 pairs, you want the one with the lower value for the first element to go before the other one. You can write a comparator function like so:
// This function returns true if the first pair is "less"
// than the second one according to some metric
// In this case, we say the first pair is "less" if the first element of the first pair
// is less than the first element of the second pair
bool pairCompare(const std::pair<double, Processor*>& firstElem, const std::pair<double, Processor*>& secondElem) {
return firstElem.first < secondElem.first;
}
Now, pass this function into your sort method:
//The sort function will use your custom comparator function
std::sort(baryProc.begin(), baryProc.end(), pairCompare);