rangge(区间)
所有的算法都是用来处理一个或者多个区间内的元素,为了操作元素的某个子集,我们必须将区间首尾按照两个实参传给算法,我不是一口气将整个容器传递过去。我们必须保证两个迭代器必须属于同一个容器,且前后放置正确,否则后果难料。stl的区间都是半开区间,也就是包括前面的迭代器而不包括后面的迭代器。
按照算法的参数,划分为:
1 function(sou-range)
算法的参数中只有源区间。
reverse:将元素倒置。
max_element:求区间最大值。
min_element:求区间最小值。
distance:求两个迭代器的距离
vector<int> m_vector = {1,2,3,4,5,6,9};
list<int> m_list = { 1,2,3,4,5,6,0};
reverse(m_vector.begin(), m_vector.end());
auto max= max_element(m_vector.begin(), m_vector.end());
cout << *max << endl;
auto min = min_element(m_vector.begin(), m_vector.end());
cout << *min << endl;
auto re = distance(m_vector.begin(), m_vector.end());
cout << re << endl;
2 function(sou-range,operation)
算法的参数对源区间进行操作.
find:查找opertion的值,成功返回该位置的迭代器,失败返回cend()的迭代器。
remove:删除opertion的值,实际并没有删除,只是用后面的值覆盖了。如在容器1,2,3,4,5删除4,后结果为:1,2,3,5,5.成功返回该位置的迭代器,失败返回cend()的迭代器。
for_each:每个元素执行operation
find_if:每个元素执行判断式直到返回true为止,失败则返回cend()
auto find_value=find(m_vector.cbegin(), m_vector.cend(), 7);
cout << *find_value << endl;//若为cend则报错。
auto re=remove(m_vector.begin(), m_vector.end(), 3);
copy(m_vector.begin(), m_vector.end(), ostream_iterator<int>(cout, " "));
cout << endl;
copy(m_vector.begin(),re, ostream_iterator<int>(cout, " "));
m_vector.erase(re, m_vector.end());
cout << endl;
copy(m_vector.begin(), m_vector.end(), ostream_iterator<int>(cout, " "));
也可以一步完成删除容器中的3.
m_vector.erase(remove(m_vector.begin(), m_vector.end(), 3), m_vector.end());
operation的多样性
1使用函数作为operation
void print(int& elem)
{
cout << ++elem << endl;
}
int main()
{
vector<int> m_vector = {1,2,3,4,5,6,9};
for_each(m_vector.begin(), m_vector.end(), print);
}
2使用判断式作为operation
判断式是一种特殊的辅助函数,它会返回bool值常用来作为排序准则或者查找准则。
bool is_ou(int elem)
{
if (elem & 1)
return true;
return false;
}
int main()
{
vector<int> m_vector = {1,3,5,7,8,9};
list<int> m_list ;
auto re= find_if(m_vector.cbegin(),m_vector.cend(),is_ou);
}
3使用Lambda作为operation
int main()
{
vector<int> m_vector = {1,3,5,7,8,9};
list<int> m_list ;
auto re= find_if(m_vector.cbegin(),m_vector.cend(),[](int elem){
if (elem & 1)
return true;
return false;
});
}
4使用函数对象作为operation
传递给算法的不一定是函数,也可以是行为类似函数的对象,称为函数对象或者防函数。
class test
{
public:
void operator()(int elem)
{
cout << elem << endl;
}
test() {};
~test() {};
private:
};
int main()
{
vector<int> m_vector = { 1, 2, 3, 4, 5 };
for_each(m_vector.begin(),m_vector.end(),test());
}
5使用预定义的函数对象作为operation
标准库中有很多预定的函数对象,如operation <默认的排序准则为调用less<>,所以当申明 set<int>coll时候,默认扩展为set<int,less<int>>coll.使用预定义的函数对象,需要包含#include<functional>
negate():将每个元素取为负数。
vector<int> m_vector = { 1, 2, 3, 4, 5 };
list<int> m_list;
transform(m_vector.begin(),m_vector.end(),back_inserter(m_list),negate<int>());
copy(m_list.begin(), m_list.end(),ostream_iterator<int>(cout," "));
6 使用函数适配器作为operation
可以使用binder将函数对象和其他数值结为一体。
replace_if:将区间中,为5的元素替换为10.
vector<int> m_vector = { 1, 2, 3, 4, 5 };
replace_if(m_vector.begin(),m_vector.end(),bind(equal_to<int>(),std::placeholders::_1,5),10);
copy(m_vector.begin(), m_vector.end(),ostream_iterator<int>(cout," "));
3 function(sou-range,dis-range)
处理多重区间时候,目标区间的容器的元素个数至少要等于源区间的个数。==若小于,可以调用成员函数修改大小或者采用安插型迭代器。
equal:判断源区间和目标区间的元素是否相等。相等返回true,否则返回false
copy:将源区间拷贝到目标区间
bool re= equal(m_vector.begin(), m_vector.end(), m_list.begin())
copy(m_vector.begin(), m_vector.end(), m_list.begin());
4 function(sou-range,dis-range,operation)
transform:将将源区间的每个元素调用operation函数,函数返回值再插入目标区间
int trans(int elem)
{
return elem*elem;
}
int main()
{
vector<int> m_vector = {1,2,3,4,5,6,9};
list<int> m_list ;
transform(m_vector.begin(),m_vector.end(),back_inserter(m_list),trans);
copy(m_list.begin(), m_list.end(), ostream_iterator<int>(cout, " "));
system("pause");
}