Return Erlang 列表中列表的索引
Return the index for a list from a list in Erlang
我一直在练习使用递归在 Erlang 中定义索引。在这里,我需要实现一个函数来 return 列表中列表的索引。
例如
([2, 4, 4], [1, 1, 2, 4, 4, 3, 4 ]) ----> 2
([1, 3], [5, 2, 2, 3, 1, 3, 5]) ----> 4
([1], [3, 2, a, {1, 1}, 1] ----> 4
这是我的代码:
-module(project).
-export([index/2]).
index([X|XS],[_]) -> index([X|XS],[_],1).
index(_,[],_) -> [];
index([X|XS],[X|_], ACC) -> ACC;
index([X|XS],[_|rest],ACC) ->index([X|XS],rest,ACC+1).
我按逻辑修改编码,还是编译不出来。我希望有人能帮助我。谢谢!
要编译代码,您必须将其更改为:
-module(project).
-export([index/2]).
%%index([X|XS],[_]) -> index([X|XS],[_],1).
index([X|XS],List) -> index([X|XS],List,1).
%% you shuld not pass '_' as parameter it's will be marked as unbound
index(_,[],_) -> [];
index([X|XS],[X|_], ACC) -> ACC;
%%index([X|XS],[_|rest],ACC) ->index([X|XS],rest,ACC+1).
index([X|XS],[_|Rest],ACC) ->index([X|XS],Rest,ACC+1).
%% rest is an atom, it's not the case you need to use here.
%%Variables should start with upper case letter.
这段代码会编译但在某些情况下会出现错误的结果。
只是为了好玩,这里是一个不是以非常干净的方式编写的实现,但说明了我认为您正在寻找的技术。注意有两种基本状态:"checking" 和 "matching".
-module(sublistmatch).
-export([check/2]).
check(Segment, List) ->
SegLen = length(Segment),
ListLen = length(List),
Index = 1,
check(Segment, List, SegLen, ListLen, Index).
check(S, S, _, _, I) ->
{ok, I};
check(_, _, SL, LL, _) when SL >= LL ->
nomatch;
check(S = [H|Ss], [H|Ls], SL, LL, I) ->
case matches(Ss, Ls) of
true -> {ok, I};
false -> check(S, Ls, SL, LL - 1, I + 1)
end;
check(S, [_|L], SL, LL, I) ->
check(S, L, SL, LL - 1, I + 1).
matches([H|S], [H|L]) -> matches(S, L);
matches([], _) -> true;
matches(_, _) -> false.
请注意,这取决于了解您正在检查的段的长度以及要检查的剩余列表的当前长度。考虑为什么这是必要的。还要考虑使用效用函数 matches/2
如何为我们提供一个自然的地方来探索选项是否匹配,如果不匹配则回溯。
在实际程序中,您将使用标准库函数,例如 lists:prefix/2
, lists:suffix/2
, or sets:is_subset/2
,或者根据情况对 gb_tree、字典、映射或数组进行一些键或成员操作。
我一直在练习使用递归在 Erlang 中定义索引。在这里,我需要实现一个函数来 return 列表中列表的索引。
例如
([2, 4, 4], [1, 1, 2, 4, 4, 3, 4 ]) ----> 2
([1, 3], [5, 2, 2, 3, 1, 3, 5]) ----> 4
([1], [3, 2, a, {1, 1}, 1] ----> 4
这是我的代码:
-module(project).
-export([index/2]).
index([X|XS],[_]) -> index([X|XS],[_],1).
index(_,[],_) -> [];
index([X|XS],[X|_], ACC) -> ACC;
index([X|XS],[_|rest],ACC) ->index([X|XS],rest,ACC+1).
我按逻辑修改编码,还是编译不出来。我希望有人能帮助我。谢谢!
要编译代码,您必须将其更改为:
-module(project).
-export([index/2]).
%%index([X|XS],[_]) -> index([X|XS],[_],1).
index([X|XS],List) -> index([X|XS],List,1).
%% you shuld not pass '_' as parameter it's will be marked as unbound
index(_,[],_) -> [];
index([X|XS],[X|_], ACC) -> ACC;
%%index([X|XS],[_|rest],ACC) ->index([X|XS],rest,ACC+1).
index([X|XS],[_|Rest],ACC) ->index([X|XS],Rest,ACC+1).
%% rest is an atom, it's not the case you need to use here.
%%Variables should start with upper case letter.
这段代码会编译但在某些情况下会出现错误的结果。
只是为了好玩,这里是一个不是以非常干净的方式编写的实现,但说明了我认为您正在寻找的技术。注意有两种基本状态:"checking" 和 "matching".
-module(sublistmatch).
-export([check/2]).
check(Segment, List) ->
SegLen = length(Segment),
ListLen = length(List),
Index = 1,
check(Segment, List, SegLen, ListLen, Index).
check(S, S, _, _, I) ->
{ok, I};
check(_, _, SL, LL, _) when SL >= LL ->
nomatch;
check(S = [H|Ss], [H|Ls], SL, LL, I) ->
case matches(Ss, Ls) of
true -> {ok, I};
false -> check(S, Ls, SL, LL - 1, I + 1)
end;
check(S, [_|L], SL, LL, I) ->
check(S, L, SL, LL - 1, I + 1).
matches([H|S], [H|L]) -> matches(S, L);
matches([], _) -> true;
matches(_, _) -> false.
请注意,这取决于了解您正在检查的段的长度以及要检查的剩余列表的当前长度。考虑为什么这是必要的。还要考虑使用效用函数 matches/2
如何为我们提供一个自然的地方来探索选项是否匹配,如果不匹配则回溯。
在实际程序中,您将使用标准库函数,例如 lists:prefix/2
, lists:suffix/2
, or sets:is_subset/2
,或者根据情况对 gb_tree、字典、映射或数组进行一些键或成员操作。