泛型算法

泛型算法:

1、STL类库中提供的一些通用的 非成员函数操作。算法是STL的苦力,是处理容器里面数据的方法,操作。 这些算法可以操作在多种容器类型上,所以称为“泛型”, 泛型算法不是针对容器编写,而只 是单独依赖迭代器和迭代器操作实现。

2、使用泛型算法必须先包含algorithm头文件,使用泛化的算术算法则必须包含numeric头文件:
  #include <algorithm>
  #include <numeric>



算法分类:
1、STL将算法库分为4组,前3个在#include<algorithm>头文件中描述,而第4个在#include<numeric>头文件中描述:
1、非修改式序列操作:不改变容器的内容,如 find()、for_each() 等。
2、修改式序列操作:可以修改容器中的内容,如 transform()、random_shuffle()、copy 等。
3、排序和相关操作:包括各种排序函数等,如 sort() 等。
4、通用数字运算:计算两个容器的内部乘积等。
(1)非修改式序列操作
for_each():               将一个非修改式函数用于指定区间中的每个成员
find():                      在区间中查找某个值首次出现的位置
find_if():                  在区间中查找第一个满足断言测试条件的值
find_end():               在序列中查找最后一个与另一个序列匹配的值。匹配时可使用等式或二元断言
find_first_of():          在第二个序列中查找第一个与第一个序列的值匹配的元素。匹配时可使用等式或二元断言
adjacent_find():       查找第一个与其后面的元素匹配的元素。匹配时可使用等式或二元断言
count():                   返回特定值在区间中出现的次数
count_if():
mismatch():
equal():
search():
search_n():
(2)修改式序列操作
copy():
copy_backword():
swap():
swap_ranges():
iter_swap():
transform():
replace():
replace_if()
remove/remove_if
……
(3)排序和相关操作
sort():
stable_sort():
partial_sort():
nth_element():
lower_bound():
upper_bound():
equal_range():
……
(4)数字操作
accumulate():             计算区间中的值的总和
inner_product():          计算两个区间的内部乘积
partial_sum():              将使用一个区间计算得到的小计复制到另一个区间中
adjacent_different():    将使用一个区间的元素计算得到的相邻差集复制到另一个区间中


#include <iostream>
#include <vector>
#include <algorithm>       //算法是处理容器中的元素的
using namespace std;
void print(vector<int>::value_type & v)     //定义一元函数print,以容器中的元素类型为参数
{
        v+=2;        //传递的是元素引用,会修改容器中的元素值
        cout<<v<<"  ";
}
int main()
{
        vector<int> vecInt = {1,2,3,4,5,6};
        for_each(vecInt.begin(), vecInt.end(), print);     //对vecInt中所有元素执行print操作
        cout<<endl;

        return 0;
}

//对于for_each而言,如果是vector<int> ob;这样的,此时调用for_each(ob.begin(), ob.end(), func);函数的时候,
//func函数的参数是int(或vector<int>::value_type)
//如果是map<int, string> obM;这样的,此时调用for_each(obM.begin(), obM.end(), func);函数的时候,
//func函数的参数是pair<int, string>这种数据类型的。
//总结:对于for_each的第三个参数而言,写函数的时候,函数的参数就是其中的迭代器指向的类型。
//对于vector<CMyString> 则是CMyString
//对于map<CMyString, string>则是由CMyString和string组成的,所以是pair<CMyString, string>
#include <iostream>
#include <algorithm>
#include <functional>     //使用less<>类模板要用的头文件
#include <vector>
using namespace std;
int main()
{
        vector<int> vecInt = {1,2,3,4,5,6};
        less<int> lt;    //创建less<int>类函数对象; 这个是重载了()操作符的类对象
        replace_if(vecInt.begin(),vecInt.end(),bind1st(lt,3),7);    //把vecInt中大于三的元素全部换成7
        for(auto & elem : vecInt)
                cout<< elem <<" ";
        cout<<endl<<"------------------------------"<<endl;
        vector<int> vecInt1 = {1,2,3,4,5,6};
        replace_if(vecInt1.begin(),vecInt1.end(),bind2nd(lt,3),7);    //把vecInt中小于3的元素全部换成7
        for(auto & elem : vecInt1)
                cout<< elem <<" ";
        cout<<endl;
        return 0;
}



#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
        vector<string> vecStr;
        vecStr.push_back("hello");
        int i=0;
        auto it=vecStr.begin();    //自动推断出这个变量的合理的数据类型而无需我们人为指定
        //迭代器失效
        for(; it != vecStr.end(); ++it)
        {
                cout<<"vecStr.capacity is :"<<vecStr.capacity() <<endl;
                cout<< *it <<endl;   
 //上次push操作指针位置改变,迭代器到这里找不到地址,也就不能解引用
                if(0==i)
                {
                        vecStr.push_back("world");    //底层做了扩容的操作,迭代器it已经失效
                        cout<<"vecStr.push!"<<endl;
                        i=1;
                }
        }
}
这里的扩容不是在原有空间的基础上容量增加,而是从新申请一个更大的空间,然后把旧空间的内容拷贝到新申请的空间,释放原来的空间,所以迭代器遍历的时候扩容,迭代器++就找不到我们要找的内容,直接段错误
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
        vector<int> vecInt;
        vecInt.reserve(10);
        cout<< vecInt.size() <<endl;
        cout<< vecInt.capacity() <<endl;
        for(int idx = 1;idx <=10; ++idx)
        {
                vecInt.push_back(idx);
        }
        vecInt[3] = vecInt[5] = vecInt[9] = 99;
        for(auto & elem :vecInt)
                cout<< elem << " ";
        cout<<endl;
        remove(vecInt.begin(),vecInt.end(),99);
 //用指针指向的值是要删除的99的时候,再定义一个指针在容器后面寻找第一个不为99的元素,并替换当前的99,然后两个指针都向前+1
        for(auto & elem :vecInt)
                cout<< elem << " ";
        cout<<endl;

}

此时的first不一定在最后一个元素位置


#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
        vector<int> vecInt;
        for(int idx = 1;idx <= 10; ++idx)
                vecInt.push_back(idx);
        vecInt[3] = vecInt[5] =vecInt[9] = 99;
        for(auto & elem : vecInt)
                cout<< elem <<" ";
        cout<<endl;
        cout<<"------删除后------"<<endl;
        //erase-remove 惯用法 --> 防止出现迭代器失效问题
        vecInt.erase(remove(vecInt.begin(),vecInt.end(),99),vecInt.end()); 
     //remove操作返回的是一个指针位置
        for(auto & elem : vecInt)
                cout<< elem <<" ";
        cout<<endl;
        return 0;
}




猜你喜欢

转载自www.cnblogs.com/meihao1203/p/9034412.html