erlang循环结构:尾递归,列表解析
2014-03-20 23:39
513 查看
最近看到一道erlang面试题,要求分别用尾递归,lists模块,列表解析找出0-9的偶数。
我们知道,ErLang不支持变量重复赋值,因而也不支持循环语句。erlang能使用的循环结构只有递归和列表解析。
现在看下erlang递归,erlang这里主要用的是尾递归。
先看下erlang递归和尾递归的区别,如下例子:
不难看出,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列表解析,看个例子:
在erlang列表解析表达式中,|| 左边用以生成列表元素,相当于构造器;右边由赋值语句和条件语句构成,也可以只有赋值语句。
实际上,erlang列表解析在运行时会转换成一个临时函数
参考
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
-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
相关文章推荐
- ubuntu 12.04 密码输入正确但无法进入图形化界面
- Heritrix爬虫
- 第一篇博客
- day15
- C语言中的无符号数
- This version of the rendering library is more recent than your version of ADT plug-in. Please update
- Mixing x86 with x64 code (混合编写x86和x64代码)
- HighCharts之2D堆条状图
- range xrange iterator generator
- HighCharts之2D堆条状图
- zoj 1091 BFS简单搜索
- 生命周期
- C语言单元测试
- asterisk 命令
- windows下python SSH的使用——paramiko模块
- 搭建linux开发环境
- windows下python SSH的使用——paramiko模块
- zoj 1008 DFS+剪枝(小坑爹的剪枝)
- MASM32 控制台输入输出
- Linux下mysql备份 恢复