• STL——泛型编程


    1、指针的算术运算
    对于一个存储int数据的vector,我们要查找某值是否存在于其中,采用下标操作的做法如下:
    int* find(const vector<int> &vec, int value)
    {
    for(int i = 0; i < vec.size(); i++)
    {
    if(vec[i] == value)
    return &vec[i];
    }
    return 0;
    }

    此函数对于存储int型数据的vector实用,但是如果对于其他类型的数据呢?为了达到这个目的,我们使用function template的形式:
    template <typename elemType>
    elemType* find(const vector<elemType> &vec, const elemType &value)
    {
    for(int i = 0; i < vec.size(); i++)
    {
    if(vec[i] == value)
    return &vec[i];
    }
    return 0;
    }


    现在,新任务出现了,我们需要让这样一个函数能处理vector和array的元素。对于这个问题,我们的解决办法是,传参容器中的元素而不是指明的容器。
    对于array,要传入容器中的元素,可以使用array的首尾元素的指针,即:
    template <typename elemType>
    elemType* find(const elemType *first, const elemType *last, const elemType &value)
    {
    if(!first || !last)
    return 0;
    for(;first != last; first++)
    {
    if(*first == value)
    return first;
    }
    return 0;
    }


    对于vector,由于其为连续存储结构,同样可以使用此方式,传入容器的首尾元素指针:
    vector<string> svec;
    find(&svec[0], &svec[svec.size()], search_value);   //当然,首先得保证vector不为空,这里不做多的描述


    到此为止,我们可以使用同样的find函数来查找vector和array中的指定元素了,但是此时,又有个新任务,需要find支持list的元素查找。因为list不是连续存储的,所以在find函数体内,就不能使用指针的++运算来获取下一个元素的地址了。

    为了解决这个问题,我们在指针的行为之上提供一层抽象化机制,这个机制可以屏蔽掉vector和list的指针操作行为,使用户在find中看不到指针的操作,从而看到vector和list的操作一样,这样就可以将find函数应用于所有的容器类。


    2、Iterators(泛型指针)
    这层抽象化机制,即iterator类,跟指针的操作类似,主要提供运算有:++,*,==,!=
    定义这样一个类,我们需要知道两个信息
    (1)迭代对象类型(即容器类型),这可以决定怎么存取下一个元素
    (2)迭代器指向的元素类型,决定*(取值,类似指针的*)操作的返回值
    例如:
    vector<string>::iterator iter;   //iter为vector容器类型的迭代器,指向的元素类型为string类型。
    “;;”符号标识迭代器为容器类中的嵌套类型。


    那么现在的find函数为:
    template <typename IteratorType, typename elemType>
    elemType* find(IteratorType first, IteratorType last, const elemType &value)
    {
    for(;first != last; first++)
    {
    if(*first == value)
    return first;
    }
    return last;
    }


    此版本的find函数还不够弹性,原因在于,传入的elemType类型value并不一定支持“==”运算。这个问题的解决办法在于,传入一个函数指针,利用这个函数指针调用的函数来判断,从而取代“==”。这种方法将在后面介绍。


    3、泛型算法函数
    头文件:#include<algorithm>
    搜索算法:find(),count(),adjacent_find(),find_if(),count_if(),binary_search(),find_first_of().
    排序算法:merge(),partial_sort(),partition(),random_shuffle(),reverse(),rotate(),sort().
    复制删除替换算法:copy(),remove(),remove_if(),replace(),replace_if(),swap(),unique().
    关系算法:equal(),includes(),mismatch().
    生成与质变算法:fill(),for_each(),generate(),transform().
    数值算法:accmulate(),adjacent_difference(),partial_sum(),inner_product().
    集合算法:set_union(),set_difference().




    4、设计一个泛型算法


    需求:找出一组数据中小于10的数
    首先想到的算法就是将这组数据中的每个数与10对比,然后满足条件的存储起来。然而,如果需求改变为小于11或者大于10,那么原来的函数就不能用了,所以考虑到这个问题,实现如下算法:
    bool less_than(int num1, int num2)
    {
    return num1 < num2 ? True : False;
    }


    bool greater_than(int num1, int num2)
    {
    return num1 > num2 ? True : False;
    }


    vector<int> filter(const vector<int> &vec, int filter_value, bool (*judge)(int, int))
    {
    vector<int> vecRe;
    vector<int>::iterator itBegin = vec.begin();
    vector<int>::iterator itEnd = vec.end();


    for(;itBegin != itEnd; itBegin++)
    {
    if(judge(*itBegin, filter_value))
    {
    vecRe.push_back(*itBegin);
    }
    }


    return vecRe;
    }
    当然,还可以使用template实现更加泛型的方法,并且使用function object替代函数指针来提高效率,这里就不讨论了。
  • 相关阅读:
    iPhone控件之UIWebView2
    Xcode 4.1/4.2 免证书(iDP)开发+真机调试
    iPhone控件之UIToolbar
    POJ 2472 ||SDUT 2358 106 miles to Chicago(Dijkstra算法变形)
    POJ 2418 Hardwood Species(二叉排序树)
    POJ 2513 Colored Sticks(字典树 + 并查集 + 欧拉回路)
    HDU 4033 Regular Polygon(几何 + 二分)
    POJ 3191 The Moronic Cowmpouter(二进制的变形)
    POJ 2442 Sequence(堆的应用)
    HDU 4036 Rolling Hongshu(数学+物理应用)
  • 原文地址:https://www.cnblogs.com/fangyan5218/p/10618261.html
Copyright © 2020-2023  润新知