了解素数发生器

时间:2014-03-16 13:40:55

标签: algorithm erlang primes

This site显示了一个生成素数列表的函数。

-module(eratosthenes).
-export([prime_numbers/1]).

% Sieve of Eratosthenes algorithm for finding all prime numbers up to N.
% http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes

% Generate list of prime numbers up to N.
prime_numbers(N) when is_number(N) ->
prime_numbers(N, generate(N)).

prime_numbers(Max, [H|T]) when H * H =< Max ->
   [H | prime_numbers(Max, [R || R <- T, (R rem H) > 0])];

prime_numbers(_, T) -> T.

% Generate sequence 2..N
generate(N) -> generate(N, 2).

generate(Max, Max) -> [Max];

generate(Max, X) -> [X | generate(Max, X + 1)].

我不明白这个功能:

prime_numbers(_, T) -> T.

我使用笔和纸做了这个例子:

prime_numbers(5)

1 - prime_numbers(5, [2,3,4,5])
2 - [2 | prime_numbers(5, [R || R <- [3,4,5], (R rem H) > 0)]
3 - [2 | prime_numbers(5, [3,5])]

prime_numbers(5, [3,5])

H * H =< MAX

3*3 =< 5 (False)

prime_numbers(_, T) -> T.

H = 3
T = 5

prime_numbers(5, [3,5]) = [5]

resp: [2,5]


or prime_numbers(5, [3,5]) = [3|[5]]

1 个答案:

答案 0 :(得分:2)

要理解这一点,你必须看看整个功能:

prime_numbers(Max, [H|T]) when H * H =< Max ->
   [H | prime_numbers(Max, [R || R <- T, (R rem H) > 0])];
prime_numbers(_, T) -> T.

我删除了换行符,因为在这种情况下它并不真正适用。 Erlang中的成语是将子句保存在一起,就像这样。请注意,此函数有两个子句。我们模式匹配对他们 [0] 。所以这就是:

&#34;假设我们得到一个名为Max的东西和一个至少有一个[H|T]元素的列表。将列表解构为头元素H和列表T的其余部分。现在,此模式具有when防护,因此仅适用于H*H =< Max

如果这不匹配,请说明when后卫是错误还是我们获得了空列表[],那么我们会尝试匹配下一个子句{{1} }。这个总是匹配并抛弃第一个参数((_, T))。然后它匹配第二个参数中的任何内容并将其绑定到_。然后它运行它的身体。&#34;

理解这一点的关键是理解模式匹配。一旦你掌握了这些,代码应该清晰易读。

[0] 查找模式匹配的概念。它是许多语言的核心,如Prolog,ML,Haskell,Erlang,......