当前位置:  开发笔记 > 编程语言 > 正文

如何确定std :: vector中是否存在某个项?

如何解决《如何确定std::vector中是否存在某个项?》经验,为你挑选了11个好方法。

我想做的就是检查一个元素是否存在于向量中,所以我可以处理每个案例.

if ( item_present )
   do_this();
else
   do_that();

MSN.. 873

您可以使用std::find:

#include 
vector vec; 
//can have other data types instead of int but must same datatype as item 
std::find(vec.begin(), vec.end(), item) != vec.end()

这将返回一个bool(true如果存在,false否则).用你的例子:

#include 
#include 

if ( std::find(vec.begin(), vec.end(), item) != vec.end() )
   do_this();
else
   do_that();

我没有看到count()如何比find()更快,因为一旦找到一个元素,find()就会停止,而count()总是要扫描整个序列. (214认同)

不要忘记`#include `否则你可能会得到非常奇怪的错误,例如'找不到命名空间std中的匹配函数' (113认同)

尽管STL是"面向对象的",但是它仍然没有困扰任何人,`.find()`仍然不是`std :: vector`的成员函数,正如你所期望的那样?我想知道这是否是模板的结果. (76认同)

@bobobobo:OOP与成员与非成员无关.并且有一种广泛的思想流派,如果某些东西不必是成员,或者当它作为成员实施时没有给予任何好处,那么它不应该是成员; `std :: vector <> :: find()`不会给任何优势,也不需要它,因此,不,它不应该是成员.另见http://en.wikipedia.org/wiki/Coupling_%28computer_programming%29 (70认同)

@phresnel我认为"当它作为成员实现时没有任何优势"对于这种情况是错误的.优点是简化和清晰的界面.例如:`mvec.find(key)!= mvec.cend()`比`std :: find(mvec.cbegin(),mvec.cend(),key)更好!= mvec.cend()`. (33认同)

有可能.这取决于您搜索空向量的频率. (9认同)

@bobobobo:find()函数不是向量成员的原因是它效率低下.当STL的一个对象有一个成员时,这意味着它是一种有用的,有效的方法; 它表明你应该使用它.由于find()无法有效地为向量实现,因此它不是向量的成员,并且建议如果需要使用find()操作,则使用不同的容器.它与其他评论中提到的STL"设计糟糕"无关. (5认同)

@ArtOfWarfare第三,您可能会发现`end()调用是由编译器内联的,因此根本没有实际的`call`而只是一个原始指针. (4认同)

@ArtOfWarfare由于缓存局部性而排序的`vector`通常比`map`或`set`快得多. (3认同)

@ ap31:这是真的,但当我在制作中使用这样的代码时,人们会对我大喊:( (3认同)


Brian Neal.. 109

正如其他人所说,使用STL findfind_if函数.但是,如果你在非常大的矢量搜索,这会影响性能,您可能要排序的载体,然后使用binary_search,lower_boundupper_bound算法.



1> MSN..:

您可以使用std::find:

#include 
vector vec; 
//can have other data types instead of int but must same datatype as item 
std::find(vec.begin(), vec.end(), item) != vec.end()

这将返回一个bool(true如果存在,false否则).用你的例子:

#include 
#include 

if ( std::find(vec.begin(), vec.end(), item) != vec.end() )
   do_this();
else
   do_that();


我没有看到count()如何比find()更快,因为一旦找到一个元素,find()就会停止,而count()总是要扫描整个序列.
不要忘记`#include `否则你可能会得到非常奇怪的错误,例如'找不到命名空间std中的匹配函数'
尽管STL是"面向对象的",但是它仍然没有困扰任何人,`.find()`仍然不是`std :: vector`的成员函数,正如你所期望的那样?我想知道这是否是模板的结果.
@bobobobo:OOP与成员与非成员无关.并且有一种广泛的思想流派,如果某些东西不必是成员,或者当它作为成员实施时没有给予任何好处,那么它不应该是成员; `std :: vector <> :: find()`不会给任何优势,也不需要它,因此,不,它不应该是成员.另见http://en.wikipedia.org/wiki/Coupling_%28computer_programming%29
@phresnel我认为"当它作为成员实现时没有任何优势"对于这种情况是错误的.优点是简化和清晰的界面.例如:`mvec.find(key)!= mvec.cend()`比`std :: find(mvec.cbegin(),mvec.cend(),key)更好!= mvec.cend()`.
有可能.这取决于您搜索空向量的频率.
@bobobobo:find()函数不是向量成员的原因是它效率低下.当STL的一个对象有一个成员时,这意味着它是一种有用的,有效的方法; 它表明你应该使用它.由于find()无法有效地为向量实现,因此它不是向量的成员,并且建议如果需要使用find()操作,则使用不同的容器.它与其他评论中提到的STL"设计糟糕"无关.
@ArtOfWarfare第三,您可能会发现`end()调用是由编译器内联的,因此根本没有实际的`call`而只是一个原始指针.
@ArtOfWarfare由于缓存局部性而排序的`vector`通常比`map`或`set`快得多.
@ ap31:这是真的,但当我在制作中使用这样的代码时,人们会对我大喊:(

2> Brian Neal..:

正如其他人所说,使用STL findfind_if函数.但是,如果你在非常大的矢量搜索,这会影响性能,您可能要排序的载体,然后使用binary_search,lower_boundupper_bound算法.


排序是O(nlogn),所以只有当你做的不仅仅是O(logn)搜索时,它才有价值.
@liori True it depends on your usage patterns. If you only need to sort it once, then repeatedly do many searches it can save you.
好答案!查找总是o(n).如果与随机访问迭代器一起使用,lower_bound是o(log(n)).

3> m-sharp..:

使用stl的算法头中的find.我已经用int类型说明了它的用法.您可以使用您喜欢的任何类型,只要您可以比较相等(如果您需要自定义类,则重载==).

#include 
#include 

using namespace std;
int main()
{   
    typedef vector 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;
}


根据OP的需要,find_if()也可能是合适的.它允许使用任意谓词而不是相等进行搜索.

4> Bin Feng..:

如果您的矢量未订购,请使用MSN建议的方法:

if(std::find(vector.begin(), vector.end(), item)!=vector.end()){
      // Found the item
}

如果您的矢量是有序的,请使用binary_search方法Brian Neal建议:

if(binary_search(vector.begin(), vector.end(), item)){
     // Found the item
}

二进制搜索产生O(log n)最坏情况性能,这比第一种方法更有效.为了使用二进制搜索,您可以使用qsort首先对向量进行排序以保证它是有序的.


你不是指'std :: sort`吗?`qsort`对矢量效率非常低......参见:http://stackoverflow.com/questions/12308243/trying-to-use-qsort-with-vector

5> Andy Krouwel..:

我用这样的东西......

#include 


template  
const bool Contains( std::vector& 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

......就这样,它实际上清晰可读.(显然你可以在多个地方重用模板).



6> Deqing..:

在C++ 11中,您可以使用any_of.例如,如果它是vector v;那么:

if (any_of(v.begin(), v.end(), bind(equal_to(), _1, item)))
   do_this();
else
   do_that();



7> Martin Broad..:

这是一个适用于任何Container的函数:

template  
const bool contains(const Container& container, const typename Container::value_type& element) 
{
    return std::find(container.begin(), container.end(), element) != container.end();
}

请注意,您可以使用1个模板参数,因为您可以value_type从Container中提取.你需要typename因为Container::value_type是一个从属名称.


请注意,这有时过于宽泛 - 例如,它适用于std :: set,但与find()成员函数相比,性能可怕.我发现最好为搜索速度更快的容器添加专门化(set/map,unordered_*)

8> David Thornl..:

请记住,如果您要进行大量查找,那么有更好的STL容器.我不知道你的应用程序是什么,但像std :: map这样的关联容器可能值得考虑.

std :: vector是选择的容器,除非你有另一个的理由,并且按值查找可能是这样的原因.



9> Frank..:

使用STL 查找功能.

请记住,还有一个find_if函数,如果您的搜索更复杂,可以使用它,例如,如果您不只是查找元素,但是,例如,想要查看是否存在满足某个元素的元素condition,例如,以"abc"开头的字符串.(find_if会给你一个指向第一个这样的元素的迭代器).



10> Mikhail..:

使用boost可以使用any_of_equal:

#include 

bool item_present = boost::algorithm::any_of_equal(vector, element);



11> 小智..:

你可以试试这段代码:

#include 
#include 

// You can use class, struct or primitive data type for Item
struct Item {
    //Some fields
};
typedef std::vector 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()
}

推荐阅读
kikokikolove
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有