vector中find和find_if的用法
今天郁悶寫大作業(yè)中。唉。。每次寫都tm暴力遍歷。有stl你用毛遍歷啊。現(xiàn)在記下來。再遍歷就剁手吧。(- -!)
stl包括容器、迭代器和算法:
容器 用于管理一些相關(guān)的數(shù)據(jù)類型。每種容器都有它的優(yōu)缺點(diǎn),不同的容器反映出程序設(shè)計(jì)的不同需求。容器自身可能由數(shù)組或鏈表實(shí)現(xiàn),或者容器中的每個(gè)元素都有特殊的關(guān)鍵值。
迭代器 用于遍歷一個(gè)數(shù)據(jù)集中的每個(gè)元素。這些數(shù)據(jù)集可能是容器或者容器的子集。迭代器的主要優(yōu)點(diǎn)是它們?yōu)槿我忸愋偷娜萜魈峁┮粋€(gè)小巧并且通用(注意通用很重要)的接口。例如,迭代器接口的一個(gè)操作是讓它依次遍歷數(shù)據(jù)集的每個(gè)元素。這個(gè)操作是依賴容器的內(nèi)總部結(jié)構(gòu)獨(dú)立完成的。迭代器之所以有效是因?yàn)槿萜黝愄峁┧约旱牡黝愋蛠碜觥罢_的事”,容本身的迭代器了解容器的內(nèi)部結(jié)構(gòu)。
迭代器的接口幾乎相當(dāng)于普通的指針。讓一個(gè)迭代器遞增只需調(diào)用++操作符。使用*操作符可以得到迭代器引用的數(shù)據(jù)值。因而迭代器可以被任為是一種智能指針。
算法 被用于處理數(shù)據(jù)集中的元素。例如它們可以搜索、排序、修改數(shù)據(jù)或者其他目的。算法使用迭代器,因此,一個(gè)算法只需被編寫一次就可以用于任意的容器,因?yàn)榈鞯慕涌趯λ蓄愋偷娜萜魇峭ㄓ玫摹_@就是find()的位置
為了給算法更多的擴(kuò)展性,需要提供一些被算法調(diào)用的附屬函數(shù)。可以使用通用算法去適應(yīng)非常特別和復(fù)雜的需求。你可以提供自己的搜索標(biāo)準(zhǔn)或者特殊的操作去綁定元素。
STL的概念是將數(shù)據(jù)和操作獨(dú)立開來。數(shù)據(jù)由容器類管理,而操作是由可配置的算法定義。迭代器則是這兩個(gè)元素之間的線索。它允許任何算法和容器的交互。
在某種意義上,STL的概念有勃于面向?qū)ο缶幊痰某踔?#xff1a;STL將數(shù)據(jù)和算法分離而非綁定它們。然而,這樣做的理由非常重要:原則上,你可以將任何容器同任何算法綁定,得到的結(jié)果是STL是非常可擴(kuò)展的。
STL的一個(gè)標(biāo)準(zhǔn)是它支持任意數(shù)據(jù)類型。“標(biāo)準(zhǔn)模板庫”意味著,所有部分是適應(yīng)任意類型的模板。STL是通用編程的例子。容器和算法對任意類型和類都是通用的。
STL甚至提供更多的通用組件。使用 適配器 和函數(shù)體,你可以為特定需要補(bǔ)充、限制和配置算法和接口。
一個(gè)find Vector的例子(BAIDU里找的),注意find不屬于vector的成員,而存在于算法中,應(yīng)加上頭文件#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;
}
貌似這是個(gè)簡單版,先mark一下,回頭補(bǔ)。
哈哈,正解在此,雖然渣渣從沒玩過,不過很好用的樣子,媽媽再也不用擔(dān)心程序效率低了。
用stl的find方法查找一個(gè)包含簡單類型的vector中的元素是很簡單的,例如
vector<string> strVec;?
find(strVec.begin(),strVec.end(),”aa”);
假如vector包含一個(gè)復(fù)合類型的對象呢比如
class A {
public:
?????? A(const std::string str,int id)
????? ?{
??????????????? this->str=str; this->id=id;
?????? }?
private:
????? ?std::string str; int id;
??????? };
這個(gè)時(shí)候一般的想法是寫個(gè)函數(shù)遍歷這個(gè)vector,然后進(jìn)行比較查找。實(shí)際上在使用STL的時(shí)候,不建議使用循環(huán)遍歷的查找方法,有幾個(gè)理由(參加《effictive c++》46條): 效率:泛型算法通常比循環(huán)高效。 正確性: 寫循環(huán)時(shí)比調(diào)用泛型算法更容易產(chǎn)生錯(cuò)誤。 可維護(hù)性: 與相應(yīng)的顯式循環(huán)相比,泛型算法通常使代碼更干凈、更直觀。
實(shí)際上通過find_if泛型算法可以很優(yōu)雅的達(dá)到期望的效果。
template<class InputIterator, class Predicate> InputIterator find_if( InputIterator _First, InputIterator _Last, Predicate_Pred );
這里的最后一個(gè)參數(shù)可是一個(gè)一元謂詞,即只帶一個(gè)參數(shù)且返回值限定為bool的函數(shù)對象,例如
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);
以上函數(shù)限定了比較的內(nèi)容,如果我們想要靈活的自定義比較條件的話要如何做呢,有2個(gè)辦法,一個(gè)是自定義類 ,并重載()操作符號,例如:
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;
};
比較的時(shí)候只要
vector<A>::iterator t=find_if(a.begin(),a.end(),findx(“33″));
還有一種方法是使用仿函數(shù)和綁定器。仿函數(shù)就是類似上面的重載了操作符()的自定義類,或者用struct也可以。因?yàn)樗x了操作符“()”,所以能夠像函數(shù)調(diào)用一樣在對象名后加上“()”,并傳入對應(yīng)的參數(shù),從而執(zhí)行相應(yīng)的功能。這樣的類型就是函數(shù)對象,從而能作為函數(shù)參數(shù)傳遞給find_if。
下面再說綁定器:
STL中的綁定器有類綁定器和函數(shù)綁定器兩種,類綁定器有binder1st和binder2nd,而函數(shù)綁定器是bind1st和bind2nd,他們的基本目的都是用于構(gòu)造一個(gè)一元的函數(shù)對象。比如這里我們可以利用bind2nd通過綁定二元函數(shù)對象中的第二個(gè)參數(shù)的方式來實(shí)現(xiàn)二元謂詞向一元謂詞的轉(zhuǎn)換。
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的循環(huán)還是find_if泛型算法,在性能和代碼復(fù)雜度上面都有一定得權(quán)衡,至于在實(shí)際應(yīng)用中,還是需要具體問題具體分析的。
以下泛型模板,反正我是沒看懂,不知道以后會不會用到。
現(xiàn)在還是迷糊的,下面是自己在項(xiàng)目中看到的師傅寫的一個(gè)比較實(shí)用的方法:
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);
總結(jié)
以上是生活随笔為你收集整理的vector中find和find_if的用法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 成都大熊猫繁育研究基地老年人门票免费吗?
- 下一篇: 引用 Map 数据结构的排序问题