1. 程式人生 > >vector中find和find_if的用法

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

相關推薦

vectorfindfind_if用法

今天鬱悶寫大作業中。唉。。每次寫都tm暴力遍歷。有stl你用毛遍歷啊。現在記下來。再遍歷就剁手吧。(- -!) stl包括容器、迭代器和演算法: 容器 用於管理一些相關的資料型別。每種容器都有它的優缺點,不同的容器反映出程式設計的不同需求。容器自身可能由陣列或連結串列實現,或者容器中的每個元素都有特殊

Python學習日記5|BeautifulSoupfindfind_all的用法

Python學習日記5|BeautifulSoup中find和find_all的用法  是藍先生 關注 2016.04.20 11:26* 字數 930 閱讀 37205評論 11喜歡 10 今天是4.20號。 前天晚上看到蔣方舟的一句話: 不要左顧右

odoo系統name_searchname_get用法

打印 per sequence not 添加 product xpath ret 領料單 自動帶出工序和工序序號,兩個條件都能搜索,並且兩個都帶出來顯示在前端: # 輸入工序序號會自動帶出工序名// def name_search(self, cr,user,name=

SQLServerexistsexcept用法

sqlserver sql 一、exists1.1 說明EXISTS(包括 NOT EXISTS)子句的返回值是一個BOOL值。EXISTS內部有一個子查詢語句(SELECT ... FROM...),我將其稱為EXIST的內查詢語句。其內查詢語句返回一個結果集。EXISTS子句根據其內查詢語句的結果

jQueryfindfilter的區別

query spa com 區別 tex 自身 技術 ext inf 這是jQuery裏常用的2個方法。他們兩者功能是完全不同的,而初學者往往會被誤導。 首先 我們看.find()方法:現在有一個頁面,裏面HTML代碼為;程序代碼 <div class="css"&

JAVAthissuper用法

出現 子句 package code rgs lean 眼睛 都是 java對象   參考網上資料和自行理解總結java中this和super中各自用法及其差異   <一>. this的用法   構造方法是創建java對象的重要途徑,通過new關鍵字調用構造器

在 linux find grep 的區別??

col linu 它的 -s glob 操作 功能 相關 round Linux 系統中 grep 命令是一種強大的文本搜索工具,它能使用正則表達式搜索文本,並把匹配的行打印出來。grep 全稱是 Global Regular Expression Print,表示

xshell findxargs一起使用

1、在當前目錄下查詢所有使用者具有讀、寫和執行許可權的檔案,並收回相應的寫許可權: find ./ -perm +777 | xargs chmod 700 2、查詢系統中的每一個普通檔案,然後使用xargs命令來測試他們分別屬於哪類檔案 find -type f | xargs f

oracleadd_monthstrunc用法

  oracle中add_months和trunc用法 2012-06-13 13:45  646人閱讀  評論(0)  收藏  舉報 oracle date sql 工作

SpringMVC@Controller@RequestMapping用法

fff set blank content block 方法 封裝 keyword 屬性 一、簡介 在SpringMVC 中,控制器Controller 負責處理由DispatcherServlet 分發的請求,它把用戶請求的數據經過業務處理層處理之後封裝

javascriptimportexport用法總結.md

import import 和 require 的區別 import 和js的發展歷史息息相關,歷史上 js沒有模組(module)體系,無法將一個大程式拆分成互相依賴的小檔案,再用簡單的方法拼裝起來。這對開發大型工程非常不方便。 在 ES6 之前,社群制定了一些

SpringMVC@Controller@RequestMapping用法其他常用註解

一、簡介          在SpringMVC 中,控制器Controller 負責處理由DispatcherServlet 分發的請求,它把使用者請求的資料經過業務處理層處理之後封裝成一個Model ,然後再把該Model 返回給對應的View 進行展示。在Spring

C++ STL庫 泛型演算法 find find_if

一:find()函式 函式原型: template<class _InIt, class _Ty> _NODISCARD inline _InIt find(_InIt _First, const _InIt _Last, const _Ty& _

SQLINEXISTS用法的區別

結論 1. in()適合B表比A表資料小的情況 2. exists()適合B表比A表資料大的情況 當A表資料與B表資料一樣大時,in與exists效率差不多,可任選一個使用. select * from A where id in(select id fro

Angular2InputOutput用法及示例

                     對於angular2中的Input和Output可以和angularjs中指令作類比。Input相當於指令的值繫結,無論是單向的(@)還是雙向的(=)。都是將父作用域的值“輸入”到子作用域中,然後子作用域進行相關處理。Output相當於指令的方法繫結,子作用域觸發事件

@OneToMany,@ManyToOne @mappedby @joincolumn 用法解釋

/** * 建立了一個實體類。 * * 如何持久化呢? * * 1、使用@Entity進行實體類的持久化操作,當JPA檢測到我們的實體類當中有 * * @Entity 註解的時候,會在資料庫中生成對應的表結構資訊。 * * * 如何指定主鍵以及主鍵的生成策略? *

vectorsize()capacity()取值

vector v;此時沒有初始化,所以size()和capacity()都是0; cout<<v.size()<<endl<<v.capacity()<<endl; v.push_back(1); cout<<v.size()&

TwinCAT3TONR_TRIG用法體會

程式碼在文後 使用兩個定時器實現自動交替定時。TRIGGER_ORIGEN為強制輸入,後面自動迴圈交替定時。 總結: 1.TON用法 例項:TON(IN:= , PT:= , Q=> , ET=> ); IN:上升沿開始計時,要保持高,直到Q輸出,Q未輸

Html A標籤 href onclick用法、區別、優先級別

http://gocom.primeton.com/blog21307_27051.htm 我以前在寫<A>的href和onclick一直很隨意,後來出過幾次問題,以後才開始重視這個問題: 首先摘錄一篇文件: 在Javascript中void是一個操

linuxfind命令的用法

find命令是比較常用的命令,用來在特定目錄下查詢具有某種特徵的檔案。 一:find命令格式如下: find [-path......] -options [-print -exec -ok] path:要查詢的目錄路徑(“~”表示$home目錄;“.”表示當前目錄;“/”