vector中find和find_if的用法

今天郁闷写大作业中。唉。。每次写都tm暴力遍历。有stl你用毛遍历啊。现在记下来。再遍历就剁手吧。(- -!)

stl包括容器、迭代器和算法:

容器 用于管理一些相关的数据类型。每种容器都有它的优缺点,不同的容器反映出程序设计的不同需求。容器自身可能由数组或链表实现,或者容器中的每个元素都有特殊的关键值。

迭代器 用于遍历一个数据集中的每个元素。这些数据集可能是容器或者容器的子集。迭代器的主要优点是它们为任意类型的容器提供一个小巧并且通用(注意通用很重要)的接口。例如,迭代器接口的一个操作是让它依次遍历数据集的每个元素。这个操作是依赖容器的内总部结构独立完成的。迭代器之所以有效是因为容器类提供它自己的迭代器类型来做“正确的事”,容本身的迭代器了解容器的内部结构。

迭代器的接口几乎相当于普通的指针。让一个迭代器递增只需调用++操作符。使用*操作符可以得到迭代器引用的数据值。因而迭代器可以被任为是一种智能指针。

算法 被用于处理数据集中的元素。例如它们可以搜索、排序、修改数据或者其他目的。算法使用迭代器,因此,一个算法只需被编写一次就可以用于任意的容器,因为迭代器的接口对所有类型的容器是通用的。这就是find()的位置

为了给算法更多的扩展性,需要提供一些被算法调用的附属函数。可以使用通用算法去适应非常特别和复杂的需求。你可以提供自己的搜索标准或者特殊的操作去绑定元素。

STL的概念是将数据和操作独立开来。数据由容器类管理,而操作是由可配置的算法定义。迭代器则是这两个元素之间的线索。它允许任何算法和容器的交互。

在某种意义上,STL的概念有勃于面向对象编程的初衷:STL将数据和算法分离而非绑定它们。然而,这样做的理由非常重要:原则上,你可以将任何容器同任何算法绑定,得到的结果是STL是非常可扩展的。

STL的一个标准是它支持任意数据类型。“标准模板库”意味着,所有部分是适应任意类型的模板。STL是通用编程的例子。容器和算法对任意类型和类都是通用的。

STL甚至提供更多的通用组件。使用 适配器 和函数体,你可以为特定需要补充、限制和配置算法和接口。

一个find Vector的例子(BAIDU里找的),注意find不属于vector的成员,而存在于算法中,应加上头文件#include <algorithm>:

#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
int main( )
{
    vector<int> L;
    L.push_back( 1 );
    L.push_back( 2 );
    L.push_back( 3 );
    L.push_back( 4 );
    L.push_back( 5 );
    vector<int>::iterator result = find( L.begin( ), L.end( ), 3 ); //查找3
    if ( result == L.end( ) ) //没找到
        cout << "No" << endl;
    else //找到
        cout << "Yes" << endl;

}

貌似这是个简单版,先mark一下,回头补。

哈哈,正解在此,虽然渣渣从没玩过,不过很好用的样子,妈妈再也不用担心程序效率低了。

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

以下泛型模板,反正我是没看懂,不知道以后会不会用到。

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

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);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/382068.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LeetCode 20. 有效的括号 golang(三)

20. 有效的括号 这个题做了三次&#xff0c;前两次的解法现在觉得是算不得正确的。 看的多写得少 做的多总结少 给定一个只包括 ‘(’&#xff0c;’)’&#xff0c;’{’&#xff0c;’}’&#xff0c;’[’&#xff0c;’]’ 的字符串&#xff0c;判断字符串是否有效。 有效…

引用 Map 数据结构的排序问题

用过map吧&#xff1f;map提供一个很常用的功能&#xff0c;那就是提供key-value的存储和查找功能。例如&#xff0c;我要记录一个人名和相应的存储&#xff0c;而且随时增加&#xff0c;要快速查找和修改&#xff1a; 岳不群&#xff0d;华山派掌门人&#xff0c;人称君子剑 …

LeetCode(合集)括号 golang

LeetCode&#xff08;合集&#xff09;括号 20. 有效的括号 golang&#xff08;三&#xff09; 22. 括号生成 golang 图解

一些oj的返回结果:通过结果找错误,debug。

Waiting&#xff1a;你的程序刚刚提交&#xff0c;正在等待OJ评测你的程序。Compiling&#xff1a;OJ正在编译你的程序。Accepted&#xff1a;OK!你的程序是正确的 ^_^。Wrong Answer&#xff1a;你的程序运行的结果和正确结果不同。状态页面CASE那一览显示的是你的程序在第几个…

LeetCode 128. 最长连续序列 golang

128. 最长连续序列 【困难】 给定一个未排序的整数数组&#xff0c;找出最长连续序列的长度。 要求算法的时间复杂度为 O(n)。 示例: 输入: [100, 4, 200, 1, 3, 2] 输出: 4 解释: 最长连续序列是 [1, 2, 3, 4]。它的长度为 4。 Code // 解题思路 // 将所有nums中元素录入n…

inline内联函数的优缺点

优点&#xff1a;1&#xff09;inline定义的内联函数&#xff0c;函数代码被放入符号表中&#xff0c;在使用时进行替换&#xff08;像宏一样展开&#xff09;&#xff0c;效率很高。2&#xff09;类的内联函数也是函数。编绎器在调用一个内联函数&#xff0c;首先会检查参数问…

LeetCode 88. 合并两个有序数组 golang

88. 合并两个有序数组 给你两个有序整数数组 nums1 和 nums2&#xff0c;请你将 nums2 合并到 nums1 中&#xff0c;使 nums1 成为一个有序数组。 说明: 初始化 nums1 和 nums2 的元素数量分别为 m 和 n 。 你可以假设 nums1 有足够的空间&#xff08;空间大小大于或等于 m …

为什么不能在子类的初始化列表里初始化父类的成员

好几次遇到此类问题了&#xff1a;便不得不找些资料弄明白它&#xff1b;具体代码是&#xff1a;2345678910classA{protected:intn_;};classB:publicA{public:B():n_(0){}};这是简化的&#xff0c;作为分析问题的。然后无情的报错&#xff1a;|error: class B does not have an…

LeetCode (合集)合并链表和数组

LeetCode 88. 合并两个有序数组 golang LeetCode 21. 合并两个有序链表 golang 合并两个有序链表并去重 /*** Definition for singly-linked list.* type ListNode struct {* Val int* Next *ListNode* }*/ func mergeTwoLists(list1 *ListNode, list2 *ListNode) *…

一些好的习惯

无论你是业余的还是专业的程序员&#xff0c;正确的编程风格&#xff0c;不但有助于提升软件产品的功能&#xff0c;还可以明显减少软件灾难的产生。今天&#xff0c;我们就来探讨一下有助于我们获取更佳编程风格的一些最好的规则。代码的可读性至上代码要能可阅读和可理解&…

循环链表的反转

206. 反转链表 func reverseList(head *ListNode) *ListNode {if head nil || head.Next nil {return head}p : reverseList(head.Next)head.Next.Next headhead.Next nilreturn p }循环链表的反转 func reverse(head, key *ListNode) *ListNode {if head.Next key {ret…

英语“作弊”技巧!

和大家分享个更精辟的 无须复习&#xff0c;只要十天英语四级就能过&#xff01;&#xff01;&#xff01;方法让你喷血&#xff01;&#xff01;怕以后找不到!!! 1、听力&#xff0c;有三种题型&#xff0c;dialogue(十个对话)&#xff0c;passage(三个短文)&#xff0c;compo…

程序猿不能错过的十部电影

不同的行业领域中很多时候都分享着共同的思想和理念。比如&#xff0c;大量的计算机编程中涉及到的概念都被运用到了电影里。有些概念出现在电影里后变得如此之酷&#xff0c;甚至反过来能帮助我们程序员更好的理解这些概念。下面就是小编最喜欢的10大电影&#xff0c;它们都在…

Redis运维和开发学习目录

Redis运维和开发学习笔记-全书思维导图 Redis运维和开发学习笔记(1) Redis简介 Redis运维和开发学习笔记(2) redis持久化 Redis运维和开发学习笔记(3)redis搭建集群 Redis运维和开发学习笔记(4) Redis参数意义 Redis运维和开发学习笔记(5) 主从复制和sentinel哨兵模式 Re…

刘汝佳训练指南——数论专题知识点总结:

数论是一个神奇的东西&#xff0c;各种结论都很经典&#xff0c;有些懂&#xff0c;有些自己还不是很懂。接下来就一个一个的介绍吧。第一、素数&#xff0c;素数本身就是一个很让人惊奇的数&#xff0c;因为它代表的是唯一&#xff0c;自己就有连个因数&#xff0c;一个是1&am…

第一次训练赛的相关总结和教训!

没有想到时间会不够用&#xff01;这是来到这里的真实感受&#xff0c;每天不停歇地看电脑&#xff0c;资料&#xff0c;刷题&#xff01;几乎没有停下过&#xff0c;有点喘不过气来&#xff0c;不过身体却有一种莫名的兴奋&#xff01; 不喜欢拖拉的人&#xff0c;可自己又总是…

goland中grpc的安装

go modules https://github.com/goproxy/goproxy.cn/blob/master/README.zh-CN.md go env -w GO111MODULEongo env -w GOPROXYhttps://goproxy.cn,direct安装 gRPC 网络环境允许的同学安装 gRPC 非常方便&#xff0c;直接执行以下命令即可安装完成&#xff1a; go get -u -v…

uva11029 - Leading and Trailing

11029 - Leading and TrailingTime limit: 3.000 seconds http://uva.onlinejudge.org/index.php?optioncom_onlinejudge&Itemid8&category115&pageshow_problem&problem1970Apart from the novice programmers, all others know that you can’t exactly rep…

goland远程调试Docker

开发环境 goland windows10 Docker centos IP:123.57.43.91 操作原理及流程 goland通过tcp/8080(应该选取2375&#xff0c;登录阿里云开启这个端口&#xff0c;这里临时采用)端口与docker-host通信&#xff0c; 发送docker指令&#xff0c;然后让linux执行&#xff0c;通过d…

博客同步测试

该博客通过word发布&#xff01;