Your algorithm is O (n * m), where n and m are the number of elements in the vectors.
If you have no problems when the input is untrusted, you are likely to get the best results with:
- Put all elements of
A in unordered_set - For each item in
B , if it is in the set, increase the counter.
For example:
int vec_intersect(const std::vector<int>& A_, const std::vector<int>& B_) { std::unordered_set<int> aSet(A_.cbegin(), A_.cend()); return std::count_if(B_.cbegin(), B_.cend(), [&](int element) { return aSet.find(element) != aSet.end(); }); }
This will likely give the results O (m + n). (Hash tables are almost always O (1), but if an attacker can cause many collisions in the table, they can cause O (n) behavior to lead to a denial of service)
If you need deterministic results, and the order of the vectors does not matter, sorting a single vector will work, which will only be O (m lg m + m + n). I.e:
- Sort the first vector
- For each element in the second vector, use a binary search to determine if the element is in the first vector, and if so, increase your counter.
For example:
int vec_intersect(std::vector<int>& A_, const std::vector<int>& B_) { std::sort(A_.begin(), A_.end()); return std::count_if(B_.cbegin(), B_.cend(), [&](int element) { return std::binary_search(A_.cbegin(), A_.cend(), element); }); }
Just for a giggle, here's a <algorithm> -developed version of your algorithm:
int vec_intersect(const std::vector<int>& A_, const std::vector<int>& B_) { return std::count_if(B_.cbegin(), B_.cend(), [&](int element) { return std::find(A_.cbegin(), A_.cend(), element) != A_.cend(); }); }
Billy oneal
source share