【每周一坑】罗马数字转换

简介: 由图可知,螺旋数组中的数字运动方向依次 右 -> 下 -> 左 -> 上 -> 右 这样的循环,在合适的条件下变换累加方向即可。

罗马数字是欧洲在阿拉伯数字传入之前使用的一种数码,现在的使用已经非常少了,大概偶尔会在钟表、文章中的标号等地方还能见到。


罗马数字采用七个罗马字母作数字、即 I(1)、X(10)、C(100)、M(1000)、V(5)、L(50)、D(500)。它有一套不同于阿拉伯数字的写法规则,简单来说可以总结为:


  1. 相同的数字连写,所表示的数等于这些数字相加得到的数,如 Ⅲ=3;
  2. 小的数字在大的数字的右边,所表示的数等于这些数字相加得到的数,如 Ⅷ=8、Ⅻ=12;
  3. 小的数字(限于 Ⅰ、X 和 C)在大的数字的左边,所表示的数等于大数减小数得到的数,如 Ⅳ=4、Ⅸ=9;
  4. 在一个数的上面画一条横线,表示这个数增值 1,000 倍。




那么今天,我们就来尝试写个罗马数字和阿拉伯数字的转换器吧:


给定一个小于 3999 的罗马数,将其转换为整数,例如:Ⅲ=3、Ⅳ=4、Ⅵ=6、XIX=19、XX=20、XLV=45、MCMLXXX=1980。


附加题:


给定一个小于 3999 整数,将其转换为罗马数。


示例:


def romanToInt(s):
    # your code here
    return i
assert romanToInt('III') == 3
assert romanToInt('IV') == 4
assert romanToInt('VI') == 6
assert romanToInt('XIX') == 19
assert romanToInt('XLV') == 45
assert romanToInt('MCMLXXX') == 1980
assert romanToInt('CMXCIX') == 999


期待各位同学提交解答。

提交代码可以使用 paste.ubuntu.com 或 codeshare.io 等代码分享网站,只需将代码复制上去保存,即可获得一个分享地址,非常方便。

往期问题可通过公众号菜单栏“课外辅导”栏目中进入查看。




【解答】螺旋矩阵


解题思路:


  1. 由图可知,螺旋数组中的数字运动方向依次 右 -> 下 -> 左 -> 上 -> 右 这样的循环,在合适的条件下变换累加方向即可。
  2. 变换方向的条件有两个,一是遇到数组边界,二是下一位置被其他数占据。
  3. 可用一个二维列表存储数据,按照规则将列表中填上数字,最后再输出。


示例代码:


class Spiral:
    def __init__(self, N):
        # 构造一个二维数组
        self.matrix = [[None for i in range(N)] for j in range(N)]
        # 起始行列数
        self.row = 0
        self.col = 0
        # 数组的边界值
        self.max_row = N
        # 更换方向的标记
        self.mark = 0
    # 按需取出数组运动方向
    def derection(self, mark):
        around = [
            [self.row, self.col+1], # 向右
            [self.row+1, self.col], # 向下
            [self.row, self.col-1], # 向左
            [self.row-1, self.col]  # 向上
        ]
        return around[mark%4]
    # 针对目前位置,获取下一位置的行列数
    # 下一位置为边界则更换方向
    # 下一位置已经有元素则更换方向
    def next(self):
        # 下一位置
        i = self.derection(mark=self.mark)
        # 判断是否更换方向,不更换则更新 self.row / self.col
        if -1 not in i and self.max_row not in i:
            if self.matrix[i[0]][i[1]] is None:
                self.row,self.col = i
                return None
        # 更换方向
        self.mark += 1
        return self.next()
    def solution(self):
        # 逐一取出 1 到 n^2 值
        for i in range(1,self.max_row**2+1):
            # 按行列赋值
            self.matrix[self.row][self.col] = i
            # 退出条件
            if i == self.max_row**2:
                break
            # 更新行列值
            self.next()
        # 打印结果
        for r in self.matrix:
            for c in r:
                print('{0:^{1}}'.format(c,self.max_row), end=' ')
            print('\n')
if __name__ == '__main__':
    n = int(input('>>>'))
    s = Spiral(n)
    s.solution()


@wuxiaojiao 同学的代提交答案中最简洁的

http://paste.ubuntu.com/24955910/

@徐大龙 同学的代码使用了 numpy 库

https://github.com/PeytonXu/learn-python/blob/master/cases/helix_matrix/helix_matrix.py


『码上行动』在线学习班正在开放中,详情请回复 码上行动 查看


近期文章推荐阅读:

喏,你们要的 PyCharm 快速上手指南

给伸手党的福利:Python 新手引导

只学2个月编程能写出什么代码?他们表示:You can you code!

如何用100行Python代码做出魔性声控游戏“八分音符酱”

数据分析:当赵雷唱民谣时他唱些什么?

一行代码扫出“敬业福”

我扒了杜蕾斯的微博

Python 爬虫爬取美剧网站

今天,你抢到票了吗?

爆款游戏《贪吃蛇大作战》的 Python 实现

相关文章
|
6月前
字符组成的超级玛丽
字符组成的超级玛丽
|
6月前
|
程序员
老程序员分享:LOJ10155数字转换
老程序员分享:LOJ10155数字转换
30 0
|
7月前
每日一题——只出现一次的数字(II)
每日一题——只出现一次的数字(II)
每日一题——只出现一次的数字(II)
|
7月前
每日一题——只出现一次的数字
每日一题——只出现一次的数字
|
7月前
每日一题——只出现一次的数字(III)
每日一题——只出现一次的数字(III)
|
7月前
|
Java
每日一题《剑指offer》字符串篇之替换空格
每日一题《剑指offer》字符串篇之替换空格
59 0
每日一题《剑指offer》字符串篇之替换空格
367. 有效的完全平方数【我亦无他唯手熟尔】
367. 有效的完全平方数【我亦无他唯手熟尔】
60 0
299. 猜数字游戏【我亦无他唯手熟尔】
299. 猜数字游戏【我亦无他唯手熟尔】
60 0
|
机器学习/深度学习 数据采集 人工智能
【每周一坑】杨辉三角形
了解完背景知识之后,来看看对应的题目,定义一个函数 yanghui() ,传入正整数参数 M、N,分别代表杨辉三角形第 M 行,左起第 N 个数字(M,N 都从 0 开始计算)。入超出范围则返回 invalid query 。
|
开发者
傻傻分不清的进制与进制转换
傻傻分不清的进制与进制转换
405 0
傻傻分不清的进制与进制转换