Algorithm 理解素数发生器

Algorithm 理解素数发生器,algorithm,erlang,primes,Algorithm,Erlang,Primes,显示一个生成素数列表的函数 -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

显示一个生成素数列表的函数

-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(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]]
素数(5)
1-素数(5,[2,3,4,5])
2-[2 |素数(5[R | | r0)]
3-[2 |素数(5[3,5])]
素数(5,[3,5])
H*H=T。
H=3
T=5
素数(5[3,5])=[5]
响应:[2,5]
或素数(5,[3,5])=[3 |[5]]

要理解这一点,您必须了解整个函数:

prime_numbers(Max, [H|T]) when H * H =< Max ->
   [H | prime_numbers(Max, [R || R <- T, (R rem H) > 0])];
prime_numbers(_, T) -> T.
当H*H= [H |素数(Max[R | | r0]); 素数(u,T)->T。 我删除了一个换行符,因为它在本例中并不真正适用。Erlang中的习惯用法是将函数的子句保持在一起,如下所示。请注意,此函数有两个子句。我们对它们进行模式匹配[0]。因此如下所示:

“假设我们得到一个名为
Max
的东西,以及一个至少包含一个元素的列表,该列表具有
[H | T]
。将该列表解构为head元素
H
和列表的其余部分
T
。现在,该模式具有
when
保护,因此仅当
H*H=
时才适用

如果这不匹配,比如说当
保护错误时,
,或者给我们一个空列表,
[]
,那么我们尝试匹配下一个子句,
(\uu,t)
。这个子句始终匹配并丢弃第一个参数(
)。然后它匹配第二个参数中的任何内容,并将其绑定到
T
。然后它运行其主体。“

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


[0]查找模式匹配的概念。它是许多语言(如Prolog、ML、Haskell、Erlang等)的核心。您的问题是什么?另外,在您的示例中,T=[3,5],因此输出是正确的素数(5[3,5])
H*H=
3*3=<5(False)
素数(\uu,T)->T.
——在这一点上,
T=[3,5]
,在这一条款中没有将其解构为
H
T
。因此,
素数(5,[3,5])->[3,5]
。当然,由于它通过试除(
mod
)过滤出数字,这不是Eratosthenes的筛子。这是有界的(即,具有上限值)最优(因为它在sqrt处停止)试验分割筛选。我认为您应该指出在哪一点OPs跟踪是错误的OK,但是当我们有案例素数(5,[3,5])时会发生什么?
prime_numbers(Max, [H|T]) when H * H =< Max ->
   [H | prime_numbers(Max, [R || R <- T, (R rem H) > 0])];
prime_numbers(_, T) -> T.