【发布时间】:2020-01-08 13:19:54
【问题描述】:
我想用 erlang 编程语言对列表进行搜索。
在 erlang 中,由于我们没有循环构造,我们使用递归方法来执行循环。
但是,我想知道我们怎样才能打破这个循环?
比如说,一旦我们在列表中找到所需的元素。
就像我们在 C 语言中使用 break 一样。
【问题讨论】:
标签: loops recursion erlang break
我想用 erlang 编程语言对列表进行搜索。
在 erlang 中,由于我们没有循环构造,我们使用递归方法来执行循环。
但是,我想知道我们怎样才能打破这个循环?
比如说,一旦我们在列表中找到所需的元素。
就像我们在 C 语言中使用 break 一样。
【问题讨论】:
标签: loops recursion erlang break
Elem = 3
List = [1,2,3,4,5,6]
elem_in_list(_Elem, []) -> false;
elem_in_list(Elem, [Elem | _Rest]) -> true;
elem_in_list(Elem, [_Head | Rest]) -> elem_in_list(Elem, Rest).
在上面的代码中,我们在给定的List 中寻找3。如果我们扩展它,它看起来像
elem_in_list(3, [ 1 | [2,3,4,5,6]]) % Matches [_Head | Rest]
elem_in_list(3, [ 2 | [3,4,5,6]]) % Matches [_Head | Rest]
elem_in_list(3, [ 3 | [4,5,6]]) % Matches [Elem | _Rest]
true
【讨论】:
贾斯汀的答案是正确的。您只需立即停止递归。
但有时您不是自己编写递归,而是想摆脱内部函数(如折叠中的函数)。这就是为什么 Erlang 有一个非本地返回关键字(即:throw)。
让我告诉你:
假设您想使用高阶函数在列表中找到最小的正整数。您可以将函数编写为:
min_pos_int(List) ->
lists:foldl(
fun (Int, Min) when is_integer(Int), Int > 0, Int < Min -> Int
; (_, Min) -> Min
end, infinity, List).
这会起作用,但是...您知道可能的最小正整数是多少(即1)。所以,如果你的列表有 1 作为一个元素,你可以在那里休息,对吧?
好的。在 Erlang 中,您可以使用 catch 和 throw 来做到这一点,就像这样……
min_pos_int(List) ->
catch lists:foldl(
fun (1, _) -> throw(1)
; (Int, Min) when is_integer(Int), Int > 0, Int < Min -> Int
; (_, Min) -> Min
end, infinity, List).
您也可以为此使用try…catch… 语法...
min_pos_int(List) ->
try lists:foldl(
fun (1, _) -> throw(1)
; (Int, Min) when is_integer(Int), Int > 0, Int < Min -> Int
; (_, Min) -> Min
end, infinity, List)
catch EarlyResult -> EarlyResult
end.
您可以通过以下方式检查它是否有效...
1> c(my_mod), timer:tc(my_mod, min_pos_int, [L]). % with catch & throw
{1,1}
2> c(my_mod), timer:tc(my_mod, min_pos_int, [L]). % without them
{2837520,1}
3> c(my_mod), timer:tc(my_mod, min_pos_int, [L]). % with try...catch
{7,1}
【讨论】:
您可以通过几种方法实现搜索,但是如果您需要在列表中找到第一个匹配项,您可以尝试使用具有如下条件的列表生成器:
1> [X || X <- [1, 2, 3, 4, 5], X =:= 3].
[3]
所以,我想你可以尝试在一些 case 块中使用它,例如:
case [X || X <- [1, 2, 3, 4, 5], X =:= 3] of
[_] -> find;
[] -> not_found
end.
【讨论】: