首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
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 删除。

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

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
HTTP报文格式及WireShark抓包分析
版权声明:本文为博主原创文章,转载请注明博客地址: https://blog.csdn.net/zy010101/article/details/86552833
zy010101
2019/05/25
7.5K0
《吐血整理》保姆级系列教程-玩转Fiddler抓包教程(1)-HTTP和HTTPS基础知识
有的小伙伴或者童鞋们可能会好奇地问宏哥,不是讲解和分享抓包工具了怎么这里开始讲解HTTP和HTTPS协议了。这是因为你对HTTP协议越了解,你就能越掌握Fiddler的使用方法,反过来你越使用Fiddler,就越能帮助你了解HTTP协议。
北京-宏哥
2022/06/30
1.1K0
《吐血整理》保姆级系列教程-玩转Fiddler抓包教程(1)-HTTP和HTTPS基础知识
Http请求报文格式和响应报文格式
客户端连上服务器后,向服务器发出获取某个Web资源的消息,称之为客户端向服务器发送了一个HTTP请求。
chenchenchen
2022/03/09
8.7K0
Http请求报文格式和响应报文格式
全网最全fiddler使用教程和fiddler如何抓包
来源:http://www.51testing.com 一、前言 抓包工具有很多,比如常用的抓包工具Httpwatch,通用的强大的抓包工具Wireshark.为什么使用fiddler?原因如下:
顾翔
2020/07/03
14.3K0
全网最全fiddler使用教程和fiddler如何抓包
学HTTP协议所要知道的基础知识(微总结)
1、网络本质 进行资源共享和信息传输。 2、基于网络的应用程序的本质 就是获取数据和传输数据给用户使用。 3、TCP/IP协议栈工作流程 实体层是不属于TCP/IP协议栈的一层。也就是说TCP/IP协议栈共计四层。 首先得接入网络,局域网或者广域网,在计算机接入网络的时候,也就是插入网线的时候本地路由器中的   路由表会更新数据,通过一定淘汰机制算法删除很久没有使用过的计算机ip以及mac地址,并对新加入组的计算 机新分配ip,在分配ip的过程中,路由表会通过ARP协议(地址解析协议)得到新接入计
汪凡
2018/05/29
6850
Http常用头部整理
3. HTTP允许传输任意类型的数据对象。类型由Content-Type加以标记。
疯狂的技术宅
2019/03/28
11.2K1
解析一次完整的HTTP请求与响应
图片来自:理解Http请求与响应http://android.jobbole.com/85218/
ZhangXianSheng
2019/05/28
1.8K0
HTTP初始(一)
HTTP是由HTTP请求和HTTP响应构成的。那么如何来发起一个HTTP请求呢?简单来说,你只要在浏览器网址栏中输入一个网址(URL),按下回车那么一个HTTP请求就发出了,界面发生了跳转或者数据发生了改变,就表明一个HTTP响应反馈来了。
东边的大西瓜
2022/05/05
6330
HTTP初始(一)
HTTP系列-报文结构详解
值得注意的是,在起始行中,每两个部分之间用空格隔开,最后一个部分后面应该接一个换行,严格遵循ABNF语法规范。
李林LiLin
2020/12/09
1.5K0
五千来字小作文,是的,我们是有个HTTP。
因为这个属性JSESSIONID比较重要,存储的是sessionId,这个要是被别人拿到的话,别人就可以冒充我在网站上做某些事情了,像我自己一样请求某些数据了
java小杰要加油
2021/05/13
4750
五千来字小作文,是的,我们是有个HTTP。
接口-Requests-HTTP报文详解
HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web)服务器传输超文本到本地浏览器的传送协议。
wangmcn
2022/07/25
5.4K0
接口-Requests-HTTP报文详解
HTTP协议详解
利用 TCP/IP 协议族进行网络通信时,会通过分层顺序与对方进行通信。发送端从应用层往下走,接收端则从链路层往上走。如下:
小柒吃地瓜
2020/04/23
2.2K0
HTTP协议详解,真的是非常经典
【程序视点】助力打工人减负,从来不是说说而已!后续小二哥会继续详细分享更多实用的工具和功能。
程序视点
2025/04/30
2250
Fiddler4抓包工具使用教程一
本文参考自http://blog.csdn.net/ohmygirl/article/details/17846199,纯属读书笔记,加深记忆 1、抓包工具有很多,为什么要使用Fiddler呢?原因如
郑小超.
2018/01/26
3.6K0
程序员都该懂点 HTTP
HTTP 全称是 HyperText Transfer Protocal ,即:超文本传输协议,从 1990 年开始就在 WWW 上广泛应用,是现今在 WWW 上应用最多的协议,HTTP 是应用层协议,当你上网浏览网页的时候,浏览器和 web 服务器之间就会通过 HTTP 在 Internet 上进行数据的发送和接收。HTTP 是一个基于请求/响应模式的、无状态的协议。即我们通常所说的 Request/Response
developerHaoz
2018/08/20
5030
面试问你HTTP知识点?这篇搞懂秒杀90%知识点!
由于自身不带验证机制,任何人都可以上传文件,因此存在安全性问题,一般不使用该方法。
乔戈里
2019/07/10
1K0
面试问你HTTP知识点?这篇搞懂秒杀90%知识点!
HTTP协议学习
HTTP 于 1990 年问世。那时的 HTTP 并没有作为正式的标准被建立。现在的 HTTP 其实含有 HTTP1.0 之前 版本的意思,因此被称为
ruochen
2021/12/07
1.1K0
Android网络编程(一)HTTP协议原理
前言 这篇文章是这个系列的开篇,作为移动开发者,开发的应用不免会对网络进行访问,虽然现在已经有很多的开源库帮助我们可以轻而易举的访问网络,但是我们仍要去了解网络访问的原理,这也是一个优秀开发人员所必备的知识点。这篇文章我们就先来了解一下HTTP协议原理。 1.HTTP简介 HTTP是一个属于应用层的面向对象的协议,由于其简捷、快速的方式,适用于分布式超媒体信息系统。它于1990年提出,经过几年的使用与发展,得到不断地完善和扩展。 HTTP协议的主要特点 支持C/S(客户/服务器)模式。 简单快速:客户向服务
用户1269200
2018/02/01
1.3K0
Android网络编程(一)HTTP协议原理
Http协议详解
若每个网站都有自己的规则,整个互联网就乱套了,而且用户访问也不是很方便,每个网站都要开发属于自己的客户端软件,致使运营成本变大。
贾维斯Echo
2023/10/18
4540
Http协议详解
理解Request Headers 和 Response Headers
请求头由key/value对组成,每行为一对,key和value之间通过冒号(:)分割。请求头的作用主要用于通知服务端有关于客户端的请求信息
xyzzz
2021/04/26
1.9K0
相关推荐
HTTP报文格式及WireShark抓包分析
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验