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

23 篇文章 0 订阅
13 篇文章 0 订阅

一. 查找算法

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;
}
/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值