好得很程序员自学网
  • 首页
  • 后端语言
    • C#
    • PHP
    • Python
    • java
    • Golang
    • ASP.NET
  • 前端开发
    • Angular
    • react框架
    • LayUi开发
    • javascript
    • HTML与HTML5
    • CSS与CSS3
    • jQuery
    • Bootstrap
    • NodeJS
    • Vue与小程序技术
    • Photoshop
  • 数据库技术
    • MSSQL
    • MYSQL
    • Redis
    • MongoDB
    • Oracle
    • PostgreSQL
    • Sqlite
    • 数据库基础
    • 数据库排错
  • CMS系统
    • HDHCMS
    • WordPress
    • Dedecms
    • PhpCms
    • 帝国CMS
    • ThinkPHP
    • Discuz
    • ZBlog
    • ECSHOP
  • 高手进阶
    • Android技术
    • 正则表达式
    • 数据结构与算法
  • 系统运维
    • Windows
    • apache
    • 服务器排错
    • 网站安全
    • nginx
    • linux系统
    • MacOS
  • 学习教程
    • 前端脚本教程
    • HTML与CSS 教程
    • 脚本语言教程
    • 数据库教程
    • 应用系统教程
  • 新技术
  • 编程导航
    • 区块链
    • IT资讯
    • 设计灵感
    • 建站资源
    • 开发团队
    • 程序社区
    • 图标图库
    • 图形动效
    • IDE环境
    • 在线工具
    • 调试测试
    • Node开发
    • 游戏框架
    • CSS库
    • Jquery插件
    • Js插件
    • Web框架
    • 移动端框架
    • 模块管理
    • 开发社区
    • 在线课堂
    • 框架类库
    • 项目托管
    • 云服务

当前位置:首页>高手进阶
<tfoot draggable='sEl'></tfoot>

Erlang ordsets

Erlang ordsets

[Erlang 0069] Erlang ordsets

     ordsets  是lists实现的有序集合.由于数据元素的变动都会触发重新排序,所以ordsets效率不高,只适用于数据量比较小的场景.ordsets中包含了常见的集合操作:求交集,并集,是否为子集,是否存在交集

 6 >  ordsets: intersection([ 1 , 2 , 3 , 4 ],[ 3 , 4 , 5 , 6  ]).
[  3 , 4  ]
  7 >  ordsets: union([ 1 , 2 , 3 , 4 ],[ 3 , 4 , 5 , 6  ]).
[  1 , 2 , 3 , 4 , 5 , 6  ]
  8 >  ordsets: is_disjoint([ 1 , 2 , 3 , 4 ],[ 3 , 4 , 5 , 6  ]).
false
  9 >  ordsets: is_disjoint([ 1 , 2 , 3 , 4 ],[ 31 , 41 , 5 , 6  ]).
true
  10 >  ordsets: is_subset([ 1 , 2 , 3 , 4 ],[ 31 , 41 , 5 , 6  ]).
false
  11 >  ordsets: is_subset([ 1 , 2 , 3 , 4 ],[ 1 , 3  ]).
false
  12 >  ordsets: is_subset([ 1 , 2 , 3 , 4 ],[ 1 , 2 , 3 , 4 , 5 , 31  ]).
true 

  

  这些方法的实现大同小异,都会遍历两个集合(实际上就是处理两个lists):

 union([E1|Es1], [E2|_]=Set2) when E1 < E2 ->
    [E1|union(Es1, Set2)]  ;
  union([E1|_]=Set1, [E2|Es2]) when E1 > E2 ->
    [E2|union(Es2, Set1)]  ;                 % switch arguments! 
 union([E1|Es1], [_E2|Es2]) ->               %E1 == E2
    [E1|union(Es1, Es2)]  ;
 union([], Es2) -> Es2 ;
 union(Es1, []) -> Es1.

 

  看一下ordsets数据元素时的处理逻辑:

add_element(E, [H|Es]) when E > H -> [H|add_element(E, Es)] ;
 add_element(E, [H|_]=Set) when E < H -> [E|Set] ;
 add_element(_E, [_H|_]=Set) -> Set ;            %E == H 
 add_element(E, []) -> [E].
 
del_element(E, [H|Es]) when E > H -> [H|del_element(E, Es)]  ;
 del_element(E, [H|_]=Set) when E < H -> Set ;
 del_element(_E, [_H|Es]) -> Es ;                 %E == H 
del_element(_, []) -> [].

 

  其它的方法实现多是简单封装了lists的方法而已比如:from_list实际上就是执行list:usort,is_set判断是List且已经排序;

 

is_subset([E1|_], [E2|_]) when E1 < E2 ->     %E1  not   in   Set2
    false  ;
  is_subset([E1|_]=Set1, [E2|Es2]) when E1 > E2 ->
    is_subset(Set1, Es2)  ;
  is_subset([_E1|Es1], [_E2|Es2]) ->          %E1 == E2
    is_subset(Es1, Es2)  ;
 is_subset([], _) -> true ;
  is_subset(_, []) -> false.

%% 下面两个方法仅仅是对lists方法的简单封装 
fold(F, Acc, Set) ->
      lists:  foldl(F, Acc, Set).
 
filter(F, Set) ->
      lists: filter(F, Set).

 lists:usort的处理过程包含了数据排重:

 1 >  lists: usort([ 2 , 1 , 3 , 4 , 2 , 3 , 8 , 9  ,a,v,c]).
[  1 , 2 , 3 , 4 , 8 , 9  ,a,c,v]
  2 >  lists: usort([ 2 , 1 , 3 , 4 , 2 , 3 , 8 , 9  ,[a,c,q,m,x],a,v,c]).
[  1 , 2 , 3 , 4 , 8 , 9  ,a,c,v,[a,c,q,m,x]]
  3 >  lists: usort([ 2 , 1 , 3 , 4 , 2 , 3 , 8 , 9 ,[ 0  ,c,q,m,x],a,v,c]).
[  1 , 2 , 3 , 4 , 8 , 9 ,a,c,v,[ 0  ,c,q,m,x]]
  4 >  lists: usort([ 2 , 1 , 3 ,{zen}, 4 , 2 , 3 , 8 , 9 ,[ 0  ,c,q,m,x],a,v,c]).
[  1 , 2 , 3 , 4 , 8 , 9 ,a,c,v,{zen},[ 0 ,c,q,m,x]]

性能相关

   OTP文档中有一点和ordsets相关的内容 lists:substract(A,B),该操作的复杂度和leng(A)*length(B)成正比,当参与运算的两个都是长列表的时候就会非常慢了;使用ordsets会好很多:

 

>  lists: subtract( "  123212  " ,  "  212  " ).   %%    lists:  subtract(A, B) is equivalent to A -- B.
  "  312  " .

不要这样做:

           HugeList1 -- HugeList2

替代方案:  

       HugeSet1 =  ordsets:  from_list(HugeList1),
        HugeSet2 =   ordsets:  from_list(HugeList2),
          ordsets: subtract(HugeSet1, HugeSet2)        

 

  显然lists中的元素原始顺序非常重要上面的方法就不适用了,要保持数据原始顺序,可以这样做:

        Set =  gb_sets:  from_list(HugeList2),
        [E || E <- HugeList1,   not   gb_sets: is_element(E, Set)]

 

 

两个细节:

1.如果lists中包含重复的元素时,两种运算不是等价的,HugeList2会移除所有在HugeList1中出现的元素

2.下面的方法比较lists中的元素使用的是相等== 而'--'操作使用的是匹配操作符'=:=';如果这个地方要求苛刻的话,可以使用sets替换为gb_sets,但要注意sets:from_list/1要比gb_sets:from_list/1慢得多.


注意:'--'操作符在处理单个元素时并无大碍:

HugeList1 -- [Element]  %%OK         

 

官方文档:

[1] lists  http://www.erlang.org/doc/man/lists.html

[2] efficiency guide  http://www.erlang.org/doc/efficiency_guide/commoncaveats.html

 

More Sharing Services Share | Share on facebook Share on myspace Share on google Share on twitter

 


 

分类:  Erlang

作者: Leo_wl

    

出处: http://www.cnblogs.com/Leo_wl/

    

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权信息

查看更多关于Erlang ordsets的详细内容...

声明:本文来自网络,不代表【好得很程序员自学网】立场,转载请注明出处:http://haodehen.cn/did48588

更新时间:2022-09-24   阅读:48次

上一篇: cocos2dx for window phone

下一篇:WCF开发框架之证书加密使用说明书

相关资讯

最新资料更新

  • 1.C#开发PACS医学影像三维重建(十四):基于能量模型算法将曲面牙床展开至二维平面
  • 2.LeetCode155:最小栈,最简单的中等难度题,时间击败100%,内存也低于官方
  • 3.《算法导论》笔记 第8章 8.3基数排序
  • 4.OpenGL光栅化作业:【bresenham算法】GL_POINTS为基础画线段
  • 5.数据结构与算法 - 大顶堆与小顶堆
  • 6.初探富文本之CRDT协同算法
  • 7.LeetCode买卖股票之一:基本套路(122)
  • 8.canny算法的实现(android加载图片,数组写入文件换行)
  • 9.知识蒸馏、轻量化模型架构、剪枝…几种深度学习模型压缩方法
  • 10.深入了解Vue2中的的双端diff算法
  • 11.又一重要进展发布!OpenMMLab算法仓支持昇腾AI训练加速
  • 12.遗传算法求TSP问题
  • 13.算法提高 概率计算
  • 14.c++ 递推算法
  • 15.java算法题解LeetCode30包含min函数的栈实例
  • 16.算法提高 矩阵乘法
  • 17.文心一言 VS 讯飞星火 VS chatgpt (79)-- 算法导论7.4 4题
  • 18.推荐系统[八]算法实践总结V1:淘宝逛逛and阿里飞猪个性化推荐:召回算法实践总结【冷启动召回、复购
  • 19.LeetCode952三部曲之二:小幅度优化(137ms -> 122ms,超39% -> 超51%
  • 20.Prim算法 (普里姆)

CopyRight:2016-2025好得很程序员自学网 备案ICP:湘ICP备09009000号-16 http://haodehen.cn
本站资讯不构成任何建议,仅限于个人分享,参考须谨慎!
本网站对有关资料所引致的错误、不确或遗漏,概不负任何法律责任。
本网站刊载的所有内容(包括但不仅限文字、图片、LOGO、音频、视频、软件、程序等)版权归原作者所有。任何单位或个人认为本网站中的内容可能涉嫌侵犯其知识产权或存在不实内容时,请及时通知本站,予以删除。

网站内容来源于网络分享,如有侵权发邮箱到:kenbest@126.com,收到邮件我们会即时下线处理。
网站框架支持:HDHCMS   51LA统计 百度统计
Copyright © 2018-2025 「好得很程序员自学网」
[ SiteMap ]