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

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

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

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

原文发布于微信公众号 - Crossin的编程教室(crossincode)

原文发表时间:2017-07-07

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Java成神之路

计算字符串相似度算法——Levenshtein

Levenshtein 距离,又称编辑距离,指的是两个字符串之间,由一个转换成另一个所需的最少编辑操作次数。

6691
来自专栏小詹同学

Leetcode打卡 | No.012 整数转罗马数字

欢迎和小詹一起定期刷leetcode,每周一和周五更新一题,每一题都吃透,欢迎一题多解,寻找最优解!这个记录帖哪怕只有一个读者,小詹也会坚持刷下去的!

1191
来自专栏C/C++基础

基数排序简介及其并行化

  基数排序号称线性时间排序算法中性能最好,速度最快的排序算法。本文将简要概括其算法思想,串行代码及其并行化。

1331
来自专栏机器学习算法工程师

一道网易笔试题引发的血案……

作者:柳行刚 编辑:黄俊嘉 网易的2016年笔试题,题目经典。 所以特地找来给各位有兴趣的童鞋看看, 有详细的解题思路以及代码喔~ 各位,请看题! 题目描述: ...

45412
来自专栏Java Web

《编写高质量代码》学习笔记(1)

前言 看大神推荐的书单中入门有这么一本书,所以决定把这本书的精华(自认为很有用的点),或许是我自己现在能用到的点都提炼出来,供大家参考学习。 以下内容均出自《...

4004
来自专栏desperate633

[编程题] 猜数游戏分析代码

首先我们分析,dp[i]表示前i个数的合法个数 当第i个数是素数的时候,前面除了1都没有能除尽的,所以这个位置可以随便选Y或N,所以dp[i] = dp[i-...

1143
来自专栏阿凯的Excel

文本数字拆分技巧

Excel处理人员呢,最喜欢的就是规范化的表,那什么样子的表是规范的呢?给大家个图片感受一下! ? 今天的要和大家分享的就是和规范化图表格格不入的,需要由不规...

3296
来自专栏tkokof 的技术,小趣及杂念

位运算实用指南

说明 : 想来这应该是初次接触移位操作符时一定会了解到的知识点,根据2进制的整数表示方法应该不难理解,原因细节不再赘述~

671
来自专栏SimpleAI

Python高级特性——为什么都说Python高效

本微教程根据廖雪峰python教程中的部分内容,配合我个人的学习经历进行总结整理。

1154
来自专栏潇涧技术专栏

Python Algorithms - C6 Divide and Combine and Conquer

Python算法设计篇(6) Chapter 6: Divide and Combine and Conquer

1222

扫码关注云+社区

领取腾讯云代金券