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 ...
随机推荐
- concurrent.futures- 启动并行任务
python因为其全局解释器锁GIL而无法通过线程实现真正的平行计算.这个论断我们不展开,但是有个概念我们要说明,IO密集型 vs. 计算密集型. IO密集型:读取文件,读取网络套接字频繁. 计算密集 ...
- 故障 -> nginx启动失败
描述:在用saltstack给 minion 安装 nginx 服务 时 提示 nginx 服务下载成功,但是启动失败. ---------- ID: nginx-systemctl Function ...
- vim使用案例
1. 请在 /tmp 这个目录下建立一个名为 vitest 的目录: 2. 进入 vitest 这个目录当中: 3. 将 /etc/man.config 复制到本目录底下(或由上述的连结下载 man. ...
- JS/Jquery版本的俄罗斯方块(附源码分析)
转载于http://blog.csdn.net/unionline/article/details/63250597 且后续更新于此 1.前言 写这个jQuery版本的小游戏的缘由在于我想通过从零到有 ...
- 无法下载apk等格式的文件的解决方案---ASP .NET Core 2.0 MVC 发布到IIS上以后无法下载apk等格式的文件的解决方案
ASP .NET Core MVC 发布到 IIS 上以后 无法下载apk等格式的文件 使用.NET Core MVC创建了一个站点,其他文件可以下载,但是后来又需求,就把手机端的apk合适的文件上 ...
- C#中decimal ,double,float的区别
浮点型 Name CTS Type Description Significant Figures Range (approximate) float System.Single 32-bit sin ...
- centos7 编译安装php 5.6
https://www.cnblogs.com/37yan/p/6879404.html
- springbank 开发日志 SpringMVC是如何找到handler找到对应的方法并执行的
从DispatcherServlet说起,本文讨论的内容都是DispatcherServlet的doDispatch方法完成 mappedHandler是一个HandlerExecutionChain ...
- HTML5游戏 围住神经猫 开发
所有文章搬运自我的个人主页:sheilasun.me 去年风靡微信朋友圈的小游戏"围住神经猫",我也试着做了一下,可以戳这里试玩→围住神经猫.游戏是用Egret引擎开发的,因为Eg ...
- [Wc]Dface双面棋盘()
题解: 一道维护奇怪信息的线段树... 我刚开始看了标签想的是删去图上一个点后求连通性 发现不会 于是退化成一般图支持删除 插入 维护连通性 发现有2两种做法 1.lct维护 按照结束顺序先后排序,给 ...