65.9K
CodeProject 正在变化。 阅读更多。
Home

Haskell 阿拉伯数字-罗马数字转换器(第 2 部分:将罗马数字转换为阿拉伯数字)

starIconstarIconstarIconstarIconstarIcon

5.00/5 (2投票s)

2014年6月24日

CPOL

2分钟阅读

viewsIcon

10152

downloadIcon

6

Haskell 阿拉伯数字-罗马数字转换器(第 2 部分:将罗马数字转换为阿拉伯数字)

引言

这是我之前关于将阿拉伯数字转换为罗马数字的技巧的第二部分(请参阅 阿拉伯数字-罗马数字转换器第 1 部分 获取第一部分)。

在这部分中,我想添加将罗马数字转换为阿拉伯数字的缺失部分。

背景

在公司最近的一次编码 Dojo 中,我们致力于创建一个将阿拉伯数字转换为罗马数字的 JavaScript 函数(原始任务:http://codingdojo.org/cgi-bin/index.pl?KataRomanNumerals)。

为了重温我的函数式编程技能,我决定用 Haskell 编写一个解决方案。

使用代码

将罗马数字转换为阿拉伯数字比预期的容易得多。 首先,我创建了一个罗马字符及其对应阿拉伯数字的列表(类似于上一篇文章)。 该列表用作计算的基础。

在 romanToNum 函数中,我决定处理输入字符串的三种不同情况:如果字符串为空,则返回 0;如果长度等于 1,则返回相应的整数(例如,“V” -> 5)。

否则,我们必须检查剩余的字符。 这里是有点棘手的部分:我们必须决定是添加下一个两个罗马字符的值(例如,“II”、“CX”、“XV”)还是使用减法规则(例如,“IV”、“CM”、“XC”)。 我们可以看到,如果第二个字符大于第一个字符,则必须使用减法规则(如 V > I),否则使用加法。

因此,根据我们必须使用的规则,我们从罗马数字的剩余部分(由 tl 表示,递归调用 romanToNum)中添加或减去当前值。

arabics :: Map Char Int
arabics = fromList [('I', 1), ('V', 5), ('X', 10), ('L', 50), ('C', 100), ('D', 500), ('M', 1000)]
                                
romanToNum :: [Char] -> Int
romanToNum xs = if (length xs == 0) then 0
                else if (length xs == 1) then arabics ! (head xs)
                else
                    let fst = arabics ! (xs !! 0)
                        snd = arabics ! (xs !! 1)
                        tl = romanToNum (tail xs)
                    in if (fst < snd) then tl - fst else tl + fst

关注点

注意: “错误”的罗马文字会导致不正确的阿拉伯数字。 没有逻辑来检测特殊情况,因此仅使用正确的罗马文字!

我将(现在完整的)NumberConverter.hs 模块添加到文章中,以便您可以自行测试这两种转换。

经过一番调整,我很高兴能够找到如此小的解决方案。 请记住,我不是 Haskell 专家。 再次,欢迎留下任何提示或关于代码的问题。

© . All rights reserved.