syntax - 帮我改进这个Erlang?

标签 syntax erlang roman-numerals

所以我对 Erlang 非常感兴趣。我找不到借口将它用于任何大事,但我不时尝试将其用于玩具问题。

现在,我正在实现一个罗马数字翻译器。我现在只是在做“到”部分,我发现代码非常重复。它就像一个魅力,但是,好吧,看看它:

-module(roman).
-compile([export_all]).

toRoman(N) ->
    toRoman(N, []).

toRoman(0,Acc) ->
    lists:reverse(lists:flatten(Acc));

toRoman(N, Acc) when N >= 1000 ->
    toRoman(N-1000,["M"|Acc]);

toRoman(N,Acc) when N >= 900 ->
    toRoman(N-900,["CM" | Acc]);

toRoman(N,Acc) when N >= 500 ->
    toRoman(N-500,["D" | Acc]);

toRoman(N,Acc) when N >= 400 ->
    toRoman(N-400, ["CD" | Acc]);

toRoman(N,Acc) when N >= 100 ->
    toRoman(N-100, ["C" | Acc]);

toRoman(N,Acc) when N >= 90 ->
    toRoman(N-90, ["XC" | Acc]);

toRoman(N,Acc) when N >= 50 ->
    toRoman(N-50, ["L" | Acc]);

toRoman(N, Acc) when N >= 40 ->
    toRoman(N-40, ["XL" | Acc]);

toRoman(N, Acc) when N >= 10 ->
    toRoman(N-10, ["X" | Acc]);

toRoman(N, Acc) when N >= 9 ->
    toRoman(N-9, ["IX" | Acc]);

toRoman(N, Acc) when N >= 5 ->
    toRoman(N-5, ["V" | Acc]);

toRoman(N, Acc) when N >= 4 ->
    toRoman(N-4, ["IV" | Acc]);

toRoman(N, Acc) ->
    toRoman(N-1, ["I" | Acc]).

test() ->
    Test = fun(X) -> io:format("~p -> ~p~n", [X, toRoman(X)]) end,
    lists:map(Test, [0,1,3,6,23,43,75,87,13,23, 3999, 3998, 2531, 140]).

我觉得有更好的方法可以做到这一点。任何人都可以提供一些见解吗?

最佳答案

其实你的代码不是那么重复。它只是看起来像,因为文本形成了重复的模式。但是你的每个子句都处理一个特定的情况,它们之间几乎没有逻辑重叠。您可以在 switch 语句中重新实现,但会得到类似的重复。罗马数字翻译中的情况太多了,我认为您无法避免使每个单独的决定造成重复的感觉。

关于syntax - 帮我改进这个Erlang?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1678465/

相关文章:

python - 使用哪个三元运算符?

Python如何将一组元组写入csv

input - 如何在 Erlang 中读取整数?

c# - 罗马数字到整数

php - 用php将数字转换为罗马数字

vim - 在 vim 中用 clojure 的注释宏高亮显示一个表单

logging - Elixir 中磁盘上的记录器

Erlang远程过程调用模块内部结构

c - 如何将整数值转换为罗马数字字符串?

java - 为什么在 Java 中定义方法时返回类型的顺序很重要?