Erlang:Erlang程序设计26一月201402:25:03PM关于列表的学习记录,包括以下五点:(以后不做单独目录结构,仅记录目录数量或附言)·列表处理(摘:Erlan
Erlang : Erlang程序设计
26 一月 2014 02:25:03 PM
关于列表的学习记录,包括以下五点:(以后不做单独目录结构,仅记录目录数量或附言)
· 列表处理(摘:Erlang程序设计PDF P36)
%mylists.erl
-module(mylists).
-export([sum/1, map/2]).
sum([H|T]) -> H + sum(T);
sum([]) -> 0.
map(_, []) -> [];
map(F, [H|T]) -> [F(H)|map(F, T)].
1、sum内部工作机制,sum执行跟踪
sum([1,3,10])
sum([1,3,10]) = 1 + sum([3,10])
= 1 + 3 + sum([10])
= 1 + 3 + 10 + 0
= 14
2、理解map/2
map(_, []) -> [];
对空列表进行处理,把任何函数映射到一个空列表中,没有任何元素,产生一个空列表
map(F, [H|T]) -> [F(H)|map(F, T)].
处理非空列表规则,头为H,尾是T.创建一个新列表,头部是F(H),尾部是map(F,T).
Tips:该处的 map/2 定义是标准库中的 lists 模块中复制,在任何情况下不要把自己的模块名修改为 lists
,除非你知道将要发生什么.
整合过后的购物函数
%shopping.erl
-module(shopping).
-export([total/1]).
-import(mylists, [map/2,sum/1]).
total(L) ->
sum(map(fun({What, N}) -> shop:cost(What) * N end, L)).
% lists:sum([shop:cost(A) * B || {A, B} <- L]).
shell执行:
17> Buy = [{oranges,4},{newspaper,1},{apples,10},{pears,6},{milk,3}].
[{oranges,4},{newspaper,1},{apples,10},{pears,6},{milk,3}]
18> c(mylists).
{ok,mylists}
19> L1 = mylists:map(fun({What,N}) -> shop:cost(What) * N end,
Buy).
[20,8,20,54,21]
20> mylists:sum(L1).
123
21> c(shopping).
{ok,shopping}
22> shopping:total(Buy).
12
· 列表解析
定义:列表解析是一种无需使用 fun、map、filter 来创建列表的表达式,使程序更为简洁和容易理解.
23> L = [1,2,3,4,5].
[1,2,3,4,5]
24> lists:map(fun(X) -> 2*X end, L).
[2,4,6,8,10]
25> [2*X || X <- L].
[2,4,6,8,10]
可以看到,line24与line25对于L处理的结果是相同的.
记号[F(X) || X <- L]代表"由F(X)组成的列表,其中X是取值于列表L".因此[2*X || X <-
L]等同于"列表L中每个元素X*2后的输出列表".
再来看购物函数Shell:
26> [{shop:cost(Name), Number} || {Name, Number} <- Buy].
[{5,4},{8,1},{2,10},{9,6},{7,3}]
27> [shop:cost(Name)*Number || {Name, Number} <- Buy].
[20,8,20,54,21]
28> lists:sum([shop:cost(A)*B || {A,B} <- Buy]).
123
那么购物函数可以这样写:
total(L) ->
% sum(map(fun({What, N}) -> shop:cost(What) * N end, L)).
lists:sum([shop:cost(A) * B || {A, B} <- L]).
Shell检验一下:
29> c(shopping).
{ok,shopping}
30> shopping:total(Buy).
123
总结性的东西直接贴图了(P39):
title="clip_image002"
alt="clip_image002" src="https://img8.php1.cn/3cdc5/1566f/243/77ee29be95fa6a51.jpeg"
border="0">
· 快速排序
%sort_quick.erl
-module(sort_quick).
-export([qsort/1]).
qsort([]) -> [];
qsort([Pivot | T]) ->
qsort([X || X <- T, X ++ [Pivot] ++
qsort([X || X <- T, X >= Pivot]).
32> f().
ok
33> L = [23,6,2,9,27,400,78,45,61,82,14].
[23,6,2,9,27,400,78,45,61,82,14]
34> c(sort_quick).
{ok,sort_quick}
35> sort_quick:qsort(L).
[2,6,9,14,23,27,45,61,78,82,400]
可以看到 L 重新进行了排序
这里是Shell中的单步解析:
1> L = [23,6,2,9,27,400,78,45,61,82,14].
[23,6,2,9,27,400,78,45,61,82,14]
2> [Pivot|T] = L.
[23,6,2,9,27,400,78,45,61,82,14]
3> Smaller = [X || X <- T, X [6,2,9,14]
4> Bigger = [X || X <- T, X >= Pivot].
[27,400,78,45,61,82]
首先将L分为两半,再将Smaller与Bigger再做分为两半的操作,直至不可分割.
· 毕达哥拉斯元组
libpythag.erl
-module(libpythag).
-export([pythag/1]).
pythag(N) ->
[{A,B,C} ||
A <- lists:seq(1, N),
B <- lists:seq(1, N),
C <- lists:seq(1, N),
A + B + C =A * A + B * B =:= C * C
].
这里lists:seq(1,N)返回由 1-N 整数组成的列表 L .其他的勾股和三角边没什么好说的.
5> c(libpythag).
{ok,libpythag}
6> libpythag:pythag(16).
[{3,4,5},{4,3,5}]
7> libpythag:pythag(30).
[{3,4,5},{4,3,5},{5,12,13},{6,8,10},{8,6,10},{12,5,13}]
· 变位词-理解为排序(组合)
libperms.erl
-module(libperms).
-export([perms/1]).
perms([]) -> [[]];
perms(L) -> [[H|T] || H <- L, T <- perms(L--[H])].
1> c(libperms).
{ok,libperms}
2> libperms:perms("123").
["123","132","213","231","312","321"]
3> libperms:perms("1234").
["1234","1243","1324","1342","1423","1432","2134","2143",
"2314","2341","2413","2431","3124","3142","3214","3241",
"3412","3421","4123","4132","4213","4231","4312","4321"]
理解为这样的关系
123 132
213 231
312 321
1234 1243 1324 1342 1423 1432
2134 2143 2314 2341
3124 3142
4123
依次类推.
Tips:
perms([]) -> [[]];
空表输出空值
perms(L) -> [[H|T] || H <- L, T <- perms(L--[H])].
非空依次输出(理解为遍历) L 中的一个值并对表尾(除去 H 的部分) T 再次递归操作
More In Here