3

我目前正在写一个罗马数字转换器来取乐。该问题适用于上述字符优先级。

由于罗马数字不是位置数字,即 III 不表示 1*whatever base^2 + 1*whatever base^1 + 1*whatever base^0。

当有人输入 XIV 时,这当然会变得很困难,我需要确保在这种情况下不添加 I,而是减去。我不知道该怎么做。解决这个问题的最佳方法是什么?

我将罗马符号及其各自的十进制数字都存储在数组中:

const char cRomanArray[] = "IVXLCDM";
const int romanArray[]   = { 1, 5, 10, 50, 100, 500, 1000 };

所以通过简单地检查数组中的优先级,即如果符号小于下一个符号,即在示例“XIV”中,如果“I”更小,我就不会太难暴力破解该死的东西比'V',在这种情况下,这是因为我已将它们排序在数组中,然后我可以让它减去值而不是加法。

但这似乎是一个非常丑陋的解决方案。有没有更好的?我在想一些类似于正则表达式的东西(如果这听起来像一个可怕的想法,请原谅我,我还没有使用过 RegExp,但听起来它可以满足我的需要,那就是确定字符串中的字符.)

4

2 回答 2

3

Start from the right. Moving to the left, add the values as long as they increase (or remain the same), and subtract when they decrease.

e.g. for XLIV

Start at V, add 5.
Move to I, it's less, so subtract 1.
Move to L, it's greater, add 50.
Move to X, it's less, so subtract 10.

And you get 44, which is correct.


Alternatively, you can actually treat it as base 10, except exchange 1...9 with I, II, III, IV... IX and 10...90 with X, XX, XXX, LX....XL, L and so on.

Read in the I&V characters, convert them to 1-9, then read in the X&L characters, covert them to 10-90, and so on.

于 2010-04-03T08:23:09.720 回答
1

罗马数字在某种意义上是有位置的,只是每个位置可能有多个字符代表十进制数字,符号随十进制大小而变化,不使用零作为占位符。

因此使用查找表:

// Decimal digit lookup tables
static const char* thousands[] = { "", "M", "MM", "MMM" } ;
static const char* hundreds[] = { "", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM" } ;
static const char* tens[] = { "", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC" } ;
static const char* units[] = { "", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX" } ;
static const char** digits[] = { thousands, hundreds, tens, units } ;

然后对于从左到右的每个十进制数字(从千位开始),在上面的查找表中查找 'digits[magnitude][decimal]' 并将子字符串附加到输出。请注意,零没有罗马数字,因此简单地省略了零。

因此,例如 1234 将被翻译为“M”+“CC”+“XXX”+“IV”=“MCCXXXIV”。

要了解其工作原理,请参阅Wikipedia 中罗马数字的解释:罗马数字 - 符号,特别是“符号”部分中的最后一个表(即进行研究 - 即使您认为自己理解一个主题!)。请注意,大于 3999 的数字需要非 ASCII 符号,因此我的表限制为 1 到 3999,但您也许可以使用 Unicode 解决方案来解决这个问题。

曾经为面试做过一次,我有一个基于上表的完全工作的实现,但是因为你这样做是为了好玩而省略了它,而且为你完成它可能没有乐趣。但是,如果您想要更多的指针或提示,甚至是整个解决方案,请询问。

于 2010-04-03T09:04:09.187 回答