一. 查找算法
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:1
std::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:5
std::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()))
{
// 进入了这里, 但是数组中并没有7
std::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;
}
/