• C++泛型编程(2)--通过排序和查找元素理解迭代器


    许多C++开源库(stl,opencv,ros和blas等)都使用了大量的泛型编程的思想,如果不理解这些思想,将很难看懂代码,而《泛型编程与STL》一书对理解泛型编程思想非常的有帮助,这里整理第二章的一些实现代码。

    1.排序元素

    #include <iostream>
    #include <vector>
    #include <algorithm>
    #include <ostream>
    #include <iterator>
    using namespace std;
    
    int main(int argc, char** argv)
    {
      vector<string> V;
      string tmp;
    
      while (getline(cin, tmp))
      {
        if (tmp == "")
          break;  // 回车结束
        V.push_back(tmp);
      }
      // sort(V.begin(), V.end());// 升序
      sort(V.begin(), V.end(), greater<string>());  // 降序
      copy(V.begin(), V.end(), ostream_iterator<string>(cout, "
    "));
      return 0;
    }

    运行结果

    输入:
    1
    2
    3
    4
    5
    6
    7
    
    排序输出:
    7
    6
    5
    4
    3
    2
    1

    2.查找元素

    #include <string.h>
    #include <iostream>
    #include <vector>
    #include <algorithm>
    #include <ostream>
    #include <iterator>
    using namespace std;
    
    // 通常的查找方法,通过''来结束查找
    char* strchr(char *s, int c)
    {
      while (*s != '' && *s != c)
      {
        ++s;
      }
      return *s == c ? s : (char*) 0;  // #define NULL (char*) 0
    }
    
    // C 改进版本的查找方法,引入了range的概念[first, last),
    // 通过比较指针first = last来结束查找
    char* find1(char* first, char* last, int value)
    {
      while (first != last && *first != value)
        ++first;
      return first;
    }
    
    // C++ 模板方法查找,数据类型作为模板参数传入
    template<class T>
    T* find2(T* first, T* last, T value)
    {
      while (first != last && *first != value)
        ++first;
      return first;
    }
    
    // C++ 模板方法查找,访问器和数据类型都作为模板参数传入,
    // 相较于find2,find具有更一般性。其很好地解决了以下问题:
    // 1.审视元素;2.移动到下一个元素;3.检查是否已经处理完成所有元素;4.元素比较
    template<class Iterator, class T>
    Iterator find3(Iterator first, Iterator last, const T& value)
    {
      while (first != last && *first != value)
      {
        ++first;
      }
      return first;
    }
    
    // 链表查找
    struct int_node
    {
      int value;
      int_node* next;
    };
    
    // 链表无法满足 操作符的比较,因此通过一个外覆类实现++ == ->等操作符号的重载
    template<class Node>
    struct node_wrapper
    {
      Node* ptr;
      node_wrapper(Node* p = 0)
          : ptr(p)
      {
      }
      // *
      Node& operator *() const
      {
        return *ptr;
      }
      // 访问->
      Node* operator ->() const
      {
        return ptr;
      }
      // 前置累加
      node_wrapper operator++()
      {
        ptr = ptr->next;
    
        return *this;
      }
      // 后置累加
      node_wrapper operator ++(int)
      {
        node_wrapper tmp = *this;
        ++*this;
        return tmp;
      }
      // 相等判断
      bool operator ==(const node_wrapper& i) const
      {
        return ptr == i.ptr;
      }
      // 非相等判断
      bool operator !=(const node_wrapper& i) const
      {
        return ptr != i.ptr;
      }
    };
    
    // template funtion, object function
    template<class Node, class T>
    bool operator !=(const Node& node, T value)
    {
      if (node.value != value)
        return true;
      return false;
    }
    
    int main(int argc, char** argv)
    {
      char pat = 'x';
      char str[10] = "horsetail";
      int str_size = strlen(str);
    
      cout << "****Task1: to find '" << pat << "' from "" << str << """ << endl;
    
      // 通常的查找方法,通过''来结束查找
      cout << "----testing strchr----" << endl;
      char* res = strchr(str, (int) pat);  // to find
      if (res != NULL)
        cout << "found " << pat << endl;
      else
        cout << "not found " << pat << endl;
    
      // C 改进版本的查找方法,引入了range的概念[first, last),
      // 通过比较指针first = last来结束查找
      cout << "----testing find1----" << endl;
      res = find1(str, str + str_size, (int) pat);  // to find
      if (res != str + str_size)
        cout << "found " << pat << endl;
      else
        cout << "not found " << pat << endl;
    
      // C++ 模板方法查找,数据类型作为模板参数传入
      cout << "----testing find2----" << endl;
      res = find2(str, str + str_size, pat);  // to find
      if (res != str + str_size)
        cout << "found " << pat << endl;
      else
        cout << "not found " << pat << endl;
    
      // C++ 模板方法查找,访问器和数据类型都作为模板参数传入,
      // 相较于find2,find具有更一般性。其很好地解决了以下问题:
      // 1.审视元素;2.移动到下一个元素;3.检查是否已经处理完成所有元素;4.元素比较
      cout << "----testing find3----" << endl;
      res = find3(str, str + str_size, pat);  // to find
      if (res != str + str_size)
        cout << "found " << pat << endl;
      else
        cout << "not found " << pat << endl;
    
      // 链表查找,链表无法满足 操作符的比较,因此通过一个外覆类实现++ == ->等操作符号的重载
      int value = 6;
      int link_size = 10;
      cout << endl;
      cout << "****Task2: to find " << value << " from {0,1,2,3,...,10}" << endl;
      cout << "----testing link int_node with find3----" << endl;
      int_node* head_node = new int_node();
      head_node->value = 0;
      head_node->next = 0;
      int_node* pnode = head_node;
      for (int i = 1; i < link_size; i++)
      {// link contain {0,1,2,3,4,5,6,...}
        int_node* node = new int_node();
        node->value = i;
        node->next = 0;
    
        pnode->next = node;
        pnode = node;
      }
    
      node_wrapper<int_node> first(head_node);
      node_wrapper<int_node> last(0);
      node_wrapper<int_node> result = find3(first, last, value);  // to find
      if (result != last)
        cout << "found " << value << endl;
      else
        cout << "not found " << value << endl;
    
      return 0;
    }

    运行结果

    ****Task1: to find 'x' from "horsetail"
    ----testing strchr----
    not found x
    ----testing find1----
    not found x
    ----testing find2----
    not found x
    ----testing find3----
    not found x
    
    ****Task2: to find 6 from {0,1,2,3,...,10}
    ----testing link int_node with find3----
    found 6

    参考资料

    [1].泛型编程与STL 侯捷 - 2003 - 中国电力出版社,第二章

  • 相关阅读:
    RvmTranslator7.4.1-Clipping Box
    使用K-means和高斯混合模型对图像进行聚类
    Python小技巧
    利用SNAP软件进行Sentinel-1A卫星微波影像的预处理
    VScode编译C,头文件显示not found的解决方法
    深浅拷贝
    CSRF攻击:陌生链接不要随便点
    跨站脚本攻击(XSS)
    同源策略:为什么XMLHttpRequest不能跨域请求资源?
    HTTP/2:如何提升网络速度
  • 原文地址:https://www.cnblogs.com/cv-pr/p/7777872.html
Copyright © 2020-2023  润新知