当前位置: 首页 > news >正文

【C++】search、search_n和find、find_if

目录

search和search_n 

find和find_if

1、find

2、find_if


search和search_n 

#include <iostream>
#include <algorithm>
#include <array>
#include <vector>
#include <functional>

using namespace std;

int main(){
	
	array<int,8> test = {3,5,7,7,11,6,17,19};
	array<int,2> t2 = {11,13};

	array<int,8>::iterator it;

	//找到t2中元素在test中第一次出现的位置,不像find函数只能找一个
	it=search(test.begin(),test.end(),t2.begin(),t2.end());

	//寻找首次连续出现2次7的位置
	it=search_n(test.begin(),test.end(),2,7);

	//寻找首次连续出现2次大于7的位置
	it=search_n(test.begin(),test.end(),2,7,[](int i,int j){return i>j;});

	if(it!=test.end())cout<<it-test.begin();
	

	return 0;
}

原文:https://www.xuebuyuan.com/2019216.html

find和find_if

      回顾学习find和find_if, 网上查了一下资料,这里记录一下。

 需 #include <algorithm>

1、find

using namespace std;
int main()
{
    list<int> lst;
    lst.push_back(10);
    lst.push_back(20);
    lst.push_back(30);
    list<int>::iterator it = find(lst.begin(), lst.end(), 10); // 查找list中是否有元素“10”
    if (it != lst.end()) // 找到了
    {
        // do something 
    }
    else // 没找到
    {
        // do something
    }
    return 0;
}

那么,如果容器里的元素是一个类呢?要查找类,那么就需要重载==,拥有给find调用判断类是否相等

例如,有list<CPerson> ,其中CPerson类定义如下:

class CPerson
{
public:
    CPerson(void); 
    ~CPerson(void);

    bool CPerson::operator==(const CPerson &rhs) const
    {
        return (age == rhs.age);
    }
public:
    int age; // 年龄
};

    用find()函数进行查找,我们需要提供一个判断两个CPerson对象“相等”的定义,这个“相等”的定义,是通过重载“==”操作符实现的,我们在CPerson类中添加一个方法,定义为:

bool operator==(const CPerson &rhs) const;
      实现为:
bool CPerson::operator==(const CPerson &rhs) const
{
    return (age == rhs.age);
}

然后我们就可以这样查找(假设list中已经有了若干CPerson对象)了:

list<CPerson> lst;
// 向lst中添加元素,此处省略

CPerson cp_to_find; // 要查找的对象
cp_to_find.age = 50;
list<CPerson>::iterator it = find(list.begin(), list.end(), cp_to_find); // 查找

if (it != lst.end()) // 找到了
{
}
else // 没找到
{
}
这样就实现了需求。

2、find_if

若要找出 满足自己自定义的某些条件的 对象 则需要find_if 函数。

例如,有一个list<CPerson*>,这个list中的每一个元素都是一个对象的指针,我们要在这个list中查找具有指定age的元素,找到的话就得到对象的指针。
      这时候,你不再能像上面的例子那样做,我们需要用到find_if函数,并自己指定predicate function(即find_if函数的第三个参数,比较函数)。先看看find_if函数的定义:

template<class InputIterator, class Predicate>
InputIterator find_if(InputIterator _First, InputIterator _Last, Predicate _Pred);

Parameters
_First
An input iterator addressing the position of the first element in the range to be searched.
_Last
    An input iterator addressing the position one past the final element in the range to be searched.
_Pred
    User-defined predicate function object that defines the condition to be satisfied by the element being searched for. A predicate takes single argument and returns true or false.


我们在CPerson类外部定义这样一个结构体:

typedef struct finder_t
{
    finder_t(int n) : age(n) 
    { 
    } 
    bool operator()(CPerson *p)  //仿函数
    { 
        return (age == p->age); 
    } 
    int age;
}finder_t;

然后就可以利用find_if函数来查找了:

找年纪等于指定年龄的对象:

list<CPerson*> lst;
// 向lst中添加元素,此处省略

list<CPerson*>::iterator it = find_if(lst.begin(), lst.end(), finder_t(50)); // 查找年龄为50的人
if (it != lst.end()) // 找到了
{
    cout << "Found person with age : " << (*it)->age;
}
else // 没找到
{
    // do something
}

2.1、例子1

找key==0的对象:

map<int, char*> mapItems;
auto it = find_if(mapItems.begin(), mapItems.end(),
 [&](const pair<int, char*> &item) {return item->first == 0/*期望值*/;});


2.2、例子2

找 .a > 2 && .b < 8 的对象

typedef struct testStruct
{
    int a;
    int b;
}testStruct;

vector<testStruct> testStructVector;
auto itrFind = find_if(testStructVector.begin(), testStructVector.end(), [](testStruct myStruct)
{
     return myStruct.a > 2 && myStruct.b < 8;
});
 
if(itrFind != testStructVector.end())
        TRACE("found!");
else
        TRACE("not found!");

2.3、例子3

#include <string>
#include <algorithm>
class map_value_finder
{
public:
    map_value_finder(const std::string &cmp_string):m_s_cmp_string(cmp_string){}
    bool operator ()(const std::map<int, std::string>::value_type &pair)
    {
        return pair.second == m_s_cmp_string;
    }
private:
    const std::string &m_s_cmp_string;                    
};
 
int main()
{
    std::map<int, std::string> my_map;
    my_map.insert(std::make_pair(10, "china"));
    my_map.insert(std::make_pair(20, "usa"));
    my_map.insert(std::make_pair(30, "english"));
    my_map.insert(std::make_pair(40, "hongkong"));    
    
    std::map<int, std::string>::iterator it = my_map.end();
    it = std::find_if(my_map.begin(), my_map.end(), map_value_finder("English"));
    if (it == my_map.end())
       printf("not found\n");       
    else
       printf("found key:%d value:%s\n", it->first, it->second.c_str());
       
    return 0;        
}

2.4、例子4

struct map_value_finder  
{  
public:  
    map_value_finder(const std::string &cmp_string):m_s_cmp_string(cmp_string){}  
    bool operator ()(const std::map<int, std::string>::value_type &pair)  
    {  
        return pair.second == m_s_cmp_string;  
    }  
private:  
    const std::string &m_s_cmp_string;                      
};  


 bool funddd(const std::map<int, std::string>::value_type &pair)  
{  
    return pair.second == "english";  
} 
  
int main()  
{  
    std::map<int, std::string> my_map;  
    my_map.insert(std::make_pair(10, "china"));  
    my_map.insert(std::make_pair(20, "usa"));  
    my_map.insert(std::make_pair(30, "english"));  
    my_map.insert(std::make_pair(40, "hongkong"));      
      
    std::map<int, std::string>::iterator it = my_map.end();  
    it = std::find_if(my_map.begin(), my_map.end(), funddd);  
    if (it == my_map.end())  
       printf("not found\n");         
    else  
       printf("found key:%d value:%s\n", it->first, it->second.c_str());  

    getchar();  
    return 0;          
}

下面再说绑定器bind:
      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泛型算法,在性能和代码复杂度上面都有一定得权衡,至于在实际应用中,还是需要具体问题具体分析的。

以下泛型模板
现在还是迷糊的,下面是自己在项目中看到的师傅写的一个比较实用的方法:

template<typename T> bool compare_no(const T* s1 , const T* s2)
{  
    return strcmp(s1->no, s2->no) == 0;
}

template<typename T> bool less_no(const T* s1 , const T* s2)
{
    return strcmp(s1->no, s2->no) < 0;
}

template<typename T> bool compare_id(const T* s1 , const T* s2)
{
    return s1->id == s2->id;
}

template<typename T> bool less_id(const T* s1 , const T* s2)
{
    return s1->id < s2->id;
}

//排序
std::sort(vct_device.begin(), vct_device.end(), less_id<ST_DEVICE>);
std::sort(vct_camer.begin(), vct_camer.end(), less_no<ST_CAMERA>);

//通过编号查找ID

vector<ST_CAMERA*>::iterator it_cam;
ST_CAMERA tmp_cam;
strcpy(tmp_cam.no, "888888");
it_cam = std::find_if(vct_camer.begin(),vct_camer.end(),bind2nd(ptr_fun(compare_no<ST_CAMERA>), &tmp_cam));
if (it_cam != vct_camer.end())
     返回值channel = (*it_cam)->channel;

//通过ID查找编号

vector<ST_CAMERA*>::iterator it_cam;
ST_CAMERA tmp_cam;
int camid = 0;
tmp_cam.id = 3;
it_cam = std::find_if(vct_camer_secd.begin(), vct_camer_secd.end(), bind2nd(ptr_fun(compare_id<ST_CAMERA>), &tmp_cam));
if (it_cam == vct_camer_secd.end())
       返回值strcpy(camera,(*it_cam)->no);

https://blog.csdn.net/bobodem/article/details/49386131
————————————————
版权声明:本文为CSDN博主「zzhongcy」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/zzhongcy/article/details/87709685

相关文章:

  • 【C++】迭代器iterator研究(input iterator、output iterator等)----编辑中
  • 【WebRTC】WebRTC介绍及简单应用
  • 【高并发】高并发测试笔记
  • 【SSL】HTTPS 和 SSL证书原理
  • 【mySQL】WAL和MVCC ----待消化
  • 【GDB】GDB 调试多线程和多进程总结
  • 【C++】C++的类|C++类的内存结构
  • 【算法】详解二分查找算法(思路很简单,细节是魔鬼)
  • 【数据结构】linux 内核的list
  • 【linux】信号量与PV操作 (进程和线程的同步)
  • 【内存池】C++ 内存池
  • 【内存池】C++内存池的简单原理及实现
  • 【mmap】深度分析mmap:是什么 为什么 怎么用 性能总结
  • 【VS】VisualStudio 如何使用UML呢?
  • 【协程】linux进程-线程-协程上下文环境的切换与实现---未消化
  • 《微软的软件测试之道》成书始末、出版宣告、补充致谢名单及相关信息
  • C# 免费离线人脸识别 2.0 Demo
  • co模块的前端实现
  • HTTP请求重发
  • JavaScript类型识别
  • Objective-C 中关联引用的概念
  • python学习笔记 - ThreadLocal
  • 机器学习 vs. 深度学习
  • 离散点最小(凸)包围边界查找
  • 排序算法之--选择排序
  • 设计模式(12)迭代器模式(讲解+应用)
  • 深入浅出Node.js
  • 一个JAVA程序员成长之路分享
  • 原生 js 实现移动端 Touch 滑动反弹
  • 这几个编码小技巧将令你 PHP 代码更加简洁
  • 回归生活:清理微信公众号
  • 教程:使用iPhone相机和openCV来完成3D重建(第一部分) ...
  • ​如何使用ArcGIS Pro制作渐变河流效果
  • #### go map 底层结构 ####
  • (1)(1.9) MSP (version 4.2)
  • (13)[Xamarin.Android] 不同分辨率下的图片使用概论
  • (52)只出现一次的数字III
  • (delphi11最新学习资料) Object Pascal 学习笔记---第8章第2节(共同的基类)
  • (function(){})()的分步解析
  • (vue)el-checkbox 实现展示区分 label 和 value(展示值与选中获取值需不同)
  • (附源码)计算机毕业设计SSM基于健身房管理系统
  • (续)使用Django搭建一个完整的项目(Centos7+Nginx)
  • (转载)CentOS查看系统信息|CentOS查看命令
  • .sh
  • @Autowired @Resource @Qualifier的区别
  • @javax.ws.rs Webservice注解
  • @ModelAttribute使用详解
  • @RequestBody与@ModelAttribute
  • @RequestParam @RequestBody @PathVariable 等参数绑定注解详解
  • [ C++ ] STL priority_queue(优先级队列)使用及其底层模拟实现,容器适配器,deque(双端队列)原理了解
  • [ C++ ] STL---string类的使用指南
  • [ CTF ]【天格】战队WriteUp- 2022年第三届“网鼎杯”网络安全大赛(青龙组)
  • [ 蓝桥杯Web真题 ]-布局切换
  • [20190416]完善shared latch测试脚本2.txt
  • [Android]竖直滑动选择器WheelView的实现