常用查找算法
find()
find_if()
search_n()
search()
find_end()
first_first_of()
adjacent_find()
find()
和find_if()
find()
和find_if()
是线性查找,查找速度较慢。查找的结果是迭代器。- 如果是已序区间,可以使用已序区间查找算法:
binary_search()
includes()
lower_bound()
upper_bound()
- 关联式容器有等效的成员函数
find()
,时间复杂度为对数复杂度
l
o
g
(
n
)
log(n)
log(n). string
有等效的成员函数find()
.
find()
代码示例
#include <iostream>
#include <algorithm>
#include <list>
using namespace std;
int main()
{
list<int> ilist;
for (int i = 1; i <= 9; ++i)
ilist.insert(ilist.end(), i);
for (int i = 1; i <= 9; ++i)
ilist.insert(ilist.end(), i);
for (list<int>::iterator iter = ilist.begin();
iter != ilist.end(); ++iter)
cout << *iter << ' ';
cout << endl;
list<int>::iterator pos1;
pos1 = find(ilist.begin(), ilist.end(), 4);
list<int>::iterator pos2;
if (pos1 != ilist.end())
{
pos2 = find(++pos1, ilist.end(), 4);
}
if (pos1 != ilist.end() && pos2 != ilist.end())
{
--pos1;
++pos2;
for (list<int>::iterator iter = pos1; iter != pos2; ++iter)
cout << *iter << ' ';
}
return 0;
}
find_if()
代码示例
#include <iostream>
#include <algorithm>
#include <vector>
#include <functional>
using namespace std;
int main()
{
vector<int> ivec;
vector<int>::iterator pos;
for (int i = 1; i <= 9; ++i)
ivec.push_back(i);
for (vector<int>::iterator iter = ivec.begin();
iter != ivec.end(); ++iter)
cout << *iter << ' ';
cout << endl;
pos = find_if(ivec.begin(), ivec.end(), bind2nd(greater<int>(), 3));
cout << *pos << endl;
pos = find_if(ivec.begin(), ivec.end(), not1(bind2nd(modulus<int>(), 3)));
cout << *pos << endl;
return 0;
}
关联式容器成员函数find()
#include <iostream>
#include <set>
using namespace std;
int main()
{
set<int> iset;
iset.insert(43);
iset.insert(78);
iset.insert(-1);
iset.insert(124);
for (set<int>::iterator iter = iset.begin();
iter != iset.end(); ++iter)
cout << *iter << ' ';
cout << endl;
set<int>::iterator pos;
pos = iset.find(78);
if (pos != iset.end())
cout << "找到了:" << *pos << endl;
else
cout << "没找到!" << endl;
return 0;
}
string
的成员函数find()
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s("AnnaBelle");
string::size_type pos = s.find("Bell");
if (pos != string::npos)
cout << "找到了:" << pos << endl;
else
cout << "没找到!" << endl;
pos = s.find("bell");
if (pos != string::npos)
cout << "找到了:" << pos << endl;
else
cout << "没找到!" << endl;
return 0;
}
search_n()
search_n(b, e, c, v)
:查找连续的n
个值;[b, e)
迭代器,c
个数,v
数值value
。search_n(b, e, c, v, p)
:p
谓词。- 该算法的第二种形式本应为:
search_n_if(b, e, c, p)
,但是错误。
代码示例
#include <iostream>
#include <deque>
#include <algorithm>
#include <functional>
using namespace std;
int main()
{
deque<int> ideq;
for (int i = 1; i <= 9; ++i)
{
if (i == 3)
{
ideq.push_back(3);
ideq.push_back(3);
ideq.push_back(3);
ideq.push_back(3);
}
else
ideq.push_back(i);
}
for (deque<int>::iterator iter = ideq.begin();
iter != ideq.end(); ++iter)
cout << *iter << ' ';
cout << endl;
deque<int>::iterator pos;
pos = search_n(ideq.begin(), ideq.end(), 4, 3);
if (pos != ideq.end())
cout << "找到连续的4个3,序号的位置:" << distance(ideq.begin(), pos)+1 << endl;
else
cout << "没找到!" << endl;
pos = search_n(ideq.begin(), ideq.end(), 3, 6, greater<int>());
if (pos != ideq.end())
cout << "找到了连续的3个大于6的数,start with " << distance(ideq.begin(), pos) << endl;
else
cout << "没找到!" << endl;
return 0;
}
search()
和find_end()
search()
和find_end()
是一对函数,顺序和逆序查找。
简单代码示例
#include <iostream>
#include <deque>
#include <list>
#include <algorithm>
using namespace std;
int main()
{
deque<int> ideq;
list<int> ilist;
for (int i = 1; i <= 7; ++i)
ideq.insert(ideq.end(), i);
for (int i = 1; i <= 7; ++i)
ideq.insert(ideq.end(), i);
for (int i = 3; i <= 6; ++i)
ilist.insert(ilist.end(), i);
for (deque<int>::iterator iter = ideq.begin();
iter != ideq.end(); ++iter)
cout << *iter << ' ';
cout << endl;
for (list<int>::iterator iter = ilist.begin();
iter != ilist.end(); ++iter)
cout << *iter << ' ';
cout << endl;
deque<int>::iterator pos;
pos = search(ideq.begin(), ideq.end(), ilist.begin(), ilist.end());
while (pos != ideq.end())
{
cout << "找到了!位置:" << distance(ideq.begin(), pos) + 1 << endl;
++pos;
pos = search(pos, ideq.end(), ilist.begin(), ilist.end());
}
cout << "使用find_end()进行查找:" << endl;
pos = find_end(ideq.begin(), ideq.end(), ilist.begin(), ilist.end());
if (pos != ideq.begin())
cout << "找到了!位置:" << distance(ideq.begin(), pos) + 1 << endl;
else
cout << "没找到!" << endl;
return 0;
}
使用二元谓词代码示例
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
bool checkEven(int elem, bool even)
{
if (even)
return elem % 2 == 0;
else
return elem % 2 == 1;
}
int main()
{
vector<int> ivec;
for (int i = 1; i <= 9; ++i)
ivec.push_back(i);
ivec.push_back(10);
ivec.push_back(20);
ivec.push_back(30);
for (vector<int>::iterator iter = ivec.begin();
iter != ivec.end(); ++iter)
cout << *iter << ' ';
cout << endl;
bool checkEvenArgs[3] = { false, true, true };
vector<int>::iterator pos;
pos = search(ivec.begin(), ivec.end(), checkEvenArgs, checkEvenArgs + 3, checkEven);
if (pos != ivec.end())
cout << "找到了!位置:" << distance(ivec.begin(), pos) + 1 << endl;
else
cout << "没找到!" << endl;
return 0;
}
find_first_of()
find_first_of(b, e, sb, se)
- 在迭代器
[b,e)
中查找迭代器[sb, se)
中的任意一个元素,返回能找到的迭代器[sb, se)
中能找到的第一个元素的下标。
find_first_of(b, e, sb, se, bp)
- 使用逆向迭代器,没有
find_last_of()
算法
string
查找函数和STL查找算法的比较
string 函数 | STL算法 |
---|
find() | find() |
rfind() | find() +逆向迭代器 |
find() | search() |
rfind() | find_end() |
find_first_of() | find_first_of() |
find_last_of() | find_first_of() +逆向迭代器 |
代码示例
#include <iostream>
#include <vector>
#include <list>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
vector<int> ivec;
list<int> searchList;
for (int i = 1; i <= 9; ++i)
ivec.push_back(i);
for (vector<int>::iterator iter = ivec.begin();
iter != ivec.end(); ++iter)
cout << *iter << ' ';
cout << endl;
searchList.push_back(3);
searchList.push_back(6);
searchList.push_back(9);
vector<int>::iterator pos;
pos =find_first_of(ivec.begin(), ivec.end(), searchList.begin(), searchList.end());
if (pos != ivec.end())
cout << "找到了!位置:" << distance(ivec.begin(), pos) + 1 << endl;
else
cout << "没找到!" << endl;
vector<int>::reverse_iterator rpos;
rpos = find_first_of(ivec.rbegin(), ivec.rend(), searchList.begin(), searchList.end());
cout << "找到了!位置:" << distance(ivec.begin(), rpos.base()) << endl;
string numerics("0123456789");
string name("ra8d3wp6k");
string::size_type p = name.find_first_of(numerics);
if (p != string::npos)
cout << "找到了,下标:" << p << endl;
else
cout << "没找到!" << endl;
p = name.find_last_of(numerics);
if (p != string::npos)
cout << "找到了,下标:" << p << endl;
else
cout << "没找到!" << endl;
return 0;
}
adjacent_find()
adjacent_find(b, e)
:搜索序列中两个连续相等的元素,用 ==
运算符来比较连续的一对元素,返回的迭代器指向前两个相等元素中的第一个。如果没有一对相等的元素,这个算法返回这个序列的结束迭代器。adjacent_find(b, e, p)
:谓词p
.
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
bool doubled(int elem1, int elem2)
{
return elem1 * 2 == elem2;
}
int main()
{
vector<int> ivec;
ivec.push_back(1);
ivec.push_back(3);
ivec.push_back(2);
ivec.push_back(4);
ivec.push_back(5);
ivec.push_back(5);
ivec.push_back(0);
for (vector<int>::iterator iter = ivec.begin();
iter != ivec.end(); ++iter)
cout << *iter << ' ';
cout << endl;
vector<int>::iterator pos;
pos = adjacent_find(ivec.begin(), ivec.end());
if (pos != ivec.end())
cout << "找到了!位置:" << distance(ivec.begin(), pos) + 1 << endl;
else
cout << "没找到!" << endl;
pos = adjacent_find(ivec.begin(), ivec.end(), doubled);
if (pos != ivec.end())
cout << "找到了!位置:" << distance(ivec.begin(), pos) + 1 << endl;
else
cout << "没找到!" << endl;
return 0;
}
已序区间查找算法
binary_search()
和includes()
binary_search(b, e, v)
:只返回bool
查找结果。binary_search(b, e, v, p)
includes(b, e, sb, se)
includes(b, e, sb, se, p)
- 查找必须要求已排序。
- 查找可以不连续,只要有就可以。
- 谓词
p
可以指定排序规则。
代码示例
#include <iostream>
#include <list>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
list<int> ilist;
vector<int> search;
for (int i = 1; i <= 9; ++i)
ilist.insert(ilist.end(), i);
search.push_back(3);
search.push_back(4);
search.push_back(7);
for (list<int>::iterator iter = ilist.begin();
iter != ilist.end(); ++iter)
cout << *iter << ' ';
cout << endl;
if (binary_search(ilist.begin(), ilist.end(), 5))
cout << "找到了!" << endl;
else
cout << "没找到!" << endl;
if (includes(ilist.begin(), ilist.end(), search.begin(), search.end()))
cout << "都有,都找到了" << endl;
else
cout << "没找到!" << endl;
return 0;
}
lower_bound()
upper_bound()
equal_range()
代码示例
#include <iostream>
#include <list>
#include <algorithm>
using namespace std;
int main()
{
list<int> ilist;
for (int i = 1; i <= 9; ++i)
ilist.insert(ilist.end(), i);
for (int i = 1; i <= 9; ++i)
ilist.insert(ilist.end(), i);
ilist.push_back(5);
ilist.push_back(5);
ilist.push_back(5);
ilist.sort();
for (list<int>::iterator iter = ilist.begin();
iter != ilist.end(); ++iter)
cout << *iter << ' ';
cout << endl;
list<int>::iterator pos1, pos2;
pos1 = lower_bound(ilist.begin(), ilist.end(), 5);
pos2 = upper_bound(ilist.begin(), ilist.end(), 5);
cout << "第一个5的位置:" << distance(ilist.begin(), pos1) + 1 << endl;
cout << "大于5的第一个位置:" << distance(ilist.begin(), pos2) + 1 << endl;
ilist.insert(lower_bound(ilist.begin(), ilist.end(), 5), 5);
ilist.insert(upper_bound(ilist.begin(), ilist.end(), 5), 5);
for (list<int>::iterator iter = ilist.begin();
iter != ilist.end(); ++iter)
cout << *iter << ' ';
cout << endl;
pair<list<int>::iterator, list<int>::iterator> range;
range = equal_range(ilist.begin(), ilist.end(), 5);
cout << distance(ilist.begin(), range.first) + 1 << endl;
cout << distance(ilist.begin(), range.second) + 1 << endl;
return 0;
}