许多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, "\n"));
return ;
}

运行结果

输入:

排序输出:

2.查找元素

#include <string.h>
#include <iostream>
#include <vector>
#include <algorithm>
#include <ostream>
#include <iterator>
using namespace std; // 通常的查找方法,通过'\0'来结束查找
char* strchr(char *s, int c)
{
while (*s != '\0' && *s != c)
{
++s;
}
return *s == c ? s : (char*) ; // #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 = )
: 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[] = "horsetail";
int str_size = strlen(str); cout << "****Task1: to find '" << pat << "' from \"" << str << "\"" << endl; // 通常的查找方法,通过'\0'来结束查找
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 = ;
int link_size = ;
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 = ;
head_node->next = ;
int_node* pnode = head_node;
for (int i = ; i < link_size; i++)
{// link contain {0,1,2,3,4,5,6,...}
int_node* node = new int_node();
node->value = i;
node->next = ; pnode->next = node;
pnode = node;
} node_wrapper<int_node> first(head_node);
node_wrapper<int_node> last();
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 ;
}

运行结果

****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 from {,,,,...,}
----testing link int_node with find3----
found

参考资料

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

C++泛型编程(2)--通过排序和查找元素理解迭代器的更多相关文章

  1. 类 java.util.Collections 提供了对Set、List、Map进行排序、填充、查找元素的辅助方法。

      类 java.util.Collections 提供了对Set.List.Map进行排序.填充.查找元素的辅助方法. 1. void sort(List) //对List容器内的元素排序,排序的规 ...

  2. vector向量容器元素排序与查找

    1.利用标准库函数sort()对vector进行排序 参考源码: #include <algorithm> #include <vector> vector<int> ...

  3. Leetcode算法【34在排序数组中查找元素】

    在之前ARTS打卡中,我每次都把算法.英文文档.技巧都写在一个文章里,这样对我的帮助是挺大的,但是可能给读者来说,一下子有这么多的输入,还是需要长时间的消化. 那我现在改变下方式,将每一个模块细分化, ...

  4. Java实现 LeetCode 34 在排序数组中查找元素的第一个和最后一个位置

    在排序数组中查找元素的第一个和最后一个位置 给定一个按照升序排列的整数数组 nums,和一个目标值 target.找出给定目标值在数组中的开始位置和结束位置. 你的算法时间复杂度必须是 O(log n ...

  5. 【Java实现】剑指offer53.1——在排序数组中查找数字(LeetCode34:在排序数组中查找元素的起始位置)

    序数组中查找元素的起始位置):思路分享 <剑指offer>题目和LeetCode主站本质是一样的,想要找到target数目,也需要找到左右边界 题目解析: 在一个排序数组中,找到targe ...

  6. 【LeetCode】34. 在排序数组中查找元素的第一个和最后一个位置

    34. 在排序数组中查找元素的第一个和最后一个位置 知识点:数组,二分查找: 题目描述 给定一个按照升序排列的整数数组 nums,和一个目标值 target.找出给定目标值在数组中的开始位置和结束位置 ...

  7. 34、在排序数组中查找元素的第一个和最后一个位置 | 算法(leetode,附思维导图 + 全部解法)300题

    零 标题:算法(leetode,附思维导图 + 全部解法)300题之(34)在排序数组中查找元素的第一个和最后一个位置 一 题目描述 二 解法总览(思维导图) 三 全部解法 1 方案1 1)代码: / ...

  8. Golang的排序和查找

    Golang的排序和查找 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.排序的基本介绍 排序是将一组数据,依指定的顺序进行排列的过程.排序的分类如下 1>.内部排序 指将 ...

  9. C/C++中的排序和查找

    以下内容来自<C/C++程序设计实用案例教程> 1.排序 1.1使用qsort函数 C/C++库函数提供了快速排序函数qsort(q时quick的简写),需要引入头文件<stdlib ...

随机推荐

  1. bootstrap 的媒体查询

    有时候需要对bootstap的样式自定义,比如说某个元素的“height”值,要放在与bootstrap媒体查询同步的样式里,才会兼容响应式布局. .container类是bootstrap的官方参考 ...

  2. Json对象和字符串互相转换 数据拼接 JSON使用方式

    JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式. 一.JSON字符串转换为JSON对象: eval() 和 JSON.parse eg- json字符串: ...

  3. Ex 5_33 实现一个关于公式长度(其中所有文字总的出现次数)为线性时间的Horn公式可满足性问题_第十次作业

    对于所有的蕴含式,生成一张有向图,对于每一个蕴含式,将左边的每一个文字连接到一个中间结点,并用中间结点记录蕴含式左边文字的数量,然后将中间结点连接到蕴含式的右侧结点.例如,对于蕴含式集合 生成的有向图 ...

  4. PYTHON-绑定方法 反射 内置函数

    '''绑定方法类中定义函数分为了两大类: 1. 绑定方法 特殊之处: 绑定给谁就应该由谁来调用,谁来调用就会将谁当做第一个参数自动传入 如何用: 绑定给对象的方法: 在类中定义函数没有被任何装饰器修饰 ...

  5. VSCode配置python调试环境

    VSCode配置python调试环境 很久之前的一个东东,翻出来看看 VSCode配置python调试环境 * 1.下载python解释器 * 2.在VSCode市场中安装Python插件 * 4.在 ...

  6. PreparedStatement setDate setTimestamp ,util.date sql.date区别

    如果数据库中是时分秒,那么切记,用setTimestamp 而不是 setDate(仅仅精确是天,不含时分秒)

  7. hdu1698

    /*区间更新*/#include <cstdio> #include <algorithm> using namespace std; #define lson l , m , ...

  8. python接口自动化测试九:重定向相关

    allow_redirects=False  不重定向 # 获取重定向后的地址 loc = r.headers # 相对地址 host = 'https://i.cnblogs.com/' url = ...

  9. Zookeeper简介(一)

    使用Zookeeper已经有几年时间了,零零散散的积累了一些经验,但从未想过能写出一些列的文章分享出来.从今天起,计划持续更新关于Zookeeper相关的文章,从基本的搭建使用.原理分析.典型场景分析 ...

  10. Redis、RabbitMQ、Memcached

    知识目录: Memcached Redis RabbitMQ Memcached 回到顶部 Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中 ...