此代码摘自此book。
count_characters(Str) ->
count_characters(Str, #{}).
count_characters([H|T], #{ H => N }=X) ->
count_characters(T, X#{ H := N+1 });
count_characters([H|T], X) ->
count_characters(T, X#{ H => 1 });
count_characters([], X) ->
X.
所以,
1> count_characters("hello").
#{101=>1,104=>1,108=>2,111=>1}
我从中理解的是,count_characters()
接受参数 hello ,并将其放在第一个函数中,即count_characters(Str)
。
我不明白的是,字符串字符如何在不使用$
的情况下转换为ascii值,并且增加了。我对二郎很新,如果你能帮助我理解上述内容,我将非常感激。谢谢。
答案 0 :(得分:2)
在erlang中,字符串文字"hello"
只是编写列表[104,101,108,108,111]
的一种更方便的方式。字符串格式是语法糖,没有erlang在内部知道。 ascii字符串是内部字符串,内部存储为32位整数列表。
当打印值恰好在ascii范围内的列表时,这也会变得混乱:
io:format("~p~n", [[65,66]]).
将打印
"AB"
即使你没想到字符串也是如此。
答案 1 :(得分:1)
如前所述,Erlang中没有字符串数据类型,它使用整数列表的内部表示,所以
"hello" == [$h,$e,$l,$l,$o] == [104|[101|[108|[108|[111|[]]]]]]
每个都是整数列表的有效表示。
要进行字符计数,该函数使用新的Erlang数据类型:map。 (自R17起可用)
地图是键/值对的集合,在您的情况下,键将是字符,值是每个字符出现的值。
使用空地图调用该函数:count_characters(Str, #{})
。
然后它以递归方式遍历列表,并且对于每个头H
,有2个案例是可行的:
H
,然后当前地图X
将与模式#{ H => N }
匹配,告诉我们已找到N
次H
,所以我们继续递归列表的其余部分和一个新的地图,其中与H
相关联的值现在为N+1
:count_characters(T, X#{ H := N+1 }
。H
,然后我们继续使用列表的其余部分进行递归,并添加一个新地图,其中添加了键/值对H/1
:{{1} }。当到达列表的末尾时,只需返回地图:count_characters(T, X#{ H => 1 })