首页 > 其他分享 >用find_if查找vector内对象的成员

用find_if查找vector内对象的成员

时间:2023-04-10 15:04:09浏览次数:37  
标签:vector return 函数 绑定 查找 str find


用stl的find方法查找一个包含简单类型的vector中的元素是很简单的,例如

vector<string> strVec;  find(strVec.begin(),strVec.end(),”aa”);

假如vector包含一个复合类型的对象呢比如

class A
{
public:
A(const std::string str,int id)
{
this->str=str;
this->id=id;
}
private:
std::string str;
int id;
};

这个时候一般的想法是写个函数遍历这个vector,然后进行比较查找。实际上在使用STL的时候,不建议使用循环遍历的查找方法,有几个理由(参加《effictive c++》46条):

  • 效率:泛型算法通常比循环高效。
  • 正确性: 写循环时比调用泛型算法更容易产生错误。
  • 可维护性: 与相应的显式循环相比,泛型算法通常使代码更干净、更直观。

实际上通过find_if泛型算法可以很优雅的达到期望的效果。template<class InputIterator, class Predicate> InputIterator find_if( InputIterator _First, InputIterator _Last, Predicate_Pred );这里的最后一个参数可是一个一元谓词,即只带一个参数且返回值限定为bool的函数对象,例如

bool compare(A& dValue)
{
if(dValue.GetStr().compare(“bb”)==0)
return true;
else
return false;
}


示例:

vector<A> a;
A b(“aa”,4);
A c(“bb”,6);
A d(“zz”,7);
a.push_back(b);
a.push_back(c);
a.push_back(d);
vector<A>::iterator t=find_if(a.begin(),a.end(),compare);



以上函数限定了比较的内容,如果我们想要灵活的自定义比较条件的话要如何做呢,有2个办法,一个是自定义类
,并重载()操作符号,例如:

class findx
{
public:
findx(const string str)
{
class D
{};
test=str;
}
string GetTest()
{
return test;
}
bool operator()(A& dValue)
{
if(dValue.GetStr().compare(test)==0)
return true;
else
return false;
}
private:
string test;
};

比较的时候只要

vector<A>::iterator t=find_if(a.begin(),a.end(),findx(“33″));

还有一种方法是使用仿函数和绑定器。仿函数就是类似上面的重载了操作符()的自定义类,或者用struct也可以。因为他定义了操作符“()”,所以能够像函数调用一样在对象名后加上“()”,并传入对应的参数,从而执行相应的功能。这样的类型就是函数对象,从而能作为函数参数传递给find_if。

下面再说绑定器:STL中的绑定器有类绑定器和函数绑定器两种,类绑定器有binder1st和binder2nd,而函数绑定器是bind1st和bind2nd,他们的基本目的都是用于构造一个一元的函数对象。比如这里我们可以利用bind2nd通过绑定二元函数对象中的第二个参数的方式来实现二元谓词向一元谓词的转换。

struct compare: binary_function<A, string,bool>
{
bool operator()( A &value, string str) const
{
if (value.GetStr()== str)
return true;
else
return false;
}
};

示例:
 
vector<A>::iterator t=find_if(a.begin(),a.end(),bind2nd(compare(),”33″));



无论是用vector的循环还是find_if泛型算法,在性能和代码复杂度上面都有一定得权衡,至于在实际应用中,还是需要具体问题具体分析的


标签:vector,return,函数,绑定,查找,str,find
From: https://blog.51cto.com/u_130277/6180909

相关文章

  • mysql - 在 MySQL 空间数据库中查找相交区域
    在MySQL数据库中,如何找到完全或部分落在距另一点一定距离内的圆形区域?有很多例子可以找到某个半径内的点,但没有找到与该半径相交的圆形区域。我有一份为某些区域(点和半径)提供服务的承包商列表。客户需要能够根据与他们的距离找到这些承包商。最佳答案我认为您正在寻找......
  • LeetCode习题——x 的平方根(二分查找)
    ###x的平方根力扣链接:[x的平方根](https://leetcode.cn/problems/sqrtx/)####题目>给你一个非负整数x,计算并返回x的算术平方根。>>由于返回类型是整数,结果只保留整数部分,小数部分将被舍去。>>注意:不允许使用任何内置指数函数和算符,例如pow(x,0.5)或者x*......
  • 二分查找
    #include<iostream>usingnamespacestd;intbinaryFind(int*arr,intlen,inttarget){intleft=0;intright=len;#不要用sizeof(arr)/sizeof(arr[0])求数组长度,这样相当于求一个指针所占字节数8/4=2,引入参数lenwhile(left<=right){......
  • 18.LUT查找表
    前面介绍的阈值比较方法中只有一个阈值,如果需要与多个阈值进行比较,就需要用到显示查找表(Look-Up-Table,LUT)。LUT查找表简单来说就是一个像素灰度值的映射表,它以像素灰度值作为索引,以灰度值映射后的数值作为表中的内容。例如我们有一个长度为5的存放字符的数组,LUT查找表就是通过......
  • cnpm安装appium出现cannot find module xxx
    背景,我的电脑MacBookproM1芯片,brew安装了npm,再通过npm安装了cnpm,但是通过cnpm安装appium时候总会出现cannotfindmodulexxx,然后又对xxx再cnpm安装,再安装appium又出现新的xxx,网上找了很多方法,都没有对症下药的办法,最后像一个法子,直接干脆通过npm指定阿里镜......
  • vector类的学习和实现4月8日
    vector类不同于string类.他其中的成员变量都为重定义自定义类型指针为迭代器,用指针的位置来代表容量,当前容器大小构造函数:将所有指针都置为空,析构函数:释放空间并将所有成员指针置为空.拷贝构造和重载=运算符:拷贝构造可以开空间并依次尾插被拷贝类的各个数值来达到构造的......
  • 如何将 find 命令与 exec 一起使用
    Linux中的find命令是根据给定条件查找文件和目录的出色工具。通过实际对找到的文件执行特定操作,您可以将您的发现提升到一个新的水平。例如,您找到了所有扩展名为.jpeg的文件。用.jpg扩展名重命名它们怎么样?您不能只是通过管道将find命令输出重定向到另一个命令。它不会......
  • LeetCode习题——在排序数组中查找元素的第一个和最后一个位置(二分查找)
    在排序数组中查找元素的第一个和最后一个位置力扣链接:在排序数组中查找元素的第一个和最后一个位置题目给你一个按照非递减顺序排列的整数数组nums,和一个目标值target。请你找出给定目标值在数组中的开始位置和结束位置。如果数组中不存在目标值target,返回[-1,-1]。你......
  • C++竞赛常用函数库stl快捷查询手册(vector,map,set,queue,string等)
    1.控制输出流<iomanip>;cout<<setprecision(<span="">int);保留int位有效数字cout<<setprecision(<span="">int)<<fixed;保留int位有效小数为不足4位数的数填充0(如1填充变成0001),cout<<setfill('0')<<setw(4)(一次性效果)......
  • 第三库FindXXX.cmake
    1、CURLinclude(../cmake/ExternalProjectHelper)if(${CMAKE_BUILD_TYPE}STREQUAL"Debug") find_external_project_add(NAMEcurl DEPENDS"openssl" CONFIGURE_COMMANDS-DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}-DCMAKE_BUILD_TYPE......