ChatGPT解决这个技术问题 Extra ChatGPT

check if a std::vector contains a certain object? [duplicate]

This question already has answers here: How to find out if an item is present in a std::vector? (18 answers) Closed 2 years ago.

Is there something in <algorithm> which allows you to check if a std:: container contains something? Or, a way to make one, for example:

if(a.x == b.x && a.y == b.y)
return true;

return false;

Can this only be done with std::map since it uses keys?

Thanks

If it contains something specific, or just of it's not empty?
Which C++ reference are you using? And the header is called <algorithm> - note no .h.
Something specific such as a custom struct.
if the container contains a custom struct, then you'll need to implement operator== to compare them; then std::find will work.
Like answered in the duplicate, I think the most elegant is to use boost::algorithm::any_of_equal.

E
E-rich

Checking if v contains the element x:

#include <algorithm>

if(std::find(v.begin(), v.end(), x) != v.end()) {
    /* v contains x */
} else {
    /* v does not contain x */
}

Checking if v contains elements (is non-empty):

if(!v.empty()){
    /* v is non-empty */
} else {
    /* v is empty */
}

what if x is the last element in v?
David, end() points to one past the last element, so it all works out.
Does this account for numerical tolerance when trying to determine if a double is in the vector?
@NicholasHamilton: No, it uses operator==. If you need to account for numerical tolerance, use std::find_if and supply a suitable predicate.
@DarnocEloc: No.
B
Bertrand Martel

If searching for an element is important, I'd recommend std::set instead of std::vector. Using this:

std::find(vec.begin(), vec.end(), x) runs in O(n) time, but std::set has its own find() member (ie. myset.find(x)) which runs in O(log n) time - that's much more efficient with large numbers of elements

std::set also guarantees all the added elements are unique, which saves you from having to do anything like if not contained then push_back()....


Great!!! I'm writing a lexer. Sets will be much better than vectors. Does set have a count method like map? I also want to be able to get the index of the element in a set.
Excellent information! Thank you for both answering the straight question and providing an additional solution.
This is bad advice. If performance is important, profile. There is no guarantee whatsoever that complexity analysis has anything to say about your specific problem.
It depends on the number of elements. std::set's lookup characteristics work great for conainers with high number of elements at the cost of data locality. You must perform performance analysis (eg. profiling) to decide how high is high enough to switch from a vector data structure to a set data structure.
@Segmentation The O(n) notation is not about worst cases. AFAIK, set doesn't work like a vector at all. Most set implementations use red-black trees, which have a significant overhead. I don't know what you mean by a header adding overhead. Overhead usually refers to runtime overhead. The best use cases of set are "I'm feeling lazy and don't want to think about it," and "I need to get this done quickly." If you care about performance, you need to profile. unordered_set might be worth trying.
C
Community

See question: How to find an item in a std::vector?

You'll also need to ensure you've implemented a suitable operator==() for your object, if the default one isn't sufficient for a "deep" equality test.


I normally wouldn't implement a custom operator==() for my class to just be able to use std::find() once or twice. I would only do that if it actually makes sense to add that override to the public interface of your class. Needing to be able to use std::find() doesn't justify that. Furthermore, what if you need to do std::find() twice but need to compare your objects in a different way? Like on a different property?
if you are worried to implement the operator==, then I would recommend using std::find_if, then you could have re-usable predicates for your different criteria cases