IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 人工智能 -> (十二)迭代器的分类 -> 正文阅读

[人工智能](十二)迭代器的分类

标准库算法

  • 从语言层面来看
    • 容器Container是class template
    • 算法Alogorithm是function template
    • 迭代器Iterator是class template
    • 仿函数Functor是class template
    • 适配器Adapter是class template
    • 分配器Allocator是class template
  • 算法看不到迭代器,它所需要的一切信息都必需从Iterstor取得,而迭代器必需能够回答算法的所有问题,才能搭配算法的所有操作
//同一个算法可能会有多个版本
//函数模板
template <typename Iterator>
Algorithm(Iterator itr1, Iterator itr2)
{
	...
}
//名称相同,参数不同,下例中第三个参数传入的是一个准则,是一个仿函数
template<typename Iterator, typename Cmp>
Algorithm(Iterator itr1, Iterator itr2, Cmp comp)
{
	...
}

迭代器的分类

  • array、vector、deque都是连续空间,迭代器允许跳跃前进,都是random_access_iterator_tag
  • list的迭代器可以双向移动,是bidirectional_iterator_tag
  • forward_list是单向链表,是farward_iterator_tag
  • 红黑树为底层实现的容器,迭代器都可以双向移动,是bidirectional_iterator_tag
  • 哈希表为底层实现的容器,根据bucket中的链表是单向链表还是双向链表,判断迭代器是bidirectional_iterator_tag还是farward_iterator_tag
//五种iterator catagory,其中有几种之间是继承关系
struct input_iterator_tag{ };
struct output_iterator_tag{ };
struct forward_iterator_tag: public input_iterator_tag { };
struct bidirectional_iterator_tag: public forward_iterator_tag{ };
struct random_access_iterator_tag: public bidirectional_iterator_tag{ };
  • 标准库的五种迭代器,为什么采取继承关系实现
    • 判断迭代器类型时可以使用函数重载,只要传入的是不同类型的参数,就会自动调用不同的函数
    • 采取继承关系实现,对于该类型的迭代器,如果没有它特定版本的算法,它会调用符合它父类版本的算法(如后例)
  • 如何打印迭代器的类型
  • 方法一:自定义版
-----------------------五种类型的函数重载---------------------------
void _display_category(random_access_iterator_tag)
{ cout<< "random_access_iterator" << endl;}
void _display_category(bidirectional_iterator_tag)
{ cout<< "bidirectional_iterator" << endl;}
void _display_category(forward_iterator_tag)
{ cout<< "forward_iterator" << endl;}
void _diaplay_category(output_iterator_tag)
{ cout<< "output_iterator" << endl;}
voif _display_category(input_iterator_tag)
{ cout<< "input_iterator" << endl;}

template<typename T>
void display_category(I itr)
{
	typename iterator_traits<I>::iterator_category cagy;
	_display_category(cagy);
}

-----------------------测试函数-------------------------------
display_category(array<int, 10>::iterator());//构建一个迭代器类型的临时对象
display_category(set<int>::iterator());
...
//可以说是一种适配器
display_category(istream_iterator<int>());
diaplay_category(ostream_iterator<int>(cout, ""));
  • 方法二:使用标准库提供的typeid
#include<typeinfo> //typeid
template<typename I>
void display_category(I itr)
{
	typename iterator_traits<I>::iterator_category cagy;
	_display_category(cagy);

	cout<<"typeid(ite).name()=" << typeid(itr).name()<<endl;
	//typeid传进去一个类型,得到一个对象,调用name函数得到它的类型
	//输出依赖于标准库的具体实现
	//返回的结果包含类型名以及一些编译过程中添加的东西,是有不同版本的实现来决定的
}

istream_iterator

  • 不同版本的实现不同,但是不能影响接口。即虽然模板参数的数量不一样,但是一些模板参数有默认值
  • 一个继承关系,父类只是一些typedef,没有数据也没有函数,这样子类继承父类,等同于子类拥有了这些typedef(相当于少打几个字hhh)
-----------------------G4.9----------------------------------
template<typename _Category, typename _Tp, typename _Distance = ptrdiff_t, typename _Pointer = _Tp*, typename _Reference = _Tp&>
struct iterator
{
	typedef _Category iterator_category;
	typedef _Tp value_type;
	typedef _Distance difference_type;
	typedef _Pointer pointer;
	typedef _Reference reference;
};

template<typename _Tp, typename _CharT = char, typename _Traits = char_traits<_CharT>,typename _Dist = ptrdiff_t>
class istream_iterator : public iterator<input_iterator_tag, _Tp, _Dist, const _Tp*, const _Tp&>
{
...
}

--------------------------G2.9----------------------------------
template<class T, class Distance = ptrdiff_t>
class istream_iterator{
public:
	typedef input_iterator_tag iterator_category;
	....
} 

---------------------------G3.3-------------------------------------
template<class _Tp, class _CharT = char, class _Traits = char_traits<_ChatT>, class _Dist = ptrdiff_t>
class istream_iterator{
public:
	typedef input_iterator_tag iterator_category;
	...
}

迭代器的类型对算法效率的影响

  • 示例一:distance
    • distance接受两个参数,求二者之间的距离
    • 这个函数会调用一个辅助函数,它有两个版本。一个是两个迭代器直接相减,仅适合于random_access_iterator,另一个是由first逐个数到last,适合于其余的迭代器
    • 这个函数的返回类型是difference_type,是迭代器的五种typedef中专门用来表示距离

在这里插入图片描述

  • 示例二:advance
    • advance传入两个参数,表示迭代器从当前位置前进n步
    • 这个函数调用一个辅助函数,它有三个版本。random_access_iterator可以直接到达新的位置。bidirectional_iterator_tag可以向前走也可以向后走,input_iterator_tag只能向前走
    • 辅助函数有三个参数,分别是迭代器,前进步数n,迭代器类型的临时对象

在这里插入图片描述

  • 示例三:copy
    • copy传入三个参数,前两个是表示待拷贝序列的区间,第三个是目的地址
    • copy先检查传进来的迭代器是哪种类型的,此处分了三种情况,两个特化版本直接调用memmove(),这是一种十分接近系统调用的函数。泛化版本又分了三种情况,具体如下图
    • trivial op=()是type traits,把类型放进去,问它一些问题,此处是问拷贝赋值是否重要,默认版本是不重要的,如复数,它没有指针,不需要自己写拷贝赋值函数。

在这里插入图片描述

  • 算法不会对迭代器类型强加限制,但是它会暗示算法需要的迭代器类型

在这里插入图片描述

  人工智能 最新文章
2022吴恩达机器学习课程——第二课(神经网
第十五章 规则学习
FixMatch: Simplifying Semi-Supervised Le
数据挖掘Java——Kmeans算法的实现
大脑皮层的分割方法
【翻译】GPT-3是如何工作的
论文笔记:TEACHTEXT: CrossModal Generaliz
python从零学(六)
详解Python 3.x 导入(import)
【答读者问27】backtrader不支持最新版本的
上一篇文章      下一篇文章      查看所有文章
加:2021-10-04 12:51:04  更:2021-10-04 12:52:31 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/27 10:37:37-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码