练习重点
- erlang是单赋值的,就好像都经过java里边的final修饰过
- erlang没有内置的循环结构,这个和大多数语言是不一样的
- erlang是函数式语言,需要理解模式匹配编程方式
- erlang经常会遇到递归, 并且支持尾递归函数调用
练习1:数据库demo
作为学习erlang里边的模式匹配,熟悉语法。 编写一个数据库模块db.erl,它能够存储、检索、删除元素。我们需要实现的接口有:
db:new() %% Db.
db:destroy(Db) %% ok.
db:write(Key, Element, Db) %% NewDb.
db:delete(Key, Db) %% NewDb.
db:read(Key, Db) %% {ok, Element} | {error, instance}.
db:match(Element, Db) %% [Key1, ..., KeyN].
实现代码
-module(db).
%% Exported Functions
-export([new/0, write/3, read/2, match/2, delete/2, destroy/1]).
%% API Functions
new() -> [].
destroy(_) -> ok.
write(Key, Element, DB) -> [{Key,Element}|DB].
delete(Key, DB) -> delete_local(Key, DB, []).
read(Key, DB) ->
case DB of
[{Key, Element}|_] -> {oKey, Element};
[_|ODB] -> read(Key, ODB);
_ -> {error, instance}
end.
match(Element, DB) -> match_local(Element, DB, []).
%% Local Functions
match_local(Element, DB, LIST) ->
case DB of
[{Key, Element}|ODB] -> match_local(Element, ODB, [Key|LIST]);
[_|ODB] -> match_local(Element, ODB, LIST);
_ -> LIST
end.
delete_local(Key, DB, NDB) ->
case DB of
[{Key, _}|ODB] -> delete_local(Key, ODB, NDB);
[H|ODB] -> delete_local(Key, ODB, [H|NDB]);
_ -> NDB
end.
当然,case语句同样可以用如下代码替代:其中第三行的Key因为没有使用就换成_, 不然会提示警告variable ‘Key’ is unused。
delete_local(Key, [{key, _}|ODB], NDB) -> delete_local(Key, ODB, NDB);
delete_local(Key, [H|ODB], NDB) -> delete_local(Key, ODB, [H|NDB]);
delete_local(_, _, NDB) -> NDB;
练习2:排序算法
下面练习一下快速排序和归并排序,再熟悉一下模式匹配和递归的写法。
-module(sort).
-export([quicksort/1, mergesort/1]).
%% 快速排序
quicksort([H|Tail]) ->
lists:append([quicksort(lists:filter(fun(X) -> X < H end, Tail)),
[H],
quicksort(lists:filter(fun(X) -> X >= H end, Tail))]);
quicksort(L) -> L.
%% 归并排序
mergesort(A) ->
case length(A) of
0 -> [];
1 -> A;
LEN -> M = length(A) div 2,
merge(mergesort(lists:sublist(A, 1, M)),
mergesort(lists:sublist(A, M + 1, LEN - M)), [])
end.
merge(A, [], L) -> lists:append([L, A]);
merge([], B, L) -> lists:append([L, B]);
merge([HA|TA], [HB|TB], L) ->
if
HA > HB -> merge([HA|TA], TB, lists:append([L, [HB]]));
true -> merge(TA, [HB|TB], lists:append([L, [HA]]))
end.