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, "\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)--通过排序和查找元素理解迭代器的更多相关文章
- 类 java.util.Collections 提供了对Set、List、Map进行排序、填充、查找元素的辅助方法。
类 java.util.Collections 提供了对Set.List.Map进行排序.填充.查找元素的辅助方法. 1. void sort(List) //对List容器内的元素排序,排序的规 ...
- vector向量容器元素排序与查找
1.利用标准库函数sort()对vector进行排序 参考源码: #include <algorithm> #include <vector> vector<int> ...
- Leetcode算法【34在排序数组中查找元素】
在之前ARTS打卡中,我每次都把算法.英文文档.技巧都写在一个文章里,这样对我的帮助是挺大的,但是可能给读者来说,一下子有这么多的输入,还是需要长时间的消化. 那我现在改变下方式,将每一个模块细分化, ...
- Java实现 LeetCode 34 在排序数组中查找元素的第一个和最后一个位置
在排序数组中查找元素的第一个和最后一个位置 给定一个按照升序排列的整数数组 nums,和一个目标值 target.找出给定目标值在数组中的开始位置和结束位置. 你的算法时间复杂度必须是 O(log n ...
- 【Java实现】剑指offer53.1——在排序数组中查找数字(LeetCode34:在排序数组中查找元素的起始位置)
序数组中查找元素的起始位置):思路分享 <剑指offer>题目和LeetCode主站本质是一样的,想要找到target数目,也需要找到左右边界 题目解析: 在一个排序数组中,找到targe ...
- 【LeetCode】34. 在排序数组中查找元素的第一个和最后一个位置
34. 在排序数组中查找元素的第一个和最后一个位置 知识点:数组,二分查找: 题目描述 给定一个按照升序排列的整数数组 nums,和一个目标值 target.找出给定目标值在数组中的开始位置和结束位置 ...
- 34、在排序数组中查找元素的第一个和最后一个位置 | 算法(leetode,附思维导图 + 全部解法)300题
零 标题:算法(leetode,附思维导图 + 全部解法)300题之(34)在排序数组中查找元素的第一个和最后一个位置 一 题目描述 二 解法总览(思维导图) 三 全部解法 1 方案1 1)代码: / ...
- Golang的排序和查找
Golang的排序和查找 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.排序的基本介绍 排序是将一组数据,依指定的顺序进行排列的过程.排序的分类如下 1>.内部排序 指将 ...
- C/C++中的排序和查找
以下内容来自<C/C++程序设计实用案例教程> 1.排序 1.1使用qsort函数 C/C++库函数提供了快速排序函数qsort(q时quick的简写),需要引入头文件<stdlib ...
随机推荐
- oracle 回退表空间清理
1.查看已有表空间,找到回退表空间 SELECT * FROM DBA_TABLESPACES WHERE CONTENTS='UNDO' 2.创建新的回退表空间 create undo tables ...
- haproxy配置基于ssl证书的https负载均衡
本实验全部在haproxy1.5.19版本进行测试通过,经过测试1.7.X及haproxy1.3版本以下haproxy配置参数可能不适用,需要注意版本号. 一.业务要求现在根据业务的实际需要,有以下几 ...
- activit流程引擎启动流程报错
代码如下: 目录结构 ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); @Test public void ...
- 分布式调用技术 RPC VS REST
一 分布式调用大体上就分为两类,RPC式的,REST式的,两者的区别主要是就是: 1. RPC是面向动作的(方法调用) 2. REST是面向资源的(URL表示资源,HTTP动词表示动作) 从变现形式来 ...
- 获取修改value
val() 方法,获取和修改有value属性的元素,有value属性的元素有input.botton.select等.相当于JavaScript中的value. <!DOCTYPE html&g ...
- Ext.js入门:Window对象与FormPanel(六)
一:Ext.Window类 二:Ext.Window类实例 三:Ext.FormPanel类 四:Ext.FormPanel类实例 1.类Ext.Window 包: Ext 定义的文件 Windo ...
- ElasticSearch - How to search for a part of a word with ElasticSearch
Search a part of word with ElasticSearch 来自stackoverflow https://stackoverflow.com/questions/6467067 ...
- [转] 理解Web路由
1. 什么是路由 在Web开发过程中,经常会遇到『路由』的概念.那么,到底什么是路由?简单来说,路由就是URL到函数的映射. 2. router和route的区别 route就是一条路由,它将一个UR ...
- ThreadLocal、Volatile、synchronized、Atomic
前言 对于ThreadLocal.Volatile.synchronized.Atomic这四个关键字,我想一提及到大家肯定都想到的是解决在多线程并发环境下资源的共享问题,但是要细说每一个的特点.区别 ...
- 关于C#资源文件的相关操作
关于资源文件的相关操作. //1.比较常见的有获取资源文件对应的文件流,然后转换到相对应的文件 //比较典型的做法是通过代码程序集加载指定资源 //如下通过Assembly的静态方法GetExecut ...