Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >算法分析:阿拉伯数字与罗马数字的互相转换

算法分析:阿拉伯数字与罗马数字的互相转换

作者头像
青南
发布于 2019-03-19 08:06:38
发布于 2019-03-19 08:06:38
1.3K00
代码可运行
举报
文章被收录于专栏:未闻Code未闻Code
运行总次数:0
代码可运行

在看《Dive into Python》的单元测试时,发现用作例子的“阿拉伯数字-罗马数字”的转换算法非常的巧妙,现在发上来和大家分享一下。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    romanNumeralMap = (('M',1000),            ('CM',900),            ('D',500),            ('CD',400),            ('C',100),            ('XC',90),            ('L',50),            ('XL',40),            ('X',10),            ('IX',9),            ('V',5),            ('IV',4),            ('I',1))    def toRoman(n):        result = ""        for numeral, integer in romanNumeralMap:            while n >= integer:                result += numeral                n -= integer        return result
    def fromRoman(s):        result = 0        index = 0        for numeral, integer in romanNumeralMap:            while s[index:index+len(numeral)] == numeral:                result += integer                index += len(numeral)        return result
    print toRoman(1356)    print fromRoman('MCMLXXII')

这个算法的聪明之处,就在于他通过一个romanNumeralMap,把罗马数字与阿拉伯数字里面的“边界值”做出一一对应。这个边界刚刚好是罗马数字组合之间的转换。例如,I,II,III都可以通过第一个边界值组合获得;V,VI,VII,VIII可以通过V和I的组合获得。而对于一些特殊的值,则直接列出来。例如IV。通过这个边界值的组合,就能实现所需求的转换。这就类似于在一些机读卡上,需要填写1到100的数字,他会使用0,1,2,4,7这样以来:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    3 = 1 + 2;    5 = 4 + 1;    6 = 4 + 2;    8 = 7 + 1;    9 = 7 + 2.

首先看一下toRoman()函数,把阿拉伯数字转换成罗马数字。它使用Python连接字符串的操作符号 + 来使“边界值”连接到一起。例如用作例子的n = 1356,程序遍历romanNumeralMap,寻找n对应的罗马数字,如果找不到,那就找刚刚比n小一点的数字对应的罗马字符。遍历在能使n 在romanNumeralMap有对应值时结束。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
找到刚刚比1356小的那个值对应的罗马数字,也就是1000M再继续找刚刚比n = 1356 - 1000 = 356小的数,也就是100C;又继续找比n = 356 - 100 = 256小的数,还是100,也就是C;再找比n = 256 - 100 = 156小的数,仍然是100C;继续找比n = 156 - 100 = 56 小的数,50L;继续找比n = 56 - 50 = 6小的数,5V;继续找n = 6 - 5 = 1对于的数,1I。 结束。

所以1356对应的值为MCCCLVI。 这样的操作很类似于在十进制里面,一个数字1356 = 1000 + 300 + 50 + 6,只是阿拉伯数字里面6是一个单独的符号,而罗马数字里面VI是个V + I的组合而已。

下面再说说fromRoman()函数,把罗马数字转换成阿拉伯数字。这个函数在理解上面可能比toRoman()稍稍要困难一点。

还是用例子来说明,MCMLXXII转换成阿拉伯数字。 其中如下代码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    s[index:index+len(numeral)]

作用是把字符串s中,从第index位到第index+ len(numeral)位(不包含第index + len(numeral)位自身)的字符提取出来。比如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
>>> a = 'helloworld'>>> print a[2:5]llo

即s的第2,3,4位被取出。

回到对s = 'MCMLXXII'的处理。

  1. 首先map中第一个罗马字符是M,只有一位,就把s 的第0位拿出来对比,发现s的第0位刚刚好是M,于是得到一个1000,index变为1,则之后从s的第一位开始。简单的说,相当于s 变成了s = 'CMLXXII'
  2. 接下来,经过一些无效的值以后,轮换到CM,发现CM为两位,就取出s的前两位,也就是CM,发现在s中刚刚好有CM,于是得到900. index再加2,则实际上s就相当于变成了LXXII
  3. 继续经过一些无效值以后,轮换到了L,发现s当前的1位为L,于是在map中有对应的值50.然后index加1,s相当于变成了XXII
  4. 接下来到了X,发现s当前的1位为X,在map中有对应的值10.然后index 再加1,s变成了XII
  5. 虽然这个时候人已经知道是12了,但是计算机还是不知道,于是继续一个X,s变为II
  6. 然后出现一个I,s变为I
  7. 终于程序找到了一个直接相等的值I,于是转换结束。

所以MCMLXXII对于的阿拉伯数字是1000+900+50+10+10+1+1 = 1972

这个方法,把一个罗马数字从高位开始逐次剥离最高位,从而渐渐的把数字缩小。

这是一篇旧闻,2014年发表在我的博客上。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-03-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 未闻Code 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
罗马数字与阿拉伯数字转换
且“II”表示2,“III”表示3,“IV”表示4,“VI表示6”,“VII”表示7,“VIII”表示8,“IX”表示9,其余的类似。
py3study
2020/01/17
8710
Merchant’s Guide To The Galaxy笔试题解析 python解决 罗马数字转阿拉伯数字
3.最好有相关的单元测试,如果能达到100%测试覆盖率且能正确的使用mock对象最好.如果时间不够或者不熟悉测试方法否,这一部分可忽略.功能完整性是首要考察.
十四君
2019/11/27
7030
[LeetCode]Roman to Integer 罗马数字转化成整数 [LeetCode]Roman to Integer 罗马数字转化成整数
链接:https://leetcode.com/problems/roman-to-integer/#/description 难度:Easy 题目:13. Roman to Integer Given a roman numeral, convert it to an integer. Input is guaranteed to be within the range from 1 to 3999. 翻译:将给定的罗马数字转化为整数,输入保证在1~3999之间 概念:什么是罗马数字?
尾尾部落
2018/09/04
7120
【每周一坑】罗马数字转换
罗马数字是欧洲在阿拉伯数字传入之前使用的一种数码,现在的使用已经非常少了,大概偶尔会在钟表、文章中的标号等地方还能见到。 罗马数字采用七个罗马字母作数字、即 I(1)、X(10)、C(100)、M(1000)、V(5)、L(50)、D(500)。它有一套不同于阿拉伯数字的写法规则,简单来说可以总结为: 相同的数字连写,所表示的数等于这些数字相加得到的数,如 Ⅲ=3; 小的数字在大的数字的右边,所表示的数等于这些数字相加得到的数,如 Ⅷ=8、Ⅻ=12; 小的数字(限于 Ⅰ、X 和 C)在大的数字的左边,所表示
Crossin先生
2018/04/17
2K0
【每周一坑】罗马数字转换
罗马字符与整数互转的关系_整数转罗马数字 java
计数规则: 相同的数字连写,所表示的数等于这些数字相加得到的数,例如:III = 3 小的数字在大的数字右边,所表示的数等于这些数字相加得到的数,例如:VIII = 8 小的数字,限于(I、X和C)在大的数字左边,所表示的数等于大数减去小数所得的数,例如:IV = 4 正常使用时,连续的数字重复不得超过三次 在一个数的上面画横线,表示这个数扩大1000倍(本题只考虑3999以内的数,所以用不到这条规则)
全栈程序员站长
2022/11/11
4720
012. 整数转罗马数字 | Leetcode题解
例如, 罗马数字 2 写做 II ,即为两个并列的 1。12 写做 XII ,即为 X + II 。27 写做 XXVII , 即为 XX + V + II 。
苏南
2020/12/16
4600
012. 整数转罗马数字 | Leetcode题解
013. 罗马数字转整数 | Leetcode题解
罗马数字包含以下七种字符: I , V , X , L , C , D 和 M 。
苏南
2020/12/16
4760
013. 罗马数字转整数 | Leetcode题解
使用JavaScript | Python | Java | C++解决从罗马数字转换到阿拉伯数字
例如,2用罗马数字II书写,只是将两个I加在一起。12作为写XII,这是用X + II。数字27写为XXVII,即XX + V + II。
海拥
2021/08/23
9290
使用JavaScript | Python | Java | C++解决从罗马数字转换到阿拉伯数字
leetcode 12 ,13 Integer to Roman &&Roman to Integer 罗马与阿拉伯数组转换
12 Integer to Roman 13 Roman to Integer
流川疯
2019/01/18
5340
【刷穿 LeetCode】12. 整数转罗马数字(中等)
例如, 罗马数字 2 写做 II ,即为两个并列的 1。12 写做 XII ,即为 X + II 。27 写做 XXVII, 即为 XX + V + II 。
宫水三叶的刷题日记
2021/02/20
3790
HDOJ/HDU 2352 Verdis Quo(罗马数字与10进制数的转换)
Problem Description The Romans used letters from their Latin alphabet to represent each of the seven numerals in their number system. The list below shows which letters they used and what numeric value each of those letters represents:
谙忆
2021/01/21
3950
罗马数字背后的秘密——LeetCode XII XIII 题记
印象中的罗马数字,多出现在文档标题或序号中:I、II、III、IV、V、VI 等。它是阿拉伯数字传入之前使用的一种数码。其采用七个罗马字母作数字:Ⅰ(1)、X(10)、C(100)、M(1000)、V(5)、L(50)、D(500),注意是没有 0 的。罗马数字的记数方法如下:
TTTEED
2020/07/08
1.1K0
【力扣算法13】之 12. 整数转罗马数字 python
首先,我们将罗马数字的字符和对应的数值存储在两个数组中。roman_chars数组存储了罗马数字的字符,roman_values数组存储了对应的数值。例如,'I’对应的数值是1,'V’对应的数值是5,以此类推。
全栈若城
2024/02/29
1640
【力扣算法13】之 12. 整数转罗马数字 python
算法创作|罗马数字的转化
例如,罗马数字2写做II,即为两个并列的1。12写做XII,即为X+II。27写做XXVII,即为XX+V+II。
算法与编程之美
2021/04/22
4650
算法创作|罗马数字的转化
leetcode-13-Roman to Integer
题目描述: Roman numerals are represented by seven different symbols: I, V, X, L, C, D and M. Symbol Value I 1 V 5 X 10 L 50 C 100 D 500 M 1000 For example, two is written
chenjx85
2018/05/22
5680
罗马数字对照表
大约在两千五百年前,罗马人还处在文化发展的初期,当时他们用手指作为计算工具。为了表示一、二、三、四个物体,就分别伸出一、二、三、四个手指;表示五个物体就伸出一只手;表示十个物体就伸出两只手。这种习惯人类一直沿用到今天。人们在交谈中,往往就是运用这样的手势来表示数字的。
红目香薰
2023/01/13
2.2K0
罗马数字对照表
leetcode之罗马数字转整数
这里采用HashMap对罗马数字与阿拉伯数字进行映射,另外对于特殊的组合罗马数字进行替换,最后遍历char数字查找映射进行累加。
code4it
2020/10/25
4980
leetcode之罗马数字转整数
leetcode之罗马数字转整数
这里采用HashMap对罗马数字与阿拉伯数字进行映射,另外对于特殊的组合罗马数字进行替换,最后遍历char数字查找映射进行累加。
code4it
2020/11/02
3490
Merchant‘s Guide to the Galaxy
You decided to give up on earth after the latest financial collapse left 99.99% of the earth’s population with 0.01% of the wealth. Luckily, with the scant sum of money that is left in your account, you are able to afford to rent a spaceship, leave earth, and fly all over the galaxy to sell common metals and dirt (which apparently is worth a lot).
leehao
2025/02/11
800
Leetcode: Roman to Integer
题目: Given a roman numeral, convert it to an integer.
卡尔曼和玻尔兹曼谁曼
2019/01/22
5060
推荐阅读
相关推荐
罗马数字与阿拉伯数字转换
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验