STL之search()算法

我们之前介绍的find()算法以及find_if()算法都帮助我们查找判断某一个value是否被包含在序列中,并返回它第一次出现时所处的位置,假如我想找到某一段满足条件的子区间,应该怎么做呢?C++标准库又为我们提供了哪些算法呢?

(下面程序中要用到的algostuff.h)

search_n()        搜寻具有某特性的第一段“n个连续元素”

InputIterator 
search_n(InputItertor beg,InputIterator end,
        Size count,const T& value)

InputIterator
search_n(InputIterator beg,InputIterator end,
        Size count,const T&value,BinaryPredicate op)
  • 第一形式返回区间[beg,end)中第一组”连续count个元素值全等于 value"的元素位置
  • 第二形式返回区间[beg,end)中第一组“连续count个元素造成以下一元判断式结果为true”的元素位置: op(elem,value)
  • 如果没有找到匹配元素,两种形式都返回end
  • op在函数调用过程中不应该改变自身状态
  • op不应变动被传进去的参数

下面这个例子搜寻连续4个“数值大于等于3”的元素:

#include"algostuff.h"
using namespace std;
int main()
{
	deque<int> col;
	INSERT_ELEMENTS(col, 1, 9);
	PRINT_ELEMENTS(col);	//1 2 3 4 5 6 7 8 9

	//find four consecutive elements with value 3
	deque<int>::iterator pos;
	pos = search_n(col.begin(), col.end(), 4, 3);

	//print result
	if (pos != col.end())
	{
		cout << "four consecutive element with value 3 "
			<< "start with " << distance(col.begin(), pos) + 1 << ".element" << endl;
	}
	else
	{
		cout << "no four consecutive elements with value 3 not found" << endl;
	}
	//no four consecutive elements with value 3 not found
	

	//find four consecutive elements with value greater than 3
	pos = search_n(col.begin(), col.end(), 4, 3, greater<int>());
	//print result
	if (pos != col.end())
	{
		cout << "four consecutive elements with value > 3 "
			<< "start with " << distance(col.begin(), pos) + 1
			<< ". element" << endl;
	}
	else
	{
		cout << "no four consecutive elements with value > 3 found " << endl;
	}

}

 运算结果如下:

 

search()        搜寻某个子区间第一次出现位置

ForwardIterator1
search(ForwardIterator1 beg,ForwardIterator1 end,
        ForwardIterator2 searchBeg,ForwardIterator2 searchEnd)

ForwardIterator1
search(ForwardIterator1 beg,ForwardIterator1 end,
        ForwardIterator2 searchBeg,ForwardIterator2 searchEnd,
        BinaryPredicate op)
  • 两种形式都返回区间[beg,end)内“和区间[searchBeg,searchEnd)完全吻合”的第一个子区间的第一个元素位置
  • 第一形式中,子区间的元素必须完全等于[searchBeg,searchEnd)中的元素
  • 第二形式中,子区间的元素和[searchBeg,searchEnd)里面的对应元素必须造成以下二元判断式的结果为true:       op(elem,searchElem)
  • 如果没有找到符合条件的子区间,两种形式都返回end
  • op在函数调用过程中不应改变自身状态
  • op不应变动传入的参数

下面这个例子展示如何在另一个序列中搜寻一个子序列

#include"algostuff.h"
using namespace std;
int main()
{
	deque<int> col;
	list<int> subcol;

	INSERT_ELEMENTS(col, 1, 7);
	INSERT_ELEMENTS(col, 1, 7);
	PRINT_ELEMENTS(col, "col: ");	//col: 1 2 3 4 5 6 7 1 2 3 4 5 6 7

	INSERT_ELEMENTS(subcol, 3, 6);
	PRINT_ELEMENTS(subcol, "subcol: ");	//subcol: 3 4 5 6

	//search first occurrence of subcol in col
	deque<int>::iterator pos;
	pos = search(col.begin(), col.end(), subcol.begin(), subcol.end());
	//loop while subcol found as subrange of col
	while (pos != col.end())
	{
		//print position of first element
		cout << "subcol found starting with element "
			<< distance(col.begin(), pos) + 1
			<< endl;
		//search next occurrence of subcol
		++pos;
		pos = search(pos, col.end(), subcol.begin(), subcol.end());
	}
}

 

下面这个程序展示如何利用search()算法的第二形式 ,以更复杂的准则来搜寻某个子序列,这里寻找的是“偶数、奇数、偶数”排列而成的子序列区间

#include"algostuff.h"
using namespace std;

//checks whether an element is even or odd
bool checkEven(int elem, bool even)
{
	if (even)
	{
		return elem % 2 == 0;
	}
	else
	{
		return elem % 2 == 1;
	}
}

int main()
{
	vector<int> col;
	INSERT_ELEMENTS(col, 1, 9);
	PRINT_ELEMENTS(col, "col:");	//col:1 2 3 4 5 6 7 8 9

	bool checkEvenArgs[3] = { true,false,true };

	//search first subrange in col
	vector<int>::iterator pos;
	pos = search(col.begin(), col.end(),    //range
		checkEvenArgs, checkEvenArgs + 3,   //subrange values
		checkEven);							//subrange criterion

	//loop while surange found
	while (pos != col.end())
	{
		//print position of first element
		cout << "subrange found starting with element "
			<< distance(col.begin(), pos) + 1 << endl;
		//search next subrange in col
		pos = search(++pos, col.end(),			//range
			checkEvenArgs, checkEvenArgs + 3,	//subrange values
			checkEven);							//criterion
	}


}

运行结果如下: 

(以上表示共找出三个满足“偶、奇、偶”条件的子序列,分别从元素2,4,6开始) 

find_end()        搜寻某个子区间最后一次出现位置

ForwardIterator 
find_end(ForwardIterator beg,ForwardIterator end,
        ForwardIterator searchBeg,ForwardIterator searchEnd)

ForwardIterator
find_end(ForwardIterator beg,ForwardIterator end,
        ForwardIterator searchBeg,ForwardIterator searchEnd,
        BinaryPredicate op)
  • 两种形式都返回区间[beg,end)之中“和区间[searchBeg,searchEnd)完全吻合”的最后一个子区间内的第一个元素位置
  • 第一形式中,子区间的元素必须完全等于[searchBeg,searchEnd)的元素
  • 第二形式中,子区间的元素和[searchBeg,searchEnd)的对应元素必须造成以下二元判断式的结果为true:           op(elem,searchElem)
  • 如果没有找到符合条件的子区间,两种形式都返回end
  • op在函数调用过程中不应该改变自身状态
  • op不应改动传入的参数

下面这个例子展示如何在一个序列中搜寻“与某序列相等”的最后一个子序列

#include"algostuff.h"
using namespace std;
int main()
{
	deque<int> col;
	list<int> subcol;
	INSERT_ELEMENTS(col, 1, 7);
	INSERT_ELEMENTS(col, 1, 7);

	INSERT_ELEMENTS(subcol, 3, 6);

	PRINT_ELEMENTS(col, "col: ");	//col: 1 2 3 4 5 6 7 1 2 3 4 5 6 7
	PRINT_ELEMENTS(subcol, "subcol: ");	//subcol: 3 4 5 6

	//search last occurrence of subcol in col
	deque<int>::iterator pos;
	pos = find_end(col.begin(), col.end(), //range
		subcol.begin(), subcol.end());	//subrange

	//loop while subcol found as subrange of col
	deque<int>::iterator end(col.end());
	while (pos != end)
	{
		//print position of first element
		cout << "subcol found starting with element "
			<< distance(col.begin(), pos) + 1 << endl;

		//search nect occurrence of subcol
		end = pos;
		pos = find_end(col.begin(), end, subcol.begin(), subcol.end());
	}
}

 

find_first_of()        搜寻某些元素的第一次出现地点

ForwardIterator 
find_first_of(ForwardIterator1 Beg,ForwardIterator1 end,
                ForwardIterator2 searchBeg,ForwardIterator2 searchEnd)

ForwardIterator 
find_first_of(ForwardIterator1 Beg,ForwardIterator1 end,
                ForwardIterator2 searchBeg,ForwardIterator2 searchEnd,
                BinaryPredicate op)
  • 第一形式返回第一个“既在[beg,end)中出现,也在区间[searchBeg,searchEnd)中出现”的元素的位置
  • 第二形式返回区间[beg,end)中第一个这样的元素:它和区间[searchBeg,searchEnd)内每一个元素进行以下动作的结果都是true:        op(elem,searchElem)
  • 如果没有找到吻合元素,两种形式都返回end
  • op在调用过程中不应改变自身状态
  • op不应改动传入的参数

下面展示find_first_of()的用法

#include"algostuff.h"
using namespace std;
int main()
{
	vector<int> col;
	list<int> searchcol;

	INSERT_ELEMENTS(col, 1, 11);
	INSERT_ELEMENTS(searchcol, 3, 5);

	PRINT_ELEMENTS(col, "col: ");	//col: 1 2 3 4 5 6 7 8 9 10 11
	PRINT_ELEMENTS(searchcol, "searchcol: ");	//searchcol: 3 4 5

	//search first occurrence of an element of searchcol in col
	vector<int>::iterator pos;
	pos = find_first_of(col.begin(), col.end(),	//range
		searchcol.begin(), searchcol.end());	//search range

	cout << "first element of searchcol in col is element "
		<< distance(col.begin(), pos) + 1 << endl;

	//search last occurrence of an element of searchcol in col
	vector<int>::reverse_iterator rpos;
	rpos = find_first_of(col.rbegin(), col.rend(), searchcol.begin(), searchcol.end());
	cout << "last element of searchcol in col is element "
		<< distance(col.begin(), rpos.base()) << endl;

}

 

adjacent _find()        搜寻两个连续相等的元素

InputIterator
adjacent_find(InputIterator beg,InputIterator end)

InputIterator
adjacent_find(InputIterator beg,InputIterator end, BinaryPredicate op)
  • 第一形式返回区间[beg,end)中第一对“连续两个相等元素”之中的第一元素位置
  • 第二形式返回区间[beg,end)中第一对“连续两个元素均使以下二元判断式的结果为true”的其中第一元素位置:       op(elem,nectElem)
  • 如果没有找到吻合元素,两者都返回end
  • op在函数调用过程中不应该改变自身状态
  • op不应改动传入的参数

下面展示adjacent_find()算法的用法

#include"algostuff.h"
using namespace std;

//return whether the second object has double the value of the first
bool doubled(int elem1, int elem2)
{
	return elem1 * 2 == elem2;
}
int main()
{
	vector<int> col;
	col.push_back(1);
	col.push_back(3);
	col.push_back(2);
	col.push_back(4);
	col.push_back(5);
	col.push_back(5);
	col.push_back(0);

	PRINT_ELEMENTS(col, "col: ");
	// search first two elements with equal value
	vector<int>::iterator pos;
	pos = adjacent_find(col.begin(), col.end());
	if (pos != col.end())
	{
		cout << "first two elements with equal value have position "
			<< distance(col.begin(), pos) + 1 << endl;
	}
	//search first two elements for which the second has double the value of the first
	pos = adjacent_find(col.begin(), col.end(), doubled);
	if (pos != col.end())
	{
		cout << "first two elements with second value twice the first have pos. "
			<< distance(col.begin(), pos) + 1 << endl;
	}
}

search_n() 搜寻具有某特性的第一段“n个连续元素”
search() 搜寻某个子区间第一次出现位置
find_end() 搜寻某个子区间最后一次出现的位置
find_first_of() 搜寻某些元素第一次出现地点
adjacent_find() 搜寻两个连续且相等的元素

猜你喜欢

转载自blog.csdn.net/yangSHU21/article/details/130552876
今日推荐