关于erlang地图,列表和ascii的混淆

时间:2014-09-13 09:04:37

标签: erlang

此代码摘自此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值,并且增加了。我对二郎很新,如果你能帮助我理解上述内容,我将非常感激。谢谢。

2 个答案:

答案 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 }匹配,告诉我们已找到NH ,所以我们继续递归列表的其余部分和一个新的地图,其中与H相关联的值现在为N+1count_characters(T, X#{ H := N+1 }
  • 第一次找到字符H,然后我们继续使用列表的其余部分进行递归,并添加一个新地图,其中添加了键/值对H/1:{{1} }。

当到达列表的末尾时,只需返回地图:count_characters(T, X#{ H => 1 })