### content:
### 罗马数字包含以下七种字符： I， V， X， L，C，D 和 M。
### 字符          数值
### I             1
### V             5
### X             10
### L             50
### C             100
### D             500
### M             1000
### 通常情况下，罗马数字中小的数字在大的数字的右边。但也存在特例，例如 4 不写做 IIII，而是 IV。
### 数字 1 在数字 5 的左边，所表示的数等于大数 5 减小数 1 得到的数值 4 。
### 同样地，数字 9 表示为 IX。这个特殊的规则只适用于以下六种情况：

### I 可以放在 V (5) 和 X (10) 的左边，来表示 4 和 9。
### X 可以放在 L (50) 和 C (100) 的左边，来表示 40 和 90。 
### C 可以放在 D (500) 和 M (1000) 的左边，来表示 400 和 900。
### 给定一个罗马数字，将其转为整数。输入确保在 1 到 3999 的范围内。

### 示例：
### 输入: "MCMXCIV"
### 输出: 1994
### 解释: M = 1000, CM = 900, XC = 90, IV = 4.

### solution:
### 哈希法：
class Solution:
    def romanToInt(self, s: str) -> int:
        ## 1.自己的稍显麻烦的写法：
        ## 思路：从头遍历字符串s，同时判断与后一个是否能够配对，即字典中是否有对应的键值对，有则加和并跳过下一个字符继续遍历，没有则加和后顺序遍历
        # dict = {"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}
        # result = 0
        # n = len(s)
        # i = 0
        # while i<n:
        #     if i+1<n and dict[s[i]]<dict[s[i+1]]:
        #         result += dict[s[i]+s[i+1]]
        #         i += 2
        #     else:
        #         result += dict[s[i]]
        #         i += 1
        # return result
        
        ## 2.大佬两句话就搞定的方法：
        d = {'I':1, 'IV':3, 'V':5, 'IX':8, 'X':10, 'XL':30, 'L':50, 'XC':80, 'C':100, 'CD':300, 'D':500, 'CM':800, 'M':1000}
        # 字典的get函数dict.get(key, default=None)，返回键的值，或当字典中没有相应键的话返回默认值，这里大佬巧妙地用循环设置了动态默认值d[n]
        # 思路即：对给定字符序列s从头遍历，遍历到每个字符都会判断与前一位合并是否会在dict中
        # 在的话：由于前一个字符在上一步已将其值加和，这一步对应要加的值=原双字符值-前一字符的值
        # 例如CD：C首先遍历所以加了100，下一步到D时只需要加300，即可完全表示CD(400)
        # 不在的话：返回默认值d[n]即当前遍历到的字符表示的值
        return sum(d.get(s[max(i-1, 0):i+1], d[n]) for i, n in enumerate(s))
        
        
