Erlang实战杨辉三角等
erlang吧
全部回复
仅看楼主
level 11
a651944226 楼主
Erlang实战杨辉三角、选择排序、集合交与并
2013年05月21日 01点05分 1
level 11
a651944226 楼主
输出杨辉三角:接口为start(N),N为行数。
-module(triangle).
-export([start/1]).
start(N) ->
L=getN(N), %% 获取第杨辉三角第N行元素列表
if
N =:= 1 ->
%% N=1,直接输出第一行,递归调用结束
output(L);
N =/= 1 -> %% N>1,递归调用start,先输出第N-1行
start(N-1),
output(L)
end.
%% 控制输出第N行,列表L保存第N行元素,杨辉三角第N行有N个元素
output(L) -> output(L,1).
output(L,No) ->
if
length(L) =:= No ->
io:format("~p~n",[lists:nth(length(L), L)]);
length(L) =/= No ->
io:format("~p,",[lists:nth(No,L)]),
output(L,No+1)
end.
getN(N) ->
if
N =:= 1 ->
[1];
N =:= 2 ->
[1,1];
N > 2
->
L = getN(N-1), %%获得第N-1行元素
process(L) %% 通过第N-1行元素,推导出第N行
end.
process(Ele) -> process(Ele,1,[]).
process(Ele,No,L) ->
Len = length(Ele)+1,
if
Len =:= No ->
Temp = [1|L],
lists:reverse(Temp);
Len =/= No ->
if
No =:=1 ->
process(Ele,No+1,[No | L]);
No =/=1 ->
E1 = lists:nth(No-1,Ele),
E2 = lists:nth(No,Ele),
process(Ele,No+1,[E1+E2 | L])
end
end.
2013年05月21日 01点05分 2
level 11
a651944226 楼主

在程序中主要部分我都作了注释,这完全是按照我的想法来写的,如果大家对程序比较苛刻的话,自己回去再精炼一下吧。在Windows下运行结果如下:
2013年05月22日 00点05分 3
level 11
a651944226 楼主
1. 实战2:选择排序:接口为sort(L),L为输入数组。
    要求:给定一个无序数组,用选择排序法进行排序(从小到大),要求将中间过程的每一步都输出。
2013年05月22日 00点05分 4
level 11
a651944226 楼主

   原理:首先在未排序序列中找到最小元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小元素,然后放到排序序列末尾(目前已被排序的序列)。以此类推,直到所有元素均排序完毕。
  程序代码如下:
2013年05月22日 00点05分 5
level 11
a651944226 楼主

-module(choose_sort).
-export([sort/1]).
sort(L) -> sort(L,[]).
sort([],Ret) ->
io:format("Final:~p~nsort finished.",[Ret]);
sort(L,Ret) ->
Min = findMin(L),
Minimum = lists:nth(Min,L),
NewL = lists:delete(Minimum,L), %% 在L中删除最小元素
if
length(Ret) =:= 0 ->
Ele = [Minimum],
io:format("No.~p sort:~p~n",[length(Ele),Ele]);
length(Ret) =/= 0 ->
%% 使用两个列表逆置的操作是因为,要将一个元素插入列表尾
%% 注:在Erlang中,将一个元素到列表头很简单,插入到列表尾好像不直接,因此我用了两次逆置
Temp = lists:reverse(Ret),
Ele = lists:reverse([Minimum|Temp]),
io:format("No.~p sort:~p~n",[length(Ele),Ele])
end,
sort(NewL,Ele).
%% 找到最小元素位置
findMin(L) -> findMin(L,1,1).
findMin(L,Start,Loc) ->
Ele = lists:nth(Start,L),
Minimum = lists:nth(Loc,L),
if
length(L) =:= Start ->
if
Ele < Minimum ->
Start;
Ele >= Minimum ->
Loc
end;
length(L) =/= Start ->
if
Ele < Minimum ->
findMin(L,Start+1,Start);
Ele >= Minimum ->
findMin(L,Start+1,Loc)
end
end.
2013年05月22日 00点05分 6
level 11
a651944226 楼主
 注:最初我的想法是在原列表L上进行选择排序,但是,在原列表上进行选择排序可能需要交换列表的两个元素,在Erlang中,交换列表的两个元素没有直接的方法,因此,www.81nanchang.cn,我的最初想法比较繁琐。上述代码思想:(1)从列表L中选择最小元素,然后插入到结果列表Ret,;(2)将最小元素从L中删除;(3)递归调用(1)知道L中元素为空,返回结果Ret为最终排序结果。
2013年05月22日 00点05分 7
level 11
a651944226 楼主

程序运行结果如下:
2013年05月22日 00点05分 8
level 11
a651944226 楼主
杨辉三角的运行结果如下,刚刚没有把图贴上去,抱歉抱歉
2013年05月22日 01点05分 9
level 11
a651944226 楼主
1.
实战3:集合交与并操作。
  用列表表示集合,求两个集合的交集和并集,例如[1,3,4,5]和[4,5,7,9,10]的交集为[4,5],并集为[1,3,4,5,7,9,10]。
2013年05月23日 00点05分 10
level 11
a651944226 楼主
代码如下:
-module(set).
-export([inter/2]).
-export([union/2]).
inter(L1,L2) ->
S1 = lists:sort(L1),
S2 = lists:sort(L2),
inter(S1,S2,[]).
inter(S1,S2,Ret) ->
Len1 = length(S1),
Len2 = length(S2),
Log = (Len1 =:=0)
or (Len2 =:= 0),
if
Log =:= true ->
lists:reverse(Ret);
Log =/= ture ->
F1 = lists:nth(1,S1),
F2 = lists:nth(1,S2),
if
F1 =:= F2 ->
inter(lists:delete(F1,S1),lists:delete(F2,S2),[F1|Ret]);
F1 < F2 ->
inter(lists:delete(F1,S1),S2,Ret);
F1 > F2 ->
inter(S1,lists:delete(F2,S2),Ret)
end
end.
union(L1,L2) ->
S1 = lists:sort(L1),
S2 = lists:sort(L2),
lists:reverse(union(S1,S2,[])).
union(S1,S2,Ret) ->
Len1 = length(S1),
Len2 = length(S2),
Log = (Len1 =/= 0)
and (Len2 =/= 0),
if
Len1 =:= 0 ->
lists:append(Ret,S2);
Len2 =:=0
->
lists:append(Ret,S1);
Log =:= true ->
F1 = lists:nth(1,S1),
F2 = lists:nth(1,S2),
if
F1 =:= F2 ->
union(lists:delete(F1,S1),lists:delete(F2,S2),[F1|Ret]);
F1 =/= F2 ->
Temp = [F1|Ret],
Temp2 = [F2 | Temp],
union(lists:delete(F1,S1),lists:delete(F2,S2),Temp2)
end
end.
2013年05月23日 00点05分 11
level 11
a651944226 楼主
运算过程
求集合的交合并操作比较简单,交操作主要步骤如下:
调用lists:sort/1对两个列表进行排序;
若列表L1或列表L2为空,返回Ret,否则进入第三步;
将两个列表L1、L2首元进行比较,分三种情况,首元相等、大于、小于依次处理。
2013年05月23日 00点05分 12
level 11
a651944226 楼主

 并操作与交类似,只是在L1或L2为空时将不空的列表并入结果集Ret中,就不再详细说其步骤了。
运行结果如下
2013年05月23日 00点05分 13
level 11
a651944226 楼主

 好了,这次的学习讨论就到这了,这三个程序还是比较简单的,关键是思路要清晰,其次是要以Erlang的角度来思考问题,那么用Erlang实现这三个程序就显得简单了。接下去,我还是会探讨一些小程序,不过,我将花几个专题专门讨论Erlang中并行算法的实现,主要是并行枚举排序、并行快速排序、PSRS排序等,也算是这个实战系列最难得一部分吧
2013年05月23日 00点05分 14
1