python刷题日记4--Roman to Integer

给定一个罗马数字,将其转换为整数。输入保证在1到3999的范围内。

我就知道罗马数字0到9.........问了一下度娘的百科和查了相关博客,终于理解罗马数字没有像阿拉伯数字推广使用了

罗马数字采用七个罗马字母作数字: 
I(1)、X(10)、C(100)、M(1000)、V(5)、L(50)、D(500)。

记数的方法: 
1. 相同的数字连写,所表示的数等于这些数字相加得到的数,如 III=3; 
2. 小的数字在大的数字的右边,所表示的数等于这些数字相加得到的数,如 VIII=8、XIII=12; 
3. 小的数字(限于 I、X 和 C)在大的数字的左边,所表示的数等于大数减小数得到的数,如 IV=4、IX=9; 
4. 在一个数的上面画一条横线,表示这个数增值 1,000 倍。

重复数次:一个罗马数字重复几次,就表示这个数的几倍。 
右加左减:在一个较大的罗马数字的右边记上一个较小的罗马数字,表示大数字加小数字。在一个较大的数字的左边记上一个较小的罗马数字,表示大数字减小数字。但是,左减不能跨越一个位数。比如,99不可以用IC表示,而是用XCIX表示。此外,左减数字不能超过一位,比如8写成VIII,而非IIX。同理,右加数字不能超过三位,比如十四写成XIV,而非XIIII。 
加线乘千:在一个罗马数字的上方加上一条横线或者在右下方写M,表示将这个数字乘以1000,即是原数的1000倍。同理,如果上方有两条横线,即是原数的1000000倍。 
单位限制:同样单位只能出现3次,如40不能表示为XXXX,而要表示为XL。但是,由于IV是古罗马神话主神朱庇特(IVPITER,古罗马字母没有J和U)的首字,因此有时用IIII代替IV。

常用数字记法举例:

Roman Integer
Roman Integer
I 1
XXIX 29
II 2
XXX 30
III 3
XL 40
IV 4
L 50
V 5
LX 60
VI 6
LXX 70
VII 7
LXXX 80
VIII 8
XC 90
IX 9
XCIX 99
X 10
C 100
XI 11
CI 101
XII 12
CXCIX 199
XIII 13
CC 200
XIV 14
CCC 300
XV 15
CD 400
XVI 16
D 500
XVII 17
DCLXVI 666
XVIII 18
M 1,000
XIX 19
MCMXCIX 1,999
XX 20
MM 2,000
XXI 21
MMM 3,000
XXII 22
MMMM 4,000
XXVIII 28
MMMMCMXCIX 4,999

方法1:罗马数字字符串,从后向前扫描,遇到前面数大于等于后面的最大数的时候,相加;遇到前面数小于后面的最大数的时候,相减。例如DCXXI,

len(s)=5;

s[4]=I,  digits[I]=1,     等于1, maxDigit=1,     sum=1;

s[3]=X,digits[X]=10,  大于1,  maxDigit=10,  sum=11;

s[2]=X,digits[X]=10,  等于10,maxDigit=10,   sum=21;

s[1]=C,digits[C]=100,大于10,maxDigit=100,sum=121;

s[0]=D,digits[D]=500大于100,maxDigit=500,sum=621;

例如CXCIX,len(s)=5;

s[4]=X,   digits[X]=10,   大于1,    maxDigit=10,     sum=10;

s[3]=I,    digits[I]=1,       小于10,  maxDigit=10,     sum=9;

s[2]=C,  digits[C]=100, 大于10,   maxDigit=100,   sum=109;

s[1]=X,  digits[X]=10,    小于100,   maxDigit=100,sum=99;

s[0]=C,  digits[C]=100, 等于于100,maxDigit=100,sum=199;


class Solution(object):
    def romanToInt(self, s):
        """
        :type s: str
        :rtype: int
        """
        digits = {"I":1, "V":5, "X":10, "L":50, "C":100, "D":500, "M":1000}#定义一个字典
        sum = 0
        maxDigit = 0
        for i in xrange(len(s)-1, -1, -1):#xrange()会返回一个迭代序列,可以用来实现循环,它的三个参数依次是循环的起点、终点和步长。
            if digits[s[i]] >= maxDigit:
                maxDigit = digits[s[i]]
                sum += digits[s[i]]
            else:
                sum -= digits[s[i]]

        return sum

1. range([start], stop[, step])

返回等差数列。构建等差数列,起点是start,终点是stop,但不包含stop,公差是step。start 和 step 是可选项,没给出start时,从0开始;没给出step时,默认公差为1。 
以下为帮助文档解释:

>>> range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> range(1, 11)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> range(0, 30, 5)
[0, 5, 10, 15, 20, 25]
>>> range(0, 10, 3)
[0, 3, 6, 9]
>>> range(0, -10, -1)
[0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
>>> range(0)
[]
>>> range(1, 0)
[]
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

2.xrange([start], stop[, step])

xrange与range类似,只是返回的是一个“xrange object”对象,而非数组list。要生成很大的数字序列的时候,用xrange会比range性能优很多,因为不需要一上来就开辟一块很大的内存空间,这两个基本上都是在循环的时候用。

>>> x=xrange(2,5)
>>> x
xrange(2, 5)
>>> list(x)
[2, 3, 4]
>>> x[0]
2
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

与range的区别:

for i in range(0, 100):
 print i

for i in xrange(0, 100):
 print i
 
 
  • 1
  • 2
  • 3
  • 4
  • 5

这两个输出的结果都是一样的,实际上有很多不同,range会直接生成一个list对象:

>>> a = range(0,100)
>>> print a
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99]
>>> print type(a)
<type 'list'>
>>> print a[0]
0
>>>
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

而xrange将返回一个生成器对象:

>>> a = xrange(0,100)
>>> print type(a)
<type 'xrange'>
>>> print a[0]
0
>>> list(a)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99]
>>>
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值