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

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

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


罗马数字采用七个罗马字母作数字、即 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 实现

相关文章
|
5月前
字符组成的超级玛丽
字符组成的超级玛丽
|
5月前
|
程序员
老程序员分享:LOJ10155数字转换
老程序员分享:LOJ10155数字转换
22 0
|
6月前
PAT甲级真题1050 字符串减法
PAT甲级真题1050 字符串减法
47 0
|
关系型数据库 MySQL 数据处理
位、字节、字符与字(字母跟汉字)的爱恨情仇
位、字节、字符与字(字母跟汉字)的爱恨情仇
172 0
位、字节、字符与字(字母跟汉字)的爱恨情仇
|
Python
python实现炫酷字母雨
python实现炫酷字母雨
210 0
python实现炫酷字母雨
#yyds干货盘点# 第三十五题-字符串字符统计
#yyds干货盘点# 第三十五题-字符串字符统计
94 0
#yyds干货盘点# 第三十五题-字符串字符统计
|
算法 Go
算法练习第七天——有效的字母异位词
给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。 注意:若 s 和 t 中每个字符出现的次数都相同,则称 s 和 t 互为字母异位词。
|
存储 算法 Java
字符作画,我用字符画个冰墩墩
字符作画,我用字符画个冰墩墩
243 0
字符作画,我用字符画个冰墩墩
[解题报告](第24讲) 字符串算法(四) - 字符计数法(1)
[解题报告](第24讲) 字符串算法(四) - 字符计数法
[解题报告](第24讲) 字符串算法(四) - 字符计数法(1)