zoukankan      html  css  js  c++  java
  • 罗马数字转整数的golang实现

    罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。

    字符          数值
    I             1
    V             5
    X             10
    L             50
    C             100
    D             500
    M             1000

    例如, 罗马数字 2 写做 II ,即为两个并列的 1。12 写做 XII ,即为 X + II 。 27 写做 XXVII, 即为 XX + V + II 。

    通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 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 的范围内。
    输入: "III"
    输出: 3
    输入: "IV"
    输出: 4
    输入: "IX"
    输出: 9
    输入: "LVIII"
    输出: 58
    解释: L = 50, V= 5, III = 3.
    输入: "MCMXCIV"
    输出: 1994
    解释: M = 1000, CM = 900, XC = 90, IV = 4.

    按照题意,其实就是算出各个罗马数字,然后进行相加。但是这个罗马数字有可能是1个字符代表一个数字,也有可能两个字符代表一个数字,所以我就用了两个map来记录下这两种不同的情况

      specialRomanStringMap := map[string]int{"IV": 4, "IX": 9, "XL": 40, "XC": 90, "CD": 400, "CM": 900}//特殊罗马数字
       romanStringMap := map[string]int{"I": 1, "V": 5, "X": 10, "L": 50, "C": 100, "D": 500, "M": 1000}//正常罗马数字
    1. 然后我们就要对给定的字符串去取字符
    2. 但是当我们取到一个字符的时候,我们还得再取一个字符,用两个字符去特殊的map去查找是否存在
    3. 当存在的时候我们就记录下值
    4. 当没有的时候,我们就用第一个字符去正常的罗马数字map中找,并记录下值

    整体代码:

    func romanToInt(s string) int {
        specialRomanStringMap := map[string]int{"IV": 4, "IX": 9, "XL": 40, "XC": 90, "CD": 400, "CM": 900} //特殊罗马数字
        romanStringMap := map[string]int{"I": 1, "V": 5, "X": 10, "L": 50, "C": 100, "D": 500, "M": 1000}   //正常罗马数字
        result := 0
        for len(s) != 0 { //对字符串循环
            if len(s) > 1 { //当长度大于1的时候,才有必要去特殊罗马数字map中查找
                chars := s[0:2] //首先我们得拿出两个字符去特殊的map中查找
                if v, ok := specialRomanStringMap[chars]; ok { //当存在的时候记录值
                    result += v
                    s = s[2:]
                } else { //不存在的时候去正常map中查找,并记录
                    result += romanStringMap[string(s[0])]
                    s = s[1:]
                }
            } else { //当字符串的长度小于等于1的就只能去正常的罗马数字map中查找
                result += romanStringMap[string(s[0])]
                s = s[1:]
            }
        }
        return result
    }

    还有另外种思路,请仔细看下面三个说明:

    • I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。
    • X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。
    • C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。
    举个例子
    • 当输入是IV,那就是4,当输入是VI,那就是6
    • 当输入是IX,那就是9,当输入是XI,那就是11
    • 当输入是XL,那就是40,当输入是LX,那就是60
    • 当输入是XC,那就是90,当输入是CX,那就是110
    • 当输入是CD,那就是400,当输入是DC,那就是600
    • 当输入是CM,那就是900,当输入是MC,那就是1100
    可以看出来有一个规律:右加左减

    按照这个规律,那就可以从字符串的右边开始处理

    func romanToInt1(s string) int {
        res := 0
        m := map[byte]int{
            'I': 1,
            'V': 5,
            'X': 10,
            'L': 50,
            'C': 100,
            'D': 500,
            'M': 1000,
        }
    
        last := 0
        for i := len(s) - 1; i >= 0; i-- {
            temp := m[s[i]]//拿到最后一位
    
            sign := 1//用于标记是减还是加
            if temp < last {
                //小数在大数的左边,要减去小数
                sign = -1
            }
    
            res += sign * temp
    
            last = temp
        }
    
        return res
    }
  • 相关阅读:
    字符串 CSV解析 表格 逗号分隔值 通讯录 电话簿 MD
    Context Application 使用总结 MD
    RxJava RxPermissions 动态权限 简介 原理 案例 MD
    Luban 鲁班 图片压缩 MD
    FileProvider N 7.0 升级 安装APK 选择文件 拍照 临时权限 MD
    组件化 得到 DDComponent JIMU 模块 插件 MD
    gradlew 命令行 build 调试 构建错误 Manifest merger failed MD
    protobuf Protocol Buffers 简介 案例 MD
    ORM数据库框架 SQLite 常用数据库框架比较 MD
    [工具配置]requirejs 多页面,多入口js文件打包总结
  • 原文地址:https://www.cnblogs.com/TimLiuDream/p/9972025.html
Copyright © 2011-2022 走看看