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

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

作者头像
青南
发布于 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 删除。

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

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
leetcode 12 ,13 Integer to Roman &&Roman to Integer 罗马与阿拉伯数组转换
12 Integer to Roman 13 Roman to Integer
流川疯
2019/01/18
5220
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
5580
Leetcode: Roman to Integer
题目: Given a roman numeral, convert it to an integer.
卡尔曼和玻尔兹曼谁曼
2019/01/22
4960
这题真是送分——LeetCode题目12:整数转罗马数字
例如, 罗马数字 2 写做 II ,即为两个并列的1。12 写做 XII ,即为 X + II 。 27 写做 XXVII, 即为 XX + V + II 。
二环宇少
2020/08/13
4160
Leetcode 题目解析之 Roman to Integer
Given a roman numeral, convert it to an integer.
ruochen
2022/02/13
1.3K0
LeetCode第13题--Roman to Integer(Java实现)
LeetCode第13题–Roman to Integer(Java实现) 原题 Given a roman numeral, convert it to an integer. Input is guaranteed to be within the range from 1 to 3999. 解题思路 先弄明白什么是罗马数字: 这7个符号与10进制阿拉伯数字的对应关系是: I=1;X=10;C=100;M=1000;  V=5;L=50;D=500; 罗马数字编码规则如下: 1.编码最短,
felix
2018/06/07
6741
罗马数字与阿拉伯数字转换
且“II”表示2,“III”表示3,“IV”表示4,“VI表示6”,“VII”表示7,“VIII”表示8,“IX”表示9,其余的类似。
py3study
2020/01/17
8550
罗马数字对照表
大约在两千五百年前,罗马人还处在文化发展的初期,当时他们用手指作为计算工具。为了表示一、二、三、四个物体,就分别伸出一、二、三、四个手指;表示五个物体就伸出一只手;表示十个物体就伸出两只手。这种习惯人类一直沿用到今天。人们在交谈中,往往就是运用这样的手势来表示数字的。
红目香薰
2023/01/13
2.1K0
罗马数字对照表
【每周一坑】罗马数字转换
罗马数字是欧洲在阿拉伯数字传入之前使用的一种数码,现在的使用已经非常少了,大概偶尔会在钟表、文章中的标号等地方还能见到。 罗马数字采用七个罗马字母作数字、即 I(1)、X(10)、C(100)、M(1000)、V(5)、L(50)、D(500)。它有一套不同于阿拉伯数字的写法规则,简单来说可以总结为: 相同的数字连写,所表示的数等于这些数字相加得到的数,如 Ⅲ=3; 小的数字在大的数字的右边,所表示的数等于这些数字相加得到的数,如 Ⅷ=8、Ⅻ=12; 小的数字(限于 Ⅰ、X 和 C)在大的数字的左边,所表示
Crossin先生
2018/04/17
1.9K0
【每周一坑】罗马数字转换
Merchant’s Guide To The Galaxy笔试题解析 python解决 罗马数字转阿拉伯数字
3.最好有相关的单元测试,如果能达到100%测试覆盖率且能正确的使用mock对象最好.如果时间不够或者不熟悉测试方法否,这一部分可忽略.功能完整性是首要考察.
十四君
2019/11/27
6890
【力扣算法13】之 12. 整数转罗马数字 python
首先,我们将罗马数字的字符和对应的数值存储在两个数组中。roman_chars数组存储了罗马数字的字符,roman_values数组存储了对应的数值。例如,'I’对应的数值是1,'V’对应的数值是5,以此类推。
全栈若城
2024/02/29
1450
【力扣算法13】之 12. 整数转罗马数字 python
Java中文数字转阿拉伯数字
/** * 中文数字转为阿拉伯数字 * @param zhNumStr 中文数字 * @return 阿拉伯数字 */ public static int zh2arbaNum(String zhNumStr) { Stack<Integer> stack = new Stack<>(); String numStr = "一二三四五六七八九"; String unitStr = "十百千万亿"; String[] ssArr = zhNumStr.split("")
martinzh7
2020/02/21
3.7K0
Java中文数字转阿拉伯数字
罗马字符与整数互转的关系_整数转罗马数字 java
计数规则: 相同的数字连写,所表示的数等于这些数字相加得到的数,例如:III = 3 小的数字在大的数字右边,所表示的数等于这些数字相加得到的数,例如:VIII = 8 小的数字,限于(I、X和C)在大的数字左边,所表示的数等于大数减去小数所得的数,例如:IV = 4 正常使用时,连续的数字重复不得超过三次 在一个数的上面画横线,表示这个数扩大1000倍(本题只考虑3999以内的数,所以用不到这条规则)
全栈程序员站长
2022/11/11
4450
[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
6940
罗马数字背后的秘密——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
012. 整数转罗马数字 | Leetcode题解
例如, 罗马数字 2 写做 II ,即为两个并列的 1。12 写做 XII ,即为 X + II 。27 写做 XXVII , 即为 XX + V + II 。
苏南
2020/12/16
4520
012. 整数转罗马数字 | Leetcode题解
013. 罗马数字转整数 | Leetcode题解
罗马数字包含以下七种字符: I , V , X , L , C , D 和 M 。
苏南
2020/12/16
4640
013. 罗马数字转整数 | Leetcode题解
【刷穿 LeetCode】12. 整数转罗马数字(中等)
例如, 罗马数字 2 写做 II ,即为两个并列的 1。12 写做 XII ,即为 X + II 。27 写做 XXVII, 即为 XX + V + II 。
宫水三叶的刷题日记
2021/02/20
3710
使用JavaScript | Python | Java | C++解决从罗马数字转换到阿拉伯数字
例如,2用罗马数字II书写,只是将两个I加在一起。12作为写XII,这是用X + II。数字27写为XXVII,即XX + V + II。
海拥
2021/08/23
9030
使用JavaScript | Python | Java | C++解决从罗马数字转换到阿拉伯数字
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
3810
推荐阅读
相关推荐
leetcode 12 ,13 Integer to Roman &&Roman to Integer 罗马与阿拉伯数组转换
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档