Tất cả những gì tôi muốn làm là kiểm tra xem một phần tử có tồn tại trong vectơ hay không, vì vậy tôi có thể xử lý từng trường hợp.
if ( item_present )
do_this();
else
do_that();
Tất cả những gì tôi muốn làm là kiểm tra xem một phần tử có tồn tại trong vectơ hay không, vì vậy tôi có thể xử lý từng trường hợp.
if ( item_present )
do_this();
else
do_that();
Câu trả lời:
Bạn có thể sử dụng std::find
từ <algorithm>
:
#include <vector>
vector<int> vec;
//can have other data types instead of int but must same datatype as item
std::find(vec.begin(), vec.end(), item) != vec.end()
Điều này trả về một bool ( true
nếu có, false
nếu không). Với ví dụ của bạn:
#include <algorithm>
#include <vector>
if ( std::find(vec.begin(), vec.end(), item) != vec.end() )
do_this();
else
do_that();
#include <algorithm>
hoặc nếu không bạn có thể gặp các lỗi rất lạ như 'không thể tìm thấy chức năng khớp trong không gian tên std'
.find()
vẫn không phải là một chức năng thành viên std::vector
, như bạn mong đợi? Tôi tự hỏi nếu đây là một hậu quả của templating.
std::vector<>::find()
sẽ không cung cấp bất kỳ lợi thế nào, cũng không cần thiết, do đó, không, nó không nên là một thành viên. Xem thêm en.wikipedia.org/wiki/Coupling_%28computer_programming%29
mvec.find(key) != mvec.cend()
thích hợp hơn std::find(mvec.cbegin(), mvec.cend(), key) != mvec.cend()
.
Như những người khác đã nói, sử dụng STL find
hoặc các find_if
chức năng. Nhưng nếu bạn đang tìm kiếm theo vectơ rất lớn và hiệu suất tác động này, bạn có thể muốn sắp xếp vector của bạn và sau đó sử dụng binary_search
, lower_bound
hoặc upper_bound
các thuật toán.
Sử dụng find từ tiêu đề thuật toán của stl. Tôi đã minh họa việc sử dụng nó với kiểu int. Bạn có thể sử dụng bất kỳ loại nào bạn thích miễn là bạn có thể so sánh về sự bình đẳng (quá tải == nếu bạn cần cho lớp tùy chỉnh của mình).
#include <algorithm>
#include <vector>
using namespace std;
int main()
{
typedef vector<int> IntContainer;
typedef IntContainer::iterator IntIterator;
IntContainer vw;
//...
// find 5
IntIterator i = find(vw.begin(), vw.end(), 5);
if (i != vw.end()) {
// found it
} else {
// doesn't exist
}
return 0;
}
Nếu vectơ của bạn không được đặt hàng, hãy sử dụng phương pháp MSN đề xuất:
if(std::find(vector.begin(), vector.end(), item)!=vector.end()){
// Found the item
}
Nếu vector của bạn được đặt hàng, hãy sử dụng phương thức binary_search Brian Neal đề xuất:
if(binary_search(vector.begin(), vector.end(), item)){
// Found the item
}
tìm kiếm nhị phân mang lại hiệu suất trong trường hợp xấu nhất O (log n), hiệu quả hơn so với cách tiếp cận đầu tiên. Để sử dụng tìm kiếm nhị phân, bạn có thể sử dụng qsort để sắp xếp vectơ trước để đảm bảo nó được đặt hàng.
std::sort
sao? qsort
rất không hiệu quả trên các vectơ .... xem: stackoverflow.com/questions/12308243/ Kẻ
Tôi sử dụng một cái gì đó như thế này ...
#include <algorithm>
template <typename T>
const bool Contains( std::vector<T>& Vec, const T& Element )
{
if (std::find(Vec.begin(), Vec.end(), Element) != Vec.end())
return true;
return false;
}
if (Contains(vector,item))
blah
else
blah
... theo cách đó nó thực sự rõ ràng và dễ đọc. (Rõ ràng bạn có thể sử dụng lại mẫu ở nhiều nơi).
value_type
từ vùng chứa cho loại phần tử. Tôi đã thêm một câu trả lời như thế này.
Trong C ++ 11 bạn có thể sử dụng any_of
. Ví dụ: nếu là vector<string> v;
thì:
if (any_of(v.begin(), v.end(), bind(equal_to<string>(), _1, item)))
do_this();
else
do_that();
Ngoài ra, sử dụng lambda:
if (any_of(v.begin(), v.end(), [&](const std::string& elem) { return elem == item; }))
do_this();
else
do_that();
bind1st
và khôngbind2nd
được dùng nữa kể từ C ++ 11 và bị loại bỏ hoàn toàn trong C ++ 17. Sử dụng bind
với placeholders
và / hoặc lambdas thay thế.
Đây là một chức năng sẽ hoạt động cho bất kỳ Container nào:
template <class Container>
const bool contains(const Container& container, const typename Container::value_type& element)
{
return std::find(container.begin(), container.end(), element) != container.end();
}
Lưu ý rằng bạn có thể thoát khỏi 1 tham số mẫu vì bạn có thể trích xuất value_type
từ Container. Bạn cần typename
bởi vì Container::value_type
là một tên phụ thuộc .
Hãy nhớ rằng, nếu bạn sẽ thực hiện nhiều tra cứu, có những thùng chứa STL tốt hơn cho việc đó. Tôi không biết ứng dụng của bạn là gì, nhưng các thùng chứa liên kết như std :: map có thể đáng xem xét.
std :: vector là nơi chứa sự lựa chọn trừ khi bạn có lý do cho việc khác và việc tra cứu theo giá trị có thể là một lý do như vậy.
Sử dụng tìm STL chức năng .
Hãy nhớ rằng cũng có một hàm find_if , bạn có thể sử dụng nếu tìm kiếm của bạn phức tạp hơn, tức là nếu bạn không chỉ tìm kiếm một phần tử, nhưng, ví dụ, muốn xem liệu có một phần tử nào đó đáp ứng một số phần nhất định không điều kiện, ví dụ, một chuỗi bắt đầu bằng "abc". ( find_if
sẽ cung cấp cho bạn một trình vòng lặp trỏ đến phần tử đầu tiên như vậy).
Với boost bạn có thể sử dụng any_of_equal
:
#include <boost/algorithm/cxx11/any_of.hpp>
bool item_present = boost::algorithm::any_of_equal(vector, element);
Bạn có thể thử mã này:
#include <algorithm>
#include <vector>
// You can use class, struct or primitive data type for Item
struct Item {
//Some fields
};
typedef std::vector<Item> ItemVector;
typedef ItemVector::iterator ItemIterator;
//...
ItemVector vtItem;
//... (init data for vtItem)
Item itemToFind;
//...
ItemIterator itemItr;
itemItr = std::find(vtItem.begin(), vtItem.end(), itemToFind);
if (itemItr != vtItem.end()) {
// Item found
// doThis()
}
else {
// Item not found
// doThat()
}
Bạn có thể sử dụng find
hàm, được tìm thấy trong std
không gian tên, nghĩa là std::find
. Bạn truyền std::find
hàm begin
và end
iterator từ vectơ bạn muốn tìm kiếm, cùng với phần tử bạn đang tìm và so sánh iterator kết quả với phần cuối của vectơ để xem chúng có khớp hay không.
std::find(vector.begin(), vector.end(), item) != vector.end()
Bạn cũng có thể hủy bỏ trình lặp đó và sử dụng nó như bình thường, giống như bất kỳ trình vòng lặp nào khác.
Bạn có thể sử dụng đếm quá. Nó sẽ trả về số lượng vật phẩm có trong một vectơ.
int t=count(vec.begin(),vec.end(),item);
find
nhanh hơn count
, bởi vì nó không tiếp tục đếm sau trận đấu đầu tiên.
Nếu bạn muốn tìm một chuỗi trong một vectơ:
struct isEqual
{
isEqual(const std::string& s): m_s(s)
{}
bool operator()(OIDV* l)
{
return l->oid == m_s;
}
std::string m_s;
};
struct OIDV
{
string oid;
//else
};
VecOidv::iterator itFind=find_if(vecOidv.begin(),vecOidv.end(),isEqual(szTmp));
Một mẫu khác sử dụng toán tử C ++.
#include <vector>
#include <algorithm>
#include <stdexcept>
template<typename T>
inline static bool operator ==(const std::vector<T>& v, const T& elem)
{
return (std::find(v.begin(), v.end(), elem) != v.end());
}
template<typename T>
inline static bool operator !=(const std::vector<T>& v, const T& elem)
{
return (std::find(v.begin(), v.end(), elem) == v.end());
}
enum CODEC_ID {
CODEC_ID_AAC,
CODEC_ID_AC3,
CODEC_ID_H262,
CODEC_ID_H263,
CODEC_ID_H264,
CODEC_ID_H265,
CODEC_ID_MAX
};
void main()
{
CODEC_ID codec = CODEC_ID_H264;
std::vector<CODEC_ID> codec_list;
codec_list.reserve(CODEC_ID_MAX);
codec_list.push_back(CODEC_ID_AAC);
codec_list.push_back(CODEC_ID_AC3);
codec_list.push_back(CODEC_ID_H262);
codec_list.push_back(CODEC_ID_H263);
codec_list.push_back(CODEC_ID_H264);
codec_list.push_back(CODEC_ID_H265);
if (codec_list != codec)
{
throw std::runtime_error("codec not found!");
}
if (codec_list == codec)
{
throw std::logic_error("codec has been found!");
}
}
template <typename T> bool IsInVector(T what, std::vector<T> * vec)
{
if(std::find(vec->begin(),vec->end(),what)!=vec->end())
return true;
return false;
}
(C ++ 17 trở lên):
có thể sử dụng std::search
cũng
Điều này cũng hữu ích cho việc tìm kiếm chuỗi các yếu tố.
#include <algorithm>
#include <iostream>
#include <vector>
template <typename Container>
bool search_vector(const Container& vec, const Container& searchvec)
{
return std::search(vec.begin(), vec.end(), searchvec.begin(), searchvec.end()) != vec.end();
}
int main()
{
std::vector<int> v = {2,4,6,8};
//THIS WORKS. SEARCHING ONLY ONE ELEMENT.
std::vector<int> searchVector1 = {2};
if(search_vector(v,searchVector1))
std::cout<<"searchVector1 found"<<std::endl;
else
std::cout<<"searchVector1 not found"<<std::endl;
//THIS WORKS, AS THE ELEMENTS ARE SEQUENTIAL.
std::vector<int> searchVector2 = {6,8};
if(search_vector(v,searchVector2))
std::cout<<"searchVector2 found"<<std::endl;
else
std::cout<<"searchVector2 not found"<<std::endl;
//THIS WILL NOT WORK, AS THE ELEMENTS ARE NOT SEQUENTIAL.
std::vector<int> searchVector3 = {8,6};
if(search_vector(v,searchVector3))
std::cout<<"searchVector3 found"<<std::endl;
else
std::cout<<"searchVector3 not found"<<std::endl;
}
Ngoài ra có sự linh hoạt của việc vượt qua một số thuật toán tìm kiếm. Tham khảo tại đây.
Cá nhân tôi đã sử dụng các mẫu trễ để xử lý nhiều loại container cùng một lúc thay vì chỉ xử lý các vectơ. Tôi đã tìm thấy một ví dụ tương tự trực tuyến (không thể nhớ ở đâu) vì vậy tín dụng dành cho bất cứ ai tôi đã lấy từ này. Mẫu đặc biệt này dường như cũng xử lý các mảng thô.
template <typename Container, typename T = typename std::decay<decltype(*std::begin(std::declval<Container>()))>::type>
bool contains(Container && c, T v)
{
return std::find(std::begin(c), std::end(c), v) != std::end(c);
}
Sử dụng Newton C ++, nó dễ dàng hơn, tự ghi lại và nhanh hơn so với std :: find vì trả về một bool trực tiếp.
bool exists_linear( INPUT_ITERATOR first, INPUT_ITERATOR last, const T& value )
bool exists_binary( INPUT_ITERATOR first, INPUT_ITERATOR last, const T& value )
Tôi nghĩ rõ ràng những gì các chức năng làm.
include <newton/algorithm/algorithm.hpp>
if ( newton::exists_linear(first, last, value) )
do_this();
else
do_that();