字符串中的Erlang重复字符串

时间:2014-07-14 21:29:04

标签: erlang

我有一个字符串:

  

“abc abc abc abc”

如何计算“abc”重复次数?

3 个答案:

答案 0 :(得分:2)

如果您正在寻找实用且高效的实施方案,即使是更长的子字符串也能很好地扩展,您可以使用binary:matches/2,3使用Boyer–Moore string search algorithm(以及Aho-Corasic用于多个子字符串)。它显然只适用于ASCII或Latin1字符串。

repeats(L, S) -> length(binary:matches(list_to_binary(L), list_to_binary(S))).

如果是出于教育目的,您可以为任何类型的列表编写自己的低效版本。如果您在编译时知道子字符串,那么您可以使用非常简单且性能不差的方法:

-define(SUBSTR, "abc").

repeats(L) -> repeats(L, 0).

repeats(?SUBSTR ++ L, N) -> repeats(L, N+1);
repeats([_|L]       , N) -> repeats(L, N);
repeats([]          , N) -> N.

如果你不了解子字符串,你可以写得更复杂,效率更低

repeats(L, S) -> repeats(L, S, 0).

repeats([], _, N) -> N;
repeats(L, S, N) ->
    case prefix(L, S) of
        {found, L2} -> repeats( L2,   S, N+1);
        nope        -> repeats(tl(L), S, N)
    end.

prefix([H|T], [H|S]) -> prefix(T, S);
prefix( L,    [   ]) -> {found, L};
prefix( _,     _   ) -> nope.

当然,你可以尝试编写一些更为复杂的变体作为简化的Boyer-Moore列表。

答案 1 :(得分:0)

1> F = fun 
  F([],_,_,N) -> N; 
  F(L,P,S,N) -> 
    case string:sub_string(L,1,S) == P of 
      true -> F(tl(string:sub_string(L,S,length(L))),P,S,N+1);
      _ -> F(tl(L),P,S,N)
    end
  end.
  #Fun<erl_eval.28.106461118>
2> Find = fun(L,P) -> F(L,P,length(P),0) end.
#Fun<erl_eval.12.106461118>
3> Find("abc abc abc abc","abc").
4
4>

如果在模块中定义,或者在shell中定义,但只能在R17中定义。

答案 2 :(得分:0)

 length(lists:filter(fun(X) -> X=="abc" end,  string:tokens("abc abc abc abc", " "))).