I have already two STL vectors. For instance:
vector<int> MyList;
MyList.push_back(10);
MyList.push_back(20);
MyList.push_back(30);
MyList.push_back(40);
MyList.push_back(50);
vector<int> MyListSub;
MyListSub.push_back(20);
MyListSub.push_back(30);
MyListSub.push_back(40);
And I want to get the number of elements which is in the MyListSub and isn't in MyList.
For this instance, result is "2"
You can use std::set_difference for this:
std::vector<int> diff;
std::set_difference(MyList.begin(), MyList.end(),
MyListSub.begin(), MyListSub.end(),
std::back_inserter(diff));
As #Jan points out, the vectors have to be sorted. If they are not, use std::sort to sort them:
std::sort(MyList.begin(), MyList.end());
Alternatively you can consider storing your elements in an std::set in the first place, thus they will already be sorted.
Related
How do you remove elements from a vector of vectors that are identical to another vector but whose elements are not in the same indices?
For example:
std::vector<vector<int>> vectA = {{1,3,4}. {1,2,3}, {3,2,1};
I want it so that {3,2,1} is removed from vectA and it becomes:
vectA = {{1,3,4}, {1,2,3}}
Any idea how to proceed efficiently?
Sort the elements of each vector
Drop duplicates (this is an easy look-up)
If you need to retain the original element order, then build any correspondence you wish: parallel arrays of vectors (original and sorted), pairs of (unsorted, sorted) vectors, etc. Drop duplicates based on the sorted ones.
I trust that you can take it from here.
What you are describing is the behavior of std::set, ie. this solves your problem:
set<set<int>> input = {{1,3,4}, {1,2,3}, {3,2,1}};
// input is now {{1,2,3},{1,3,4}}
This works because a set is basically equal to a sorted vector with no duplicates.
If you really want to, you can now convert to std::vector:
vector<vector<int>> nums;
for(auto & s : input) nums.emplace_back(s.begin(), s.end());
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]));
I have two unordered_set and want the intersection of those. I can't find a library function to do that.
Essentially, what I want is this:
unordered_set<int> a = {1, 2, 3};
unordered_set<int> b = {2, 4, 1};
unordered_set<int> c = a.intersect(b); // Should be {1, 2}
I can do something like
unordered_set<int> c;
for (int element : a) {
if (b.count(element) > 0) {
c.insert(element);
}
}
but I think there should be a more convenient way to do that? If there's not, can someone explain why? I know there is set_intersection, but that seems to operate on vectors only?
Thanks
In fact, a loop-based solutions is the best thing you can use with std::unordered_set.
There is an algorithm called std::set_intersection which allows to find an intersection of two sorted ranges:
Constructs a sorted range beginning at d_first consisting of elements
that are found in both sorted ranges [first1, last1) and [first2,
last2).
As you deal with std::unordered_set, you cannot apply this algorithm because there is no guaranteed order for the elements in std::unordered_set.
My advice is to stick with loops as it explicitly says what you want to achieve and has a linear complexity (O(N), where N is a number of elements in the unordered set you traverse with a for loop) which is the best compexity you might achieve.
There is a function from std called set_intersection. However, it would have a very high complexity using it with std::set as input parameter.. A better solution is, create two vectors from those sets and use set_intersection with vectors as input parameters.
Suppose I have a vector A = {1,1,1,0,0};
Is there any inbuilt function in vector header to find all the indices of vector where A is repeated?
suppose for 1, returning, { 0,1,2 }
for 0, {3,4}
If not, is there any time efficient way to do so?
If not, is there any time efficient way to do so?
Sort your vector and use std::equal_range to find iterators range, then convert them to indexes. If you cannot sort the vector, create vector of indexes, sort it and copy the range from it to result.
If the vector is or can be sorted, then you can use std::equal_range.
http://en.cppreference.com/w/cpp/algorithm/equal_range
Given this set
set<string> s = {"a","b","c"};
is it possible to implement next_permutation() to get all combinations, where elements to do not repeat and order matters?
No it is not possible. std::set is an associative container and maintains an strict weak ordering. std::next_permutation transforms the range it is given which would break the ordering.
If you need to get the permutations of the contents of the set I suggest you use a std::vector. You can copy the set into the vector and then get the permutation from that.
std::set<int> set_data;
//fill set
std::vector<int> temp(set_data.begin(), set_data.end());
do
{
// code goes here
}
while(std::next_permutation(temp.begin(), temp.end()));