我的问题与Find the longest substring in a string完全相同
但与长生不老药有关
我当前的实现非常难看:
str = "aabbbssssssggssrrrr"
String.split(str, "") |> Enum.chunk_while([], fn elem, acc ->
cond do
(length(acc) == 0) ->
{:cont, [elem]}
(acc == [""]) ->
{:cont, [elem]}
(List.last(acc) == elem) ->
{:cont, [elem | acc]}
true ->
{:cont, Enum.reverse(acc), []}
end
end,
fn
[] -> {:cont, []}
acc -> {:cont, Enum.reverse(acc), []}
end) |> Enum.map(fn e -> Enum.reduce(e, "", &<>/2) end) |> Enum.max_by(&String.length/1)
是否有可能像红宝石或至少更短的东西写单线?
具有块的链接ruby解决方案非常差。它执行一些绝对不需要的操作,例如拆分,连接等,这可能会大大降低长输入的性能。
最简单的方法是将正则表达式与back reference一起使用。
str = "aabbbssssssggssrrrr"
Regex.scan(~r/(.)\1{1,}/, str, capture: :first)
#⇒ [["aa"], ["bbb"], ["ssssss"], ["gg"], ["ss"], ["rrrr"]]
例如,现在优先选择最长的字符串:
~r/(.)\1{1,}/
|> Regex.scan(str, capture: :first)
|> Enum.sort_by(&-String.length(hd(&1)))
|> hd()
|> hd()
#⇒ "ssssss"
或带有List.flatten/1
~r/(.)\1{1,}/
|> Regex.scan(str, capture: :first)
|> List.flatten()
|> Enum.sort_by(&-String.length(&1))
|> hd()
#⇒ "ssssss"
最elixirish解决方案是使用Enum.reduce/3
,这使该Enum.reduce/3
只需输入一次即可。
O(N)