在 JavaScript 中将数字转换为罗马数字
如何将整数转换为罗马数字?
function romanNumeralGenerator (int) {
}
例如,请参阅以下示例输入和输出:
1 = "I"
5 = "V"
10 = "X"
20 = "XX"
3999 = "MMMCMXCIX"
注意:仅支持 1 到 3999 之间的数字
How can I convert integers into roman numerals?
function romanNumeralGenerator (int) {
}
For example, see the following sample inputs and outputs:
1 = "I"
5 = "V"
10 = "X"
20 = "XX"
3999 = "MMMCMXCIX"
Caveat: Only support numbers between 1 and 3999
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(30)
我使用谷歌发现这个博客上有一篇不错的文章:
http://blog .stevenlevithan.com/archives/javascript-roman-numeral-converter
There is a nice one here on this blog I found using google:
http://blog.stevenlevithan.com/archives/javascript-roman-numeral-converter
转发自 2008 年的评论,网址为:http://blog.stevenlevithan。 com/archives/javascript-roman-numeral-converter
查看演示
Reposted from a 2008 comment located at: http://blog.stevenlevithan.com/archives/javascript-roman-numeral-converter
VIEW DEMO
我不明白为什么大家的解决方案都那么长并且使用了多个for循环。
I don't understand why everyone's solution is so long and uses multiple for loops.
我开发了下面的递归解决方案。该函数返回一个字母,然后调用自身返回下一个字母。它会一直这样做,直到传递给函数的数字为
0
,这意味着所有字母都已找到,我们可以退出递归。I've developed the recursive solution below. The function returns one letter and then calls itself to return the next letter. It does it until the number passed to the function is
0
which means that all letters have been found and we can exit the recursion.我个人认为最简洁的方法(无论如何不是最快的)是递归。
这仅支持数字1-40,但可以通过遵循该模式轻松扩展。
I personally think the neatest way (not by any means the fastest) is with recursion.
This will only support numbers 1-40, but it can easily be extended by following the pattern.
这些函数将任何正整数转换为其等效的罗马数字字符串;及其编号的任何罗马数字。
数字到罗马数字:
罗马数字字符串到数字:
These functions convert any positive whole number to its equivalent Roman Numeral string; and any Roman Numeral to its number.
Number to Roman Numeral:
Roman Numeral string to Number:
此版本不需要像其他版本那样针对边缘情况(例如
4(IV)、9(IX)、40(XL)、900(CM) 等
)进行任何硬编码逻辑。我已经针对 1-3999 的数据集测试了此代码,它有效。
太长了;
这也意味着该解决方案可以处理大于最大罗马刻度 (3999) 的数字。
似乎有一个交替规则来决定下一个主要罗马数字字符。从 I 开始,乘以 5 得到下一个数字 V,然后乘以 2 得到 X,然后乘以 5 得到 L,然后乘以 2 得到 C,依此类推得到音阶中的下一个主要数字字符。在这种情况下,我们假设“T”被添加到刻度中,以允许比原始罗马刻度允许的 3999 更大的数字。为了保持相同的算法,“T”将代表 5000。
这可以让我们代表从 4000 到 5000 的数字;例如,MT = 4000。
代码:
This version does not require any hard coded logic for edge cases such as
4(IV),9(IX),40(XL),900(CM), etc.
as the others do.I have tested this code against a data set from 1-3999 and it works.
TLDR;
This also means this solution can handle numbers greater than the maximum roman scale could (3999).
It appears there is an alternating rule for deciding the next major roman numeral character. Starting with I multiply by 5 to get the next numeral V and then by 2 to get X, then by 5 to get L, and then by 2 to get C, etc to get the next major numeral character in the scale. In this case lets assume "T" gets added to the scale to allow for larger numbers than 3999 which the original roman scale allows. In order to maintain the same algorithm "T" would represent 5000.
This could then allow us to represent numbers from 4000 to 5000; MT = 4000 for example.
Code:
我知道这是一个老问题,但我对这个解决方案感到非常自豪:)它只能处理小于 1000 的数字,但可以通过添加到“numeralCodes”二维数组来轻松扩展以包含您需要的大小。
I know this is an old question but I'm pretty proud of this solution :) It only handles numbers less than 1000 but could easily be expanded to include however large you'd need by adding on to the 'numeralCodes' 2D array.
循环可能更优雅,但我发现它们很难阅读。想出了一个或多或少的硬编码版本,看起来很容易。只要你理解了第一行,剩下的就很简单了。
Loops may be more elegant but I find them hard to read. Came up with a more or less hard coded version that's easy on the eyes. As long as you understand the very first line, the rest is a no-brainer.
我创建了两个转换函数。
第一个函数可以使用reduce 将数字转换为罗马数字。
第二个函数与第一个函数非常相似,函数使用相同的方式来转换值。
您需要更改的所有内容都是
_roman
属性。因为您必须根据需要扩展此常量,所以我在那里放置了最大数量1000
但您可以放置更多。您可以在这里找到更大的罗马数字 https://www.tuomas .salste.net/doc/roman/numeri-romani.html
I created two convert functions.
The first function can convert numbers to roman using reduce.
And the second function is very similar to the first function, the function uses the same way to convert the value.
Everything that you need to change is the
_roman
property. Because you have to extend this const with scale what you want, I place there max number1000
but you can put more.Larger scale with roman numbers you can find here https://www.tuomas.salste.net/doc/roman/numeri-romani.html
这是递归的解决方案,看起来很简单:
Here is the solution with recursion, that looks simple:
JavaScript
许多其他建议可以在 http:// 找到blog.stevenlevithan.com/archives/javascript-roman-numeral-converter
JavaScript
many other suggestions can be found at http://blog.stevenlevithan.com/archives/javascript-roman-numeral-converter
我创建了两个孪生数组,一个包含阿拉伯数字,另一个包含罗马字符。
然后我添加了一个扫描罗马元素的循环,将 NUM 中仍然包含的最大元素添加到 RESULT,然后我们减少相同数量的 NUM。
这就像我们将 NUM 的一部分映射为罗马数字,然后将其减少相同的数量。
I created two twin arrays one with arabic numbers the other with the roman characters.
Then I added a cycle which scan the roman elements, adding the biggest still comprised in NUM to RESULT, then we decrease NUM of the same amount.
It is like we map a part of NUM in roman numbers and then we decrease it of the same amount.
我还没有看到这篇文章,所以这里有一个仅使用字符串操作的有趣解决方案:
I didn't see this posted already so here's an interesting solution using only string manipulation:
此函数会将任何小于 3,999,999 的数字转换为罗马数字。请注意,大于 3999 的数字将位于
text-decoration
设置为overline
的标签内,这将添加正确表示的overline
对于 x1000,当数字大于 3999 时。四百万 (4,000,000) 将是带有两个上划线的 IV,因此,您需要使用一些技巧来表示,也许是带有
border-top
的DIV
,或带有这两个overline
的背景图像...每个overline
代表 x1000 。This function will convert any number smaller than 3,999,999 to roman. Notice that numbers bigger than 3999 will be inside a label with
text-decoration
set tooverline
, this will add theoverline
that is the correct representation for x1000 when the number is bigger than 3999.Four million (4,000,000) would be IV with two
overline
s so, you would need to use some trick to represent that, maybe aDIV
withborder-top
, or some background image with those twooverline
s... Eachoverline
represents x1000.如果您想转换带有更多符号的大数字,也许这个算法可以提供帮助。
符号的唯一前提是必须是奇数并遵循相同的规则(1, 5, 10, 50,100 ...., 10^(N)/2, 10^(N))。
If you want to convert a big number with more symbols, maybe this algo could help.
The only premise for symbols is that must be odd and follow the same rule (1, 5, 10, 50,100 ...., 10^(N)/2, 10^(N)).
在测试了本文中的一些实现之后,我创建了一个新的优化实现,以便执行得更快。与其他程序相比,执行时间确实很短,但显然代码更丑陋:)。
使用具有所有可能性的索引数组可能会更快。
以防万一它对某人有帮助。
After testing some of the implementations in this post, I have created a new optimized one in order to execute faster. The time execution is really low comparing with the others, but obviously the code is uglier :).
It could be even faster with an indexed array with all the posibilities.
Just in case it helps someone.
此函数适用于每个数字中的不同字符集。要添加另一个数字,请在第 1 位、第 5 位和下一个 1 位添加罗马数字字符串。这很好,因为您只需知道下一组使用的字符即可更新它。
This function works on the the different character sets in each digit. To add another digit add the roman numeral string the 1 place, 5 place and next 1 place. This is nice because you update it with only knowing the next set of characters used.
我刚刚在 freecodecamp 上做了这个。它可以很容易地扩展。
I just made this at freecodecamp. It can easily be expanded.
这是一个正则表达式解决方案:
Here's a regular expression solution:
我真的很喜欢 jaggedsoft 的解决方案,但我无法回复,因为我的代表太低了:( :(
我将其分解,为那些不理解的人解释一下。希望它对某人有所帮助。
I really liked the solution by jaggedsoft but I couldn't reply because my rep is TOO LOW :( :(
I broke it down to explain it a little bit for those that don't understand it. Hopefully it helps someone.
如果 HTMLElement 中有此数字(例如 span),我们建议添加 HTML attribute
data-format
:IF this number in HTMLElement (such as span), we recommend to Add HTML attribute
data-format
:这适用于仅需要罗马数字 M 及以下的所有数字。
This works for all numbers only in need of roman numerals M and below.
这是我第一次真正陷入 freecodecamp。我仔细阅读了这里的一些解决方案,并对它们的不同感到惊讶。这就是最终对我有用的东西。
This is the first time I really got stuck on freecodecamp. I perused through some solutions here and was amazed at how different they all were. Here is what ended up working for me.