从Erlang中的列表返回列表的索引

时间:2015-12-02 04:52:37

标签: recursion erlang indexof

我一直在练习使用递归来定义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).

我在逻辑上进行了修改和编码,但仍然无法编译。我希望有人可以帮助我。谢谢!

2 个答案:

答案 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/2lists:suffix/2sets: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.

此代码将编译但在某些情况下会出现错误结果。