我正在尝试计算Elixir中字符串上的重复字母.我确实尝试了一些尝试,但直到现在都没有成功.
我们以此字符串为例: "AAABBAAC"
期望的输出将是"3A2B2A1C".
将此字符串转换为a List,我能够计算每个字母"5A2B1C",但是我必须按照顺序计算.
这是我正在做的代码:
string
|> String.graphemes
|> Enum.reduce([], fn(letter, acc) -> Keyword.update(acc, letter, 1, &(&1 + 1)) end)
Run Code Online (Sandbox Code Playgroud)
但是,在我的测试中,我正在尝试生成一个List,就像这样["AAA", "BB", "AA", "C"],所以我可以轻松地计算String.lenght.
有没有办法产生这个?
提前致谢.
更新:
看起来像使用Enum.chunk_by我越来越接近解决方案.
更新2:
有人可以告诉我为什么这个问题被标记为-1?正如你所看到的,我对StackOverflow很新,所以我想以正确的方式做到这一点.
更新3:
在主要问题中添加了一些代码,遵循社区中的最佳实践,以避免混淆和关闭主题的投票.无论如何,这个问题已经解决了.
如果使用递归方法实现此操作,则可以轻松跟踪最后发生的字符及其当前计数,以及到目前为止保存结果的累加器.如果当前字符等于最后一个字符,则只需增加计数.如果两者不同,则将最后一个字符及其计数添加到累加器,然后继续执行下一个字符,直到字符串为空.最后,编码最终值并返回结果.
defmodule RunLengthEncoding do
# public interface, take first char and remember it as the current value
def encode(<<char::utf8, rest::binary>>) do
do_encode(rest, char, 1, "")
end
# current == last, increase the count and proceed
defp do_encode(<<char::utf8, rest::binary>>, char, count, acc) do
do_encode(rest, char, count + 1, acc)
end
# current != last, reset count, encode previous values and proceed
defp do_encode(<<char::utf8, rest::binary>>, last, count, acc) do
do_encode(rest, char, 1, acc <> to_string(count) <> <<last::utf8>>)
end
# input empty, encode final values and return
defp do_encode("", last, count, acc) do
acc <> to_string(count) <> <<last::utf8>>
end
end
Run Code Online (Sandbox Code Playgroud)