我一直在练习使用递归来定义Erlang中的索引。在这里,我需要实现一个函数来从列表中返回列表的索引。
例如
([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).
我在逻辑上进行了修改和编码,但仍然无法编译。我希望有人可以帮助我。谢谢!
答案 0 :(得分:2)
只是为了好玩,这里的实现并不是一种非常简洁的方式,而是说明了我认为您正在寻找的技术。请注意,有两种基本状态:“检查”和“匹配”。
-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
或sets:is_subset/2
,或者对gb_tree,dict,map或array执行某些键或成员操作视情况而定。
答案 1 :(得分:0)
要编译您必须将其更改为:
的代码-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.
此代码将编译但在某些情况下会出现错误结果。