C++中检查vector是否包含给定元素的几种方式详解

所属分类: 软件编程 / C 语言 阅读数: 126
收藏 0 赞 0 分享

概述

在编码中经常会遇到一种场景,就是要在数组或列表中查找某个元素是否存在,其实对于这种线性操作,自己实现一个循环来检查是非常简单的事情,那既然这样,为啥还要专门写篇博客来分享呢?
一个最重要的原因就是我们原本就可以用更简洁直观高效的方式去替代手写for循环,这个方式就是使用C++标准库函数。

再啰嗦几句。
通常在面试的时候,为了考察面试者的编码功底,会让其从头实现某些基础的算法,但是在实际开发中,很多东西都有现成的封装。只有把语言、标准库“双剑合璧”才能算是真正的C++。而且据C++标准委员会的安排,今后C++也会更侧重于扩充库而不是扩充语言,可见其分量的轻重了。

总之,C++标准库是一个非常强大的东东,并且实现这些标准库的人都是些非常牛逼的顶级程序员,性能都是最优的。所以不要总想着所有事情都亲力亲为的去写一遍,既浪费时间,写出来的东西可能还很菜。那么,这里就通过一些简单的示例来演示如何通过标准库函数来实现。

正文

如何检查vector中是否包含给定元素。

std::count

最简单的方式是对vector中的指定元素进行计数,如果count不为零,表示该元素存在,那么std::count可以很容易实现。

#include <iostream>
#include <vector>
#include <algorithm>

int main()
{
	std::vector<int> v = { 1, 20, 2, 6, 3, 7 };
	int key = 6;

	if (std::count(v.begin(), v.end(), key))
		std::cout << "Element found";
	else
		std::cout << "Element not found";

	return 0;
}

std::find

相比第一种方式,std::find()算法能够更快速的查找给定范围内的值,因为std::count()会变量整个容器以获得元素计数,而find()在找到匹配元素后就立即停止搜索。

#include <iostream>
#include <vector>
#include <algorithm>

int main()
{
	std::vector<int> v = { 1, 20, 2, 6, 3, 7 };
	int key = 6;

	if (std::find(v.begin(), v.end(), key) != v.end())
		std::cout << "Element found";
	else
		std::cout << "Element not found";

	return 0;
}

std::find_if

和find相似的还有一个叫 std::find_if()算法,如果查找需要满足某些条件,那么推荐使用该方法。这里我们可以结合lambda来使用,非常简洁。

比如,要查找列表中是否有元素能被5整除

#include <iostream>
#include <vector>
#include <algorithm>

int main()
{
  auto lst = {1,4,9,5,11};
  if(std::find_if(lst.begin(),lst.end(),[](auto v){
    if(v%5 ==0)
      return true;
    else
      return false;
  }) != lst.end()){
    std::cout << "Element found";
  }
  else{
    std::cout << "Element not found";
  }
  return 0;
}

C++ 11 - std::any_of

该算法与std::find_if相似,但不是返回满足条件的的序列中第一个元素的迭代器,而是如果任何元素满足条件后返回true,否则返回false。

#include <iostream>
#include <vector>
#include <algorithm>

struct compare
{
	int key;
	compare(int const &i): key(i) { }

	bool operator()(int const &i)
	{
		return (i == key);
	}
};

int main()
{
	std::vector<int> v = { 4, 7, 5, 2, 6, 9 };
	int key = 6;

	if (std::any_of(v.begin(), v.end(), compare(key)))
		std::cout << "Element found";
	else
		std::cout << "Element not found";

	return 0;
}

或者直接修改find_of的案例:

int main()
{
  auto lst = {1,4,9,5,11};
  if(std::any_of(lst.begin(),lst.end(),[](int v){
    if(v%5 ==0)
      return true;
    else
      return false;
  })){
    std::cout << "Element found";
  }
  else{
    std::cout << "Element not found";
  }
  return 0;
}

C++ 11 - std::none_of

该算法刚好和any_of相反,如果给定的条件在范围内所有元素都返回false,则返回true,如果至少一个元素返回true,则返回false。

直接修改上述示例,将if条件改成“非”就可以了,不再赘述。

std::binary_search

最后一种方法,如果vector是有序的,那么可以考虑使用这种算法,如果在给定范围内找到元素,则返回true,否则返回false。该方式是采用二分法查找,时间复杂度为O(log(n)),速度比较快。

#include <iostream>
#include <vector>
#include <algorithm>

int main()
{
	std::vector<int> v = { 1, 2, 3, 4, 5, 6, 7 };
	int key = 4;

	if (std::binary_search(v.begin(), v.end(), key))
		std::cout << "Element found";
	else
		std::cout << "Element not found";

	return 0;
}

OK,以上所有方法都可以实现我们想要的结果,只是在不同情况下选择一种自己喜欢的方式即可。

附:
C++接口文档:https://en.cppreference.com/w/
C++算法库介绍:https://en.cppreference.com/w/cpp/algorithm

更多精彩内容其他人还在看

用标准c++实现string与各种类型之间的转换

这个类在头文件中定义, < sstream>库定义了三种类:istringstream、ostringstream和stringstream,分别用来进行流的输入、输出和输入输出操作。另外,每个类都有一个对应的宽字符集版本
收藏 0 赞 0 分享

C++如何通过ostringstream实现任意类型转string

再使用整型转string的时候感觉有点棘手,因为itoa不是标准C里面的,而且即便是有itoa,其他类型转string不是很方便。后来去网上找了一下,发现有一个好方法
收藏 0 赞 0 分享

C/C++指针小结

要搞清一个指针需要搞清指针的四方面的内容:指针的类型,指针所指向的类型,指针的值或者叫指针所指向的内存区,还有指针本身所占据的内存区
收藏 0 赞 0 分享

C++ 类的静态成员深入解析

在C++中类的静态成员变量和静态成员函数是个容易出错的地方,本文先通过几个例子来总结静态成员变量和成员函数使用规则,再给出一个实例来加深印象
收藏 0 赞 0 分享

C++类的静态成员初始化详细讲解

通常静态数据成员在类声明中声明,在包含类方法的文件中初始化.初始化时使用作用域操作符来指出静态成员所属的类.但如果静态成员是整型或是枚举型const,则可以在类声明中初始化
收藏 0 赞 0 分享

C++类静态成员与类静态成员函数详解

静态成员不可在类体内进行赋值,因为它是被所有该类的对象所共享的。你在一个对象里给它赋值,其他对象里的该成员也会发生变化。为了避免混乱,所以不可在类体内进行赋值
收藏 0 赞 0 分享

C++中的friend友元函数详细解析

友元可以是一个函数,该函数被称为友元函数;友元也可以是一个类,该类被称为友元类。友元函数的特点是能够访问类中的私有成员的非成员函数。友元函数从语法上看,它与普通函数一样,即在定义上和调用上与普通函数一样
收藏 0 赞 0 分享

static全局变量与普通的全局变量的区别详细解析

以下是对static全局变量与普通的全局变量的区别进行了详细的分析介绍,需要的朋友可以过来参考下,希望对大家有所帮助
收藏 0 赞 0 分享

C++ explicit关键字的应用方法详细讲解

C++ explicit关键字用来修饰类的构造函数,表明该构造函数是显式的,既然有"显式"那么必然就有"隐式",那么什么是显示而什么又是隐式的呢?下面就让我们一起来看看这方面的知识吧
收藏 0 赞 0 分享

教你5分钟轻松搞定内存字节对齐

随便google一下,人家就可以跟你解释的,一大堆的道理,我们没怎么多时间,讨论为何要对齐.直入主题,怎么判断内存对齐规则,sizeof的结果怎么来的,请牢记以下3条原则
收藏 0 赞 0 分享
查看更多