STL算法---查找算法(一)

来源:互联网 发布:晚上忍不住吃东西知乎 编辑:程序博客网 时间:2024/05/24 06:49

一. 查找算法

1. adjacent_find (相邻查找)

adjacent_find(_First, _Last);
在范围[_First, _Last)查找第一对相邻相等的元素, 并返回这对元素的前面的iterator.

adjacent_find(_First, _Last, _Pred);
在范围[_First, _Last)查找第一对相邻的元素, 这对元素满足_Pred的比较关系, 并返回这对元素的前面的iterator.
_Pred是一个函数对象, _Pred实现括号操作符(相当于一个回调函数指针).

例子:
//////////////////////////////////////////#include "stdafx.h"#include <algorithm>#include <numeric>#include <functional>#include <vector>#include <iostream>class MyObject {  public:MyObject(){}~MyObject(){}// 括号操作符    bool operator()(int val1, int val2)      {          return (val1 == (val2 - 1)) ? true : false;      }};int _tmain(int argc, _TCHAR* argv[]){std::vector<int> nV;std::vector<int>::iterator iter;std::vector<int>::iterator iterBegin;std::vector<int>::iterator iterEnd;nV.push_back(1);nV.push_back(4);nV.push_back(5);nV.push_back(1);nV.push_back(1);iterBegin = nV.begin();iterEnd = nV.end();iter = std::adjacent_find(iterBegin, iterEnd);if(iter != iterEnd){// 输出 1:1std::cout << *iter << ":" << *(iter + 1) << std::endl;}iterBegin = nV.begin();iterEnd = nV.end() - 1;iter = std::adjacent_find(iterBegin, iterEnd);if(iter != iterEnd){// 不进入这里std::cout << *iter << ":" << *(iter + 1) << std::endl;}iterBegin = nV.begin();iterEnd = nV.end();iter = std::adjacent_find(iterBegin, iterEnd, MyObject());// 这里使用函数对象if(iter != iterEnd){// 输出4:5std::cout << *iter << ":" << *(iter + 1) << std::endl;}return 0;}//////////////////////////////////////////////

2. binary_search (二分查找)

在有序序列中查找value,找到返回true。重载的版本实用指定的比较函数对象或函数指针来判断相等.

bool binary_search(_FwdIt _First, _FwdIt _Last, const _Ty& _Val);
在范围[_First, _Last)查找_Val, 如果找到返回true. (比较器是 <)

bool binary_search(_FwdIt _First, _FwdIt _Last, const _Ty& _Val, _Pr _Pred);
在范围[_First, _Last)查找_Val, 如果找到返回true. (比较器是 _Pred)


2.1. 注意点一

在binary_search中, 范围[_First, _Last)需要升序排列, 否则查找会错误.
(个人理解: 这里的二分查找算法按照升序排列来只遍历部分元素).

例子:
/////////////////////////////////////////////////////////////#include "stdafx.h"#include <algorithm>#include <numeric>#include <functional>#include <vector>#include <iostream>int _tmain(int argc, _TCHAR* argv[]){std::vector<int> nV;std::vector<int>::iterator iter;std::vector<int>::iterator iterBegin;std::vector<int>::iterator iterEnd;int nSearch = 6;// 无序nV.push_back(1);nV.push_back(5);nV.push_back(3);nV.push_back(2);nV.push_back(6);nV.push_back(4);iterBegin = nV.begin();iterEnd = nV.end();if(true == std::binary_search(iterBegin, iterEnd, nSearch)){// 这里不一定有结果std::cout << "OK1" << std::endl;}// 降序nV.clear();nV.push_back(6);nV.push_back(5);nV.push_back(4);nV.push_back(3);nV.push_back(2);nV.push_back(1);iterBegin = nV.begin();iterEnd = nV.end();if(true == std::binary_search(iterBegin, iterEnd, nSearch)){// 这里没有结果std::cout << "OK2" << std::endl;}// 升序nV.clear();nV.push_back(1);nV.push_back(2);nV.push_back(3);nV.push_back(4);nV.push_back(5);nV.push_back(6);iterBegin = nV.begin();iterEnd = nV.end();if(true == std::binary_search(iterBegin, iterEnd, nSearch)){// 这里有结果std::cout << "OK3" << std::endl;}return 0;}

2.2 注意点二

在binary_search中, 匹配数据相等时, 两个值a和b在!(a < b) && !(b < a)求值为true时被认为是相等的.
例子:

////////////////////////////////////////////////////#include "stdafx.h"#include <algorithm>#include <numeric>#include <functional>#include <vector>#include <iostream>class MyObject1{  public:MyObject1(){}~MyObject1(){}// 括号操作符    bool operator()(int val1, int val2)      {          return val1 < val2 ? true : false;      }};class MyObject2{  public:MyObject2(){}~MyObject2(){}// 括号操作符    bool operator()(int val1, int val2)      {          return val1 == val2 ? true : false;      }};int _tmain(int argc, _TCHAR* argv[]){std::vector<int> nV;std::vector<int>::iterator iter;std::vector<int>::iterator iterBegin;std::vector<int>::iterator iterEnd;int nSearch = 7;// 升序nV.clear();nV.push_back(1);nV.push_back(2);nV.push_back(3);nV.push_back(4);nV.push_back(5);nV.push_back(6);iterBegin = nV.begin();iterEnd = nV.end();if(true == std::binary_search(iterBegin, iterEnd, nSearch, MyObject1())){// 没有进入这里, std::cout << "OK1" << std::endl;}iterBegin = nV.begin();iterEnd = nV.end();if(true == std::binary_search(iterBegin, iterEnd, nSearch, MyObject2())){// 进入了这里, 但是数组中并没有7std::cout << "OK2" << std::endl;}return 0;}/////////////////////////////////////////////////

说明:
A. MyObject1和MyObject2的区别是"<"和"==".
B. 代入公式:!(a < b) && !(b < a)看一下, 可以理解的是, 使用MyObject2的时候, "<"被转成了"=="了, 所以得到不想要的结果.
C. 也就是说, MyObject的括号操作符的实现中要符合比较元素的"<"规则才是正确的.
D. 如果[_First, _Last)中的元素与比较元素_Val是同一类型时, 你可以直接重载元素的"<"操作也是可以的, 而不需要定义一个MyObject函数对象.


例子
/////////////////////////////////////////////#include "stdafx.h"#include <algorithm>#include <numeric>#include <functional>#include <vector>#include <iostream>#include <string>struct STItem{STItem(){}STItem(const std::string& strData): m_strData(strData){}STItem(const STItem& stItem){*this = stItem;}~STItem(){Release();}STItem& operator=(const STItem& stItem){m_strData = stItem.m_strData;return *this;}bool operator<(const STItem& stItem) const{return m_strData.length() < stItem.m_strData.length();}void Release(){}std::string m_strData;};int _tmain(int argc, _TCHAR* argv[]){std::vector<STItem> nV;std::vector<STItem>::iterator iter;std::vector<STItem>::iterator iterBegin;std::vector<STItem>::iterator iterEnd;STItem stItem;stItem.m_strData = "54321";// 升序nV.clear();nV.push_back(STItem("1"));nV.push_back(STItem("12"));nV.push_back(STItem("123"));nV.push_back(STItem("1234"));nV.push_back(STItem("12345"));nV.push_back(STItem("123456"));iterBegin = nV.begin();iterEnd = nV.end();if(true == std::binary_search(iterBegin, iterEnd, stItem)){// 进入这里, 而且是正确的std::cout << "OK1" << std::endl;}stItem.m_strData = "7654321";iterBegin = nV.begin();iterEnd = nV.end();if(true == std::binary_search(iterBegin, iterEnd, stItem)){// 没有进入这里, 是正确的std::cout << "OK2" << std::endl;}return 0;}/////////////////////////////////////////////

0 0
原创粉丝点击