我们之前介绍的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() | 搜寻两个连续且相等的元素 |