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 ...
随机推荐
- SQL Server 触发器demo
GO /****** Object: Trigger [dbo].[tri_device] Script Date: 2018/6/11 10:56:08 ******/ SET ANSI_NUL ...
- PYTHON-基本数据类型-数字类型,字符串类型,列表类型-练习
# 字符串练习# 写代码,有如下变量,请按照要求实现每个功能 (共6分,每小题各0.5分)# name = " aleX"# # 1) 移除 name 变量对应的值两边的空格,并输 ...
- 1. let 和 const 命令
一.简单认识 1. 用let来声明变量,变量作用域就在{}(块级作用域)中 2. 用const声明变量,变量值不可更改 3. 增加了let以后,在声明变量时应该多考虑一下变量的用途,是否希望只在当前代 ...
- 使用navicat premium将数据库从Oracle迁移到SQL Server,或从Oracle迁移到MySQL
有时候我们有迁移数据库的需求,例如从Oracle迁移到SQL Server,或者从MySQL迁移到Oracle. 很多江湖好汉一时不知如何手工操作,所幸的是Navicat提供了迁移的自动化操作界面. ...
- CCF2016093炉石传说(C语言版)
问题描述 <炉石传说:魔兽英雄传>(Hearthstone: Heroes of Warcraft,简称炉石传说)是暴雪娱乐开发的一款集换式卡牌游戏(如下图所示).游戏在一个战斗棋盘上进行 ...
- cf789c
主要是线性时间内求最大连续和 #include<bits/stdc++.h> using namespace std; #define maxn 200005 #define ll lon ...
- python 全栈开发,Day2(in,while else,格式化输出,逻辑运算符,int与bool转换,编码)
一.in的使用 in 操作符用于判断关键字是否存在于变量中 a = '男孩wusir' print('男孩' in a) 执行输出: True in是整体匹配,不会拆分匹配. a = '男孩wusir ...
- 【C++ Primer 第16章】1. 定义模板 (一)
类模板 #include<iostream> #include<vector> #include<memory> using namespace std; temp ...
- 【C++ Primer 第11章 练习答案】2. 关联容器操作
11.3.1节练习 [练习11.16]代码 map<int, int> m; auto iter = m.begin(); iter ->second = ;
- TopCoder FlowerGarden【拓扑排序】
https://community.topcoder.com/stat?c=problem_statement&pm=1918&rd=5006拓扑排序,每次选择最大的就好了 #incl ...