Chinaunix首页 | 论坛 | 博客
  • 博客访问: 43001
  • 博文数量: 6
  • 博客积分: 1445
  • 博客等级: 上尉
  • 技术积分: 90
  • 用 户 组: 普通用户
  • 注册时间: 2007-03-26 22:18
文章分类

全部博文(6)

文章存档

2012年(1)

2011年(1)

2009年(2)

2008年(2)

我的朋友
最近访客

分类:

2009-08-14 01:23:32

最近在学Erlang,因为头一回接触FP,所以找了几个老掉牙的题目练习一下。

1. Hello World

hello.erl:

-module(hello).

-export([hello/0]).


hello() -> io:format("Hello World~n").

这是传统,没啥可说的....

2. 分解质因数
prime.erl:

-module(prime).

-export([factors/1]).


factors(N) -> lists:reverse(factors(2, N, [])).


factors(_, N, L) when N =< 1 ->

    L;

factors(P, N, L) when N rem P =:= 0 ->

    factors(P, N div P, [P | L]);

factors(P, N, L) ->

    factors(P+1, N, L).

调用prime:factor(N)返回一个由N的所有质因数组成的列表。例如:
1> prime:factors(60).
[2,2,3,5]
factors/3的第三个参数L是用来保存中间结果的。

3. 汉诺塔
hanoi.erl:

-module(hanoi).

-export([hanoi/1]).


hanoi(N) when N < 1 -> [];

hanoi(N) -> hanoi(N, a, b, c).


hanoi(1, A, _, C) -> [{A, C}];

hanoi(N, A, B, C) ->

    hanoi(N-1, A, C, B) ++ [{A, C}] ++ hanoi(N-1, B, A, C).

这个应该算得上是教科书中的保留题目了,给新人讲递归的最好例子。拿FP来写这种递归问题肯定是再顺手不过了,因为根本就没有循环让你用....
调用hanoi:hanoi(N)返回一个列表,表示移动的步骤,其中每个元素都是一个二元元组{A,C}表示将盘子从某位置A移动到某位置C。例如:
1> L = hanoi:hanoi(3).
[{a,c},{a,b},{c,b},{a,c},{b,a},{b,c},{a,c}]
可以像这样把它格式化输出下:
2> lists:foreach(fun({A,C})->io:format("~p => ~p~n",[A,C]) end, L).            
a => c
a => b
c => b
a => c
b => a
b => c
a => c
ok

4. N皇后

-module(queens).

-export([queens/1]).


queens(N) -> queens(N, [], 0, 0).


queens(N, _L, N, R) -> R;

queens(N, L, _X, R) when length(L) =:= N ->

    io:format("~p~n", [L]),

    R + 1;

queens(N, L, X, R) ->

    D = length(L),

    Checked = is_checked(L, X, D),

    R1 = if Checked -> queens(N, [X | L], 0, R);

    true -> R end, queens(N, L, X+1, R1).

is_checked([], _, _) -> true;

is_checked([H|T], X, D) ->

    if

        H =:= X ->false;

        abs(X - H) =:= abs(length(T) - D) -> false;

        true -> is_checked(T, X, D)

    end.

N*N的棋盘摆N个皇后,要求不能互吃,有多少种摆法?也是老掉牙的题目了。
调用queens:queens(N),返回解的个数。具体的解在找到之后直接输出了,改改代码,可以变成返回具体解法的解集合,一个解用一个长度为N的列表表示,下标值表示行,值表示列,不细说了。例如:
1> queens:queens(4).
[2,0,3,1]
[1,3,0,2]
2

没有循环,变量不变...感觉不习惯(嗯,还挺押韵的,呵呵)。
Erlang中不再有命令式语言中各种变量相关的概念,什么全局、静态、成员、公有、私有,统统没有了,只有函数内部变量。感觉概念少了,操心的事也就少了,理解起来很容易。这样带来的不便就是你不能再像以前那样随手弄个成员变量或者静态变量来保存中间状态了,所有状态都只能在函数内部保。于是参数列表就成了命根子,同时因为变量不变又得为中间变量起个名字...这是我感到最头疼的事儿了。这样带来的好处就是便于并发了,没有共享,就不需要再为“锁”事操心。好处应该不只这一点,还有很多,我还得慢慢体会去。
阅读(738) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~