我有一个字符串:
“abc abc abc abc”
如何计算“abc”重复次数?
答案 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", " "))).