STL算法总结之查找算法示例
1.adjacent_find:
// 所有容器适用(线性的)
adjacent_find(begin,end);
adjacent_find(begin,end,Predicate);
在范围[first,last)之间寻找第一次出现的两个连续相等的元素,如果存在,则返回指向第一个元素迭代器,否则返回last.还可以使用自己定义的二元断言(就是自定义的判断方法)
#include<vector>
#include<iostream>
#include<stdio.h>
#include<algorithm>
using namespace std;
/**
自定义的方法,判断的相等的条件是
i=j*2
*/
bool myfunction (int i, int j){
return (i==j*2);
}
/**
//所有容器适用(线性的)
adjacent_find(b,e);
adjacent_find(b,e,p);
在范围[first,last)之间寻找第一次出现的两个
连续相等的元素,如果存在,则返回指向第一个元素迭代器,否则返回last.
还可以使用自己定义的判断方法
*/
int main(){
int myints[] = {10,20,30,30,40,20,10,20};
//将数组中的元素录入myvector
vector<int> myvector (myints,myints+8);
vector<int>::iterator it;//迭代器
printf("初始元素\n");
for(it=myvector.begin();it!=myvector.end();++it)
cout<<*it<<" ";
cout<<endl;
//使用默认的比较方法
it = adjacent_find (myvector.begin(), myvector.end());
if (it!=myvector.end())
cout << "第一个连续的元素是: " << *it << endl;
//使用自定义的比较方法
it = adjacent_find (myvector.begin(), myvector.end(), myfunction);
if (it!=myvector.end())
cout << "第二个连续的元素是: " << *it << endl;
return 0;
}
/*****
Output
初始元素
10 20 30 30 40 20 10 20
第一个连续的元素是: 30
第二个连续的元素是: 40
*/
2.binary_search和includes:
binary_search() //二分查找,返回bool值,
binary_search(begin,end,value);
binary_search(begin,end,value,cmp);
includes() //包含查找,判断容器是否是包含关系,返回bool值。
includes(begin1,end1,begin2,end2);
includes(begin1,end1,begin2,end2,cmp);
binary_search():如果在[first,end)范围内存在任一元素和val相等,则返回true,否则返回false.必须是已经排序的容器
includes():两个区间必须已经排序,判断区间1是否包含区间2,范围同样是[first,end)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
/**
//所有容器适用(O(log(n)))
已序区间查找算法
binary_search() //二分查找,返回bool值,
binary_search(begin,end,value);
binary_search(begin,end,value,cmp);
includes() //包含查找,判断容器是否是包含关系,返回bool值。
includes(begin1,end1,begin2,end2);
includes(begin1,end1,begin2,end2,cmp);
*/
bool myfunction (int i,int j){
return (i<j);
}
int main(){
int myints[] = {1,2,3,4,5,4,3,2,1};
vector<int> v(myints,myints+9); // 1 2 3 4 5 4 3 2 1
//使用默认的比较
sort (v.begin(), v.end());
cout << "查找 3... ";
if (binary_search (v.begin(), v.end(), 3))
cout << "发现!\n"; else cout << "没有发现.\n";
//使用自定义的比较
sort (v.begin(), v.end(), myfunction);
cout << "查找 6... ";
if (binary_search (v.begin(), v.end(), 6, myfunction))
cout << "发现!\n"; else cout << "没有发现.\n";
cout<<endl;
/**----------------------------includes()容器包含查找---------------------------**/
int container[] = {5,15,10,25,20,35,30,50,45,40};
int continent[] = {40,30,20,10};
sort (container,container+10);
sort (continent,continent+4);
//使用默认的比较
if ( includes(container,container+10,continent,continent+4) )
cout << "容器container 包含容器continent!" << endl;
//使用自定义的比较
if ( includes(container,container+10,continent,continent+4, myfunction) )
cout << "容器container 包含容器continent!" << endl;
return 0;
}
/**
Output
查找 3... 发现!
查找 6... 没有发现.
容器container 包含容器continent!
容器container 包含容器continent!
*/
3.count和count_if:
count:
count (begin,end,value);
count_if:
count_if (begin,end,predicate);
关联容器的等效成员函数
set.count
multiset.count
map.count
multimap.count
count:这个函数使用一对迭代器和一个值做参数,返回这个值出现次数的统计结果
count_if:返回区间中满足指定条件的元素数目
#include<iostream>
#include<vector>
#include<set>
#include<algorithm>
using namespace std;
/**
奇数
*/
bool IsOdd (int i){
return i&1;
}
int main(){
int mycount;
// 数组计数元素
int myints[] = {10,20,30,30,20,10,10,20}; //8个元素
mycount = (int) count (myints, myints+8, 10);
cout << "10 出现 " << mycount << " 次.\n";
//新建一个vector
vector<int> myvector (myints, myints+8);
mycount = (int) count (myvector.begin(), myvector.end(), 20);//有几个20
cout << "20 出现 " << mycount << " 次.\n";
/****************
Output:
10 出现 3 次.
20 出现 3 次.
****************/
//清除vector
myvector.clear();
for (int i=1; i<10; i++) myvector.push_back(i); // myvector: 1 2 3 4 5 6 7 8 9
cout<<"\nmyvector: 1 2 3 4 5 6 7 8 9 \n";
// mycount = (int) count_if (myvector.begin(), myvector.end(), IsOdd);
mycount = (int) count_if (myvector.begin(), myvector.end(), bind2nd(modulus<int>(),2));//表示param1 % 2
cout << "myvector 包含 " << mycount << " 奇数元素.\n";//奇数
// 如果求偶数的个数 not1,1表示一个参数取反
mycount = (int) count_if (myvector.begin(), myvector.end(), not1(bind2nd(modulus<int>(),2)));//表示!(param1 % 2)
cout << "myvector 包含 " << mycount << " 偶数元素.\n";//偶数
/****************
Output:
myvector 包含 5 奇数元素.
****************/
// 函数适配器 函数对象
// bind2nd(op,value);表示绑定第二个数 param1 > 4 这里表示统计大于4的个数
mycount=count_if(myvector.begin(),myvector.end(),bind2nd(greater<int>(),4));
cout<<"有"<<mycount<<"个数大于4"<<endl;
//拓展练习 4 > param2
mycount=count_if(myvector.begin(),myvector.end(),bind1st(greater<int>(),4));
cout<<"有"<<mycount<<"个数小于4"<<endl;
// 4 < param2
mycount=count_if(myvector.begin(),myvector.end(),bind1st(less<int>(),4));
cout<<"有"<<mycount<<"个数大于4"<<endl;
// param1 >= 4
mycount=count_if(myvector.begin(),myvector.end(),bind2nd(greater_equal<int>(),4));
cout<<"有"<<mycount<<"个数大于等于4"<<endl;
// param1 <= 4
mycount=count_if(myvector.begin(),myvector.end(),bind2nd(less_equal<int>(),4));
cout<<"有"<<mycount<<"个数小于等于4"<<endl;
/****关联容器****/
multiset<int> ms(myvector.begin(),myvector.end());
ms.insert(myvector.begin(),myvector.begin()+6);
ms.insert(myvector.begin(),myvector.begin()+4);
ms.insert(myvector.begin(),myvector.begin()+2);
ms.insert(1);
multiset<int>::iterator ims=ms.begin();
while(ims!=ms.end()){
cout<<*ims++<<" ";
}cout<<endl;
//两种方法求1的个数
int cnt=count(ms.begin(),ms.end(),1);//所有容器适用但是比较慢些
cout<<"multiset里有"<<cnt<<"个1."<<endl;
cnt=ms.count(1);//关联容器专享 set已经排序可以快速计数
cout<<"multiset里有"<<cnt<<"个1."<<endl;
return 0;
}
4.lower_bound,upper_bound,equal_range:
所有容器适用(O(log(n))) 已序区间查找算法
lower_bound() //找第一个符合的元素,返回位置迭代器
lower_bound (begin,end,value);
lower_bound (begin,end,value,cmp);
upper_bound() //找最后一个符合的元素,返回位置迭代器
upper_bound (begin,end,value);
upper_bound (begin,end,value,cmp);
equal_range() //找一对迭代器pair(<>,<>),查找到一个区间
equal_range (begin,end,value);
equal_range (begin,end,value,cmp);
关联式容器有等效的成员函数,性能更佳
lower_bound() 找第一个符合的元素,返回位置迭代器
upper_bound() 找最后一个符合的元素,返回位置迭代器
equal_range() 在[first,last)之中找出符合的元素的最大子区间
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
/**
判断i是否比j大
*/
bool mygreater(int i,int j){
return (i>j);
}
int main(){
int myints[] = {10,20,30,30,20,10,10,20};
vector<int> v(myints,myints+8); // 10 20 30 30 20 10 10 20
vector<int>::iterator low,up;
sort (v.begin(), v.end()); // 10 10 10 20 20 20 30 30
cout<<"10 10 10 20 20 20 30 30\n";
low=lower_bound (v.begin(), v.end(), 20); // ^
up= upper_bound (v.begin(), v.end(), 20); // ^
cout << "20 lower_bound at position " << int(low- v.begin()) + 1 << endl;
cout << "20 upper_bound at position " << int(up - v.begin()) + 1 << endl;
cout << endl;
/**-------------------------------------------------------------------------------**/
pair<vector<int>::iterator,vector<int>::iterator> bounds;
//使用默认的比较方法
// sort (v.begin(), v.end()); // 10 10 10 20 20 20 30 30
bounds=equal_range (v.begin(), v.end(), 20); // ^ ^
cout<<"10 10 10 20 20 20 30 30\n";
cout << "20 bounds at positions " << int(bounds.first - v.begin());
cout << " and " << int(bounds.second - v.begin()) << endl;
// using "mygreater" as comp:
sort (v.begin(), v.end(), mygreater); // 30 30 20 20 20 10 10 10
bounds=equal_range (v.begin(), v.end(), 20, mygreater); // ^ ^
cout<<endl<<"30 30 20 20 20 10 10 10"<<endl;
cout << "20 bounds at positions " << int(bounds.first - v.begin());
cout << " and " << int(bounds.second - v.begin()) << endl;
return 0;
}
/******
Output:
10 10 10 20 20 20 30 30
20 lower_bound at position 4
20 upper_bound at position 7
10 10 10 20 20 20 30 30
bounds at positions 3 and 6
30 30 20 20 20 10 10 10
bounds at positions 2 and 5
*/