Erlang中常用数据结构原理及其实现

文章目录

    • 一、Erlang 简介
    • 二、数据结构
      • 2.1、元组(Tuple)
        • 2.1.1、示例:
        • 2.1.2、实现:
      • 2.2、列表(List)
        • 2.2.1、示例
        • 2.2.2、实现
        • 2.2.3、原理
      • 3. 字典(Dictionary)
        • 3.1、创建字典
        • 3.2、添加和删除键值对
        • 3.3、获取值
        • 3.4、检查键是否存在
        • 3.5、获取字典大小
        • 3.6、遍历字典
        • 3.7、合并字典
        • 3.8、获取所有键
        • 3.9、获取所有值
      • 4. 集合(Set)
        • 4.1、创建集合
        • 4.2、添加元素
        • 4.3、删除元素
        • 4.4、判断元素是否存在
        • 4.5、获取集合大小
        • 4.5、并集
        • 4.6、交集
        • 4.7、差集
        • 4.8、遍历集合
      • 结论


一、Erlang 简介

Erlang 是一种函数式编程语言,它具有强大的并发和分布式编程能力。在 Erlang 中,常用的数据结构包括元组(tuple)、列表(list)、字典(dictionary)和集合(set)。这些数据结构在 Erlang 中被广泛应用于不同的场景中,例如存储和处理数据、通信和消息传递等。在本文中,我们将深入探讨这些常用数据结构的特点和实现方式。

二、数据结构

2.1、元组(Tuple)

元组是一种不可变的有序集合,通常用于存储固定数量的数据项。在 Erlang 中,元组用大括号 {} 表示,其中的元素之间用逗号 , 分隔。元组的元素可以是任何类型的数据,包括原子、整数、浮点数、字符串等。

2.1.1、示例:
Tuple = {1, atom, "hello", 3.14}.
2.1.2、实现:

Erlang 中的元组是不可变的,即一旦创建就不能修改。可以使用模式匹配来访问元组中的元素,也可以使用内置函数来操作元组,如 tuple_size/1 获取元组的大小,element/2 获取元组中指定位置的元素等。

Tuple = {1, atom, "hello", 3.14},
Size = tuple_size(Tuple),  % 获取元组大小
Element = element(2, Tuple).  % 获取第二个元素

2.2、列表(List)

列表是一种可变的有序集合,用于存储可变数量的数据项。在 Erlang 中,列表用方括号 [] 表示,其中的元素之间用逗号 , 分隔。列表的元素可以是任何类型的数据,也可以包含其他列表。

2.2.1、示例
List = [1, 2, 3, 4, 5].
2.2.2、实现

Erlang 中的列表是可变的,可以使用模式匹配和内置函数来操作列表。常见的列表操作包括添加元素、删除元素、查找元素、列表推导等。

List = [1, 2, 3, 4, 5],
Head = hd(List),  % 获取列表的第一个元素
Tail = tl(List),  % 获取列表的尾部
Length = length(List).  % 获取列表的长度
2.2.3、原理

下面举个例子,假设我们有这样一个列表:L = [1,2,ok,done],现在暂时用这个简单的列表来作为示例,这个列表在进程内的示意图如下所示:

在这里插入图片描述
在构造一个新的列表的时候,如果新的列表引用了其他列表,那么引用了其他列表的元素本身就是一个 Cons 单元格。例如,我们有下面两个列表:

L1 = [1, 2, 3].
L2 = [L1, L1, L1]

L2 中存在 3 个对 L1 的引用,Erlang 可以很聪明地复用 L1,内存中实际上只有一份对 L1 的拷贝,如下图所示:
在这里插入图片描述
为了简洁,这个图相比前一个图简化了,不再严格表示栈和堆的相对位置,不再严格表示 Eterm 的标签。从图中可以看到,列表 L2 中的 3 个 cons 单元格都引用了 L1。

3. 字典(Dictionary)

在 Erlang 中,字典(Dictionary)是一种键值对的数据结构,也称为关联数组或映射。字典允许您通过键来检索和存储值,它是一种非常灵活和实用的数据结构。在 Erlang 中,字典通常使用 dict 模块来实现,该模块提供了一组函数来创建、操作和查询字典。

3.1、创建字典

在 Erlang 中创建字典可以使用 dict:new/0 函数,也可以使用 dict:from_list/1 函数从列表中创建。

Dict1 = dict:new().
Dict2 = dict:from_list([{key1, value1}, {key2, value2}, {key3, value3}]).
3.2、添加和删除键值对

使用 dict:store/3 函数可以向字典中添加新的键值对,使用 dict:erase/2 函数可以删除指定键的键值对。

NewDict = dict:store(Key, Value, Dict).
NewDict = dict:erase(Key, Dict).
3.3、获取值

可以使用 dict:find/2 函数通过键来获取字典中对应的值。

{ok, Value} = dict:find(Key, Dict).
3.4、检查键是否存在

使用 dict:is_key/2 函数可以检查字典中是否存在指定的键。

Result = dict:is_key(Key, Dict).
3.5、获取字典大小

可以使用 dict:size/1 函数获取字典的大小,即键值对的数量。

Size = dict:size(Dict).
3.6、遍历字典

Erlang 中遍历字典可以使用递归或者列表推导式等方式,也可以使用 dict:fold/3 函数。

Sum = dict:fold(fun(_, Value, Acc) -> Value + Acc end, 0, Dict).
3.7、合并字典

使用 dict:merge/3 函数可以将两个字典合并为一个新的字典。

MergedDict = dict:merge(Dict1, Dict2, fun(_Key, Val1, Val2) -> Val1 end).
3.8、获取所有键

使用 dict:keys/1 函数可以获取字典中所有的键。

Keys = dict:keys(Dict).
3.9、获取所有值

使用 dict:values/1 函数可以获取字典中所有的值。

Values = dict:values(Dict).

4. 集合(Set)

在 Erlang 中,集合(Set)是一种无序的数据结构,用于存储一组唯一的元素。集合的特点是元素的唯一性和无序性,这使得它适用于许多场景,例如去重、集合操作(如并集、交集、差集等)等。在 Erlang 中,集合通常使用 sets 模块来实现,该模块提供了一组丰富的函数来操作集合。

4.1、创建集合

在 Erlang 中创建集合通常使用 sets:from_list/1 函数,该函数接受一个列表作为参数,并返回一个集合。

Set = sets:from_list([1, 2, 3, 4, 5]).
4.2、添加元素

可以使用 sets:add/2 函数向集合中添加元素。

NewSet = sets:add(6, Set).
4.3、删除元素

使用 sets:del/2 函数可以从集合中删除指定元素。

NewSet = sets:del(3, Set).
4.4、判断元素是否存在

使用 sets:is_element/2 函数可以判断集合中是否存在指定元素。

Result = sets:is_element(3, Set).
4.5、获取集合大小

使用 sets:size/1 函数可以获取集合的大小。

Size = sets:size(Set).

Erlang 的 sets 模块还提供了一些集合操作函数,如并集、交集、差集等。

4.5、并集

使用 sets:union/2 函数可以计算两个集合的并集。

UnionSet = sets:union(Set1, Set2).
4.6、交集

使用 sets:intersection/2 函数可以计算两个集合的交集。

IntersectionSet = sets:intersection(Set1, Set2).
4.7、差集

使用 sets:subtract/2 函数可以计算两个集合的差集。

DifferenceSet = sets:subtract(Set1, Set2).
4.8、遍历集合

Erlang 中遍历集合可以使用递归或者列表推导式等方式,也可以使用 sets:fold/3 函数。

Sum = sets:fold(fun(Elem, Acc) -> Elem + Acc end, 0, Set).

结论

在 Erlang 中,元组、列表、字典和集合是常用的数据结构,它们分别适用于不同的场景和需求。掌握这些数据结构的特点和实现方式,有助于编写高效、可靠的 Erlang 代码。在实际开发中,根据具体的问题和需求,选择合适的数据结构来存储和处理数据,可以提高代码的可读性和性能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/611306.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ELK 日志分析系统(一)

一、概念 二、详解 2.1 Elasticsearch 核心概念 2.1.1 接近实时(NRT) 2.1.2 cluster集群 2.1.3 Node节点 2.1.4 index索引 2.1.5 类型(type) 2.1.6 文档(document) 2.1.7 分片和副本(shards & replicas) 2.2 Logstash主要组件 …

UE_导入内容_Maya静态网格体导出为FBX的常规设置

注意事项:单位设置统一为cm;轴朝向,Maya默认y轴朝上,UE4 z轴向上;变换枢轴,UE4会将导入模型前世界中心作为枢轴中心,要旋转就需要注意了;法线,UE4内材质默认单面显示&…

记录一个Kafka客户端Offset Explore连不上的问题

我昨天把集群重装了一下,再连这个工具就连不上了(你先把zk和kafka在集群启起来),报错截图如下: 英文翻译过来大概就是说遍历zk指定路径不存在,我还以为zk的问题,回去又把zk的文档翻了一遍&#…

HCIE考试第四题:业务个性化配置

文章目录 业务个性化配置题目与做题步骤如下4业务个性化配置4.1.创建节点池solo-2【4.13中的同步创建了】4.1.1.创建Namespace4.1.2.创建节点池和节点4.2.镜像制作solo:2.04.3.创建sol0-2.0日录4.4.NFS环境检查4.5.修改Dockerfie4.6.构建镜像solo:2.0并上传到SWR【4.2-4.6为1小…

锐化空间滤波器--二阶微分图像增强(提高清晰度的另一种方式)

书上一阶微分的定义可以理解,毕竟这里不死数学上的曲线的概念,而是像素点上的曲线。所以,不同于数学的严格单调递增曲线的导数是大于等于零,这里的严格单调递增曲线,只能是大于零。 至于二阶微分的定义,就…

项目4-图书管理系统2+统一功能处理

1. 拦截器(Interceptor) 我们完成了强制登录的功能, 后端程序根据Session来判断用户是否登录, 但是实现⽅法是比较麻烦的。 所需要处理的内容: • 需要修改每个接⼝的处理逻辑 • 需要修改每个接⼝的返回结果 • 接⼝定义修改, 前端代码也需…

解决宝塔的FTP无法使用被动模式

问题:宝塔安装完ftp管理软件之后,无法使用被动模式连接 解决: 提示: 如果还是不行,那么要看看防火墙和安全组有没有放行被动模式的端口,宝塔安装的pure-ftpd软件的被动模式端口默认是39000至400…

界面设计【1】-项目的UI设计css

引言: 本篇博客对简单的css html界面设计做了简要介绍 这篇博客主要就是介绍了做横向项目中,CSS界面设计与优化。 界面设计【1】-项目的UI设计css 1. 什么是css?2. css编程demo3. 可视化效果 1. 什么是css? CSS是层叠样式表(Cascading S…

深入解析:虚拟内存——理解现代计算机内存管理的关键概念

目录 一、引言 二、程序的“搬家”记:从硬盘到内存 1. 把剧本搬上舞台 2. 分配角色和位置 3. 开始排练与演出 三、虚拟内存:理想与现实的桥梁 1.虚拟内存:运行原理 2. 虚拟内存:让每个程序都有个“私人剧场” 3. 虚拟内…

多态【C/C++复习版】

目录 一、多态是什么?如何实现? 二、 什么是重写?有什么特点? 三、什么是协变? 四、析构函数能实现多态吗?为什么要实现? 五、override和final的作用是什么? 六、 多态的原理是…

基于spring boot的班级综合测评管理系统

基于spring boot的班级综合测评管理系统设计与实现 开发语言:Java 框架:springboot JDK版本:JDK1.8 服务器:tomcat7 数据库:mysql 5.7(一定要5.7版本) 数据库工具:Navicat11 开…

数据可视化-ECharts Html项目实战(10)

在之前的文章中,我们学习了如何在ECharts中编写雷达图,实现特殊效果的插入运用,函数的插入,以及多图表雷达图。想了解的朋友可以查看这篇文章。同时,希望我的文章能帮助到你,如果觉得我的文章写的不错&…