`
cwqcwk1
  • 浏览: 89285 次
文章分类
社区版块
存档分类
最新评论

erlang循环结构:尾递归,列表解析

 
阅读更多

最近看到一道erlang面试题,要求分别用尾递归,lists模块,列表解析找出0-9的偶数。

-module(test).  
-export([tail_loop/0, lists_func/0, list_comp/0]).

% 尾递归
tail_loop() ->
	tail_loop( get_num(), []).

tail_loop([], List) ->
	List;
tail_loop([F | Other], List) ->
	tail_loop( Other, List ++ (if F rem 2 == 0 -> [F]; true -> [] end) ).

% lists模块	
lists_func() ->
	lists:foldl(fun(X, List) ->
	 if X rem 2 == 0 -> List ++ [X];
	  true -> List
	 end
	end, [], get_num()).
 
% 列表解析
list_comp() ->
	[X ||  X<- get_num(), X rem 2 == 0].
	
% 生成0到9的数字
get_num() ->
	lists:seq(0,9).

我们知道,ErLang不支持变量重复赋值,因而也不支持循环语句。erlang能使用的循环结构只有递归和列表解析。

现在看下erlang递归,erlang这里主要用的是尾递归。

先看下erlang递归和尾递归的区别,如下例子:

% 递归
loop(0) -> 
    1; 
loop(N) -> 
   N * loop(N-1).

% 尾递归
tail_loop(N)-> 
    tail_loop(N, 1).

tail_loop(0, R)-> 
    R; 
tail_loop(N, R) -> 
    tail_loop(N-1, N *R). 

不难看出,erlang尾递归是通过参数来传递实际结果。普通递归用到的栈空间和列表的长度成正比,尾递归不需要再次申请栈空间。如果递归的次数过多,显然尾递归比较合适。至于说哪个递归速度快,erlang说法有争议

It depends. On Solaris/Sparc, the body-recursive function seems to be slightly faster, even for lists with very many elements. On the x86 architecture, tail-recursion was up to about 30 percent faster.

接下来看看erlang列表解析,看个例子:

1> [X || X <- [1,2,a,3,4,b,5,6]].
[1,2,a,3,4,b,5,6]

2> [X || X <- [1,2,a,3,4,b,5,6], X > 3].
[a,4,b,5,6]

3> [X || X <- [1,2,a,3,4,b,5,6], integer(X), X > 3].
[4,5,6]

4> [{X, Y} || X <- [1,2,3], Y <- [a,b]].
[{1,a},{1,b},{2,a},{2,b},{3,a},{3,b}]

在erlang列表解析表达式中,|| 左边用以生成列表元素,相当于构造器;右边由赋值语句和条件语句构成,也可以只有赋值语句。
实际上,erlang列表解析在运行时会转换成一个临时函数

% 列表解析
[Expr(E) || E <- List]

% 解析成的临时函数
'lc^0'([E|Tail], Expr) ->
    [Expr(E)|'lc^0'(Tail, Expr)];
'lc^0'([], _Expr) -> [].
总的来说,列表递归函数和尾递归加反转没有太大差别。因此,可以忽略列表函数的性能损失(R12B)。


参考

http://blog.csdn.net/mycwq/article/details/21631123

http://www.erlang.org/doc/efficiency_guide/listHandling.html

http://www.erlang.org/doc/programming_examples/list_comprehensions.html

http://www.erlang.org/doc/efficiency_guide/myths.html#tail_recursive


分享到:
评论

相关推荐

    《Erlang之父:为什么面向对象很糟糕》PDF

    《Erlang之父:为什么面向对象很糟糕》PDF 《Erlang之父:为什么面向对象很糟糕》PDF 《Erlang之父:为什么面向对象很糟糕》PDF 《Erlang之父:为什么面向对象很糟糕》PDF 《Erlang之父:为什么面向对象很糟糕》PDF

    Windows Erlang语言安装包:otp-win64-25.2.1

    Windows上安装RabbitMQ服务,依赖的Erlang语言安装包:otp_win64_25.2.1.exe 重要:Erlang安装程序必须【以管理员身份运行】,否则RabbitMQ安装程序相关信息不会在注册表项中不存在。

    erlang-23.2.1-1.el7.x86-64.rpm

    Erlang:RabbitMQ 是用 Erlang 编写的,因此需要 Erlang 运行时。确保安装了兼容的 Erlang 版本;Erlang:RabbitMQ 是用 Erlang 编写的,因此需要 Erlang 运行时。确保安装了兼容的 Erlang 版本;Erlang:RabbitMQ ...

    erlang文献及资料汇总

    erlang位运算与二进制解析 erlang二进制高效编程 erlang异常处理详解 开发经验: 面对软件错误构建可靠的分布式系统 编写分布式的 Erlang 程序:陷阱和对策 硝烟中的Erlang 深入底层: erlang VM基于多核处理器的...

    erlang中dns解析

    在Erlang编程语言中,DNS(Domain Name System)解析是一项关键功能,它允许程序将域名转换为IP地址,反之亦然。Erlang提供了强大的工具来处理网络通信,包括DNS解析。这篇博客(虽然链接不可用)可能讨论了如何在...

    erlang-geoparser:地理定位解析器

    用 Erlang 制作的本地化解析器 目前管理: 一个特定的城市 在特定区域 在 POINT_CARDINAL 在部门 在海上/在山上 在海边 城市旁边 城市周边 靠近CITY a / at POINT_CARDINAL of / of / of the CITY / REGION 这个...

    erlang-conf:用于将 erlang conf 解析为 JSON 的 NodeJS 模块

    该"erlang-conf"模块的工作原理可能是通过解析Erlang Conf文件中的键值对,处理注释,识别列表和嵌套结构,然后映射到相应的JSON对象。它可能提供了一些API接口,如`parse()`函数,用于读取和解析Erlang Conf文件,...

    erlang_term:Erlang术语信息

    例如,列表的尾递归优化可以减少内存使用。 10. **数据结构的使用**:在Erlang中,选择合适的数据结构对于实现高效算法至关重要。例如,元组适合快速查找,列表适合迭代和插入,二进制适合大数据处理。 通过理解...

    erlang-ffi:与Haskell的Erlang节点通信

    讲出Erlang网络协议并模拟网络上的Erlang节点。 完全能够与Erlang进行双向通信。 在合理范围内,Erlang类型已映射到Haskell类型。 发给Erlang的消息只是Haskell中的函数调用,而来自Erlang的消息则传递到MVars。 ...

    erlang_couchdb:这是另一个erlang CouchDB客户端。 它比大多数简单一些,并且可以满足我的要求

    erlang_couchdb是一个非常简单的CouchDB客户端。 简单意味着它会做得尽可能少,并且不会妨碍您。 我开发此模块是因为现有的模块看起来太大了,而且对我的口味影响很大。 该模块提供了一些公共功能来执行诸如处理...

    erlang_ls:Erlang 语言服务器

    erlang_ls 一个实现微软语言服务器协议 3.15 的 Erlang 服务器。最低要求 快速开始编译项目: make要在/usr/local/bin安装生成的erlang_ls escript: make install命令行参数这些是可以提供给erlang_ls脚本的命令行...

    xapian-erlang-bindings:用于Erlang的Xapian绑定(GSOC2012项目)

    Xapian绑定到Erlang 许可证:MIT,GPL2或更高版本(Xapian仍仅受GPL约束。) 作者:Uvarov Michael( ) 是一个用C ++编写的开源搜索引擎库。 Xapian是一个高度适应性强的工具包,它使开发人员可以轻松地在其自己...

    erlang-dateparser:用 Erlang 制作的日期解析器

    Erlang-dateparser 迄今为止用 Erlang 制作的解析器目前管理: X 天/周/月/年前在 X 天/周/月/年X月下一天/最后一天前天,昨天,今天,明天,后天下周/上周下周末/上周末明年/去年日日月年这个怎么运作汇编1&gt; c ...

    Erlang入门:构建application练习2

    1. **项目结构**:一个标准的Erlang Application通常包含以下目录结构: - `ebin`:存放编译后的BEAM文件(Erlang的字节码)。 - `src`:源代码文件所在目录。 - `releases`:应用的不同版本和更新定义。 - `...

    erlang-companies:目前在生产中使用Erlang的公司列表

    标题"erlang-companies:目前在生产中使用Erlang的公司列表"表明这是一个收集了使用Erlang进行实际生产的企业名单的资源。这些公司在他们的产品或服务中利用Erlang的特性来实现高效、稳定的系统运行。这可能包括但不...

    Erlang入门:构建application练习4(进程link的作用)

    在Erlang编程语言中,进程是其核心特性之一,它们是并发执行的实体,类似于其他语言中的线程。在Erlang中,进程间通信(IPC)是通过消息传递来实现的,而`link`机制是这个通信模型中非常重要的一部分。本教程将通过...

    erlang-org:erlang.org网站

    Erlang.org网站 Erlang.org网站的源代码。 在本地设置Erlang.org Erlang.org使用来提供Web服务器支持,并使用来呈现Web页面。 它使用连接到PostgreSQL数据库。 使用docker设置Erlang.org 跑步: 码头工人组成 ...

    Erlang初级入门(英文pdf)

    ### Erlang基础知识与特性 #### 一、Erlang简介 Erlang是一种专为处理大规模并发活动设计的编程语言,由瑞典电信设备制造商爱立信的计算机科学实验室(Computer Science Laboratory, CSLab)开发。该语言的目标是...

    erlang压缩包.rar

    - **递归**:由于Erlang的进程特性,递归是常见的编程方式,尤其在处理列表和树结构时。 - **错误处理**:Erlang的异常处理通过`try...catch...after`语句实现,允许优雅地处理错误情况。 了解了这些基础知识后,你...

    erlang_prelude:解决经常遇到的问题的 Erlang 模块集合

    二郎序曲解决经常遇到的问题的 Erlang 模块集合 :-)ep_code 检查模块是否具有给定行为或获取具有给定行为的所有模块。ep_deploy 将通知您的应用程序任何重新加载的模块的行为。 还具有重新加载更新模块和内省更改的...

Global site tag (gtag.js) - Google Analytics