【问题标题】:Convert Integer to Roman Numeral String in Swift在 Swift 中将整数转换为罗马数字字符串
【发布时间】:2016-07-04 05:55:38
【问题描述】:

我希望在 Swift 中使用 Integer 并将其转换为罗马数字 String。有什么想法吗?

【问题讨论】:

  • 我能否请一些 cmets 了解为什么这个问题被否决?

标签: swift nsnumber swift-extensions


【解决方案1】:

你可以在Int 上写一个扩展,类似于下面看到的。

请注意:对于小于一的数字,此代码将返回“”。虽然就罗马数字而言这可能没问题(零不存在),但您可能希望在自己的实现中以不同方式处理。

extension Int {
    var romanNumeral: String {
        var integerValue = self
        var numeralString = ""
        let mappingList: [(Int, String)] = [(1000, "M"), (900, "CM"), (500, "D"), (400, "CD"), (100, "C"), (90, "XC"), (50, "L"), (40, "XL"), (10, "X"), (9, "IX"), (5, "V"), (4, "IV"), (1, "I")]
        for i in mappingList {
            while (integerValue >= i.0) {
                integerValue -= i.0
                numeralString += i.1
            }
        }
        return numeralString
    }
}

感谢 Kenneth Bruno 对改进代码的一些建议。

【讨论】:

  • 您可以通过将第 6 行和第 7 行更改为 for i in mappingList where (integerValue >= i.0) { 并将所有 mappingList[i] 更改为 i 来简化该代码。我也会把它变成一个计算属性,它非常适合。对我来说似乎是一个很好的算法!
  • 感谢@KennethBruno 的建议。我更新了代码以使用改进后的 for 循环声明。另外,我是 swift 新手,所以当我有机会时,我会进一步研究 mappingList 的计算属性。
  • 要使其成为计算属性,请将第 2 行更改为 var romanNumeral: String {。然后你可以把它称为number.romanNumeral,就像一个普通的属性一样。哦,删除第 7 行和第 10 行,你不再需要它们了。
  • 好的,很高兴知道,谢谢。我一定会考虑的。但是,我认为 while 循环仍然是必要的,因为您可以拥有同一个字母的多个实例。例如,3 = "III"。
  • 是的,你是对的,它必须在那里。我完全错过了!
【解决方案2】:

这是我的 int 到 roman 转换器的版本(没有嵌套循环):

extension Int {
    func toRoman() -> String {
        let conversionTable: [(intNumber: Int, romanNumber: String)] =
            [(1000, "M"),
             (900, "CM"),
             (500, "D"),
             (400, "CD"),
             (100, "C"),
             (90, "XC"),
             (50, "L"),
             (40, "XL"),
             (10, "X"),
             (9, "IX"),
             (5, "V"),
             (4, "IV"),
             (1, "I")]
        var roman = ""
        var remainder = 0
        
        for entry in conversionTable {
            let quotient = (self - remainder) / entry.intNumber
            remainder += quotient * entry.intNumber
            roman += String(repeating: entry.romanNumber, count: quotient)
        }
        
        return roman
    }
}

【讨论】:

    【解决方案3】:

    这是您问题的解决方案,请检查此

    func convertRomanToInt(strRoman : String) -> Int {

    let arrData = strRoman.map { String($0) }
    let dictRomanValue = ["I" : 1, "V" : 5, "X" : 10, "L" : 50, "C" : 100, "D" : 500, "M" : 1000]
    var currentValue = 0
    var preValue = 0
    var ans = 0
    
    for (_,obj) in arrData.enumerated().reversed() {
        _ = dictRomanValue.map({ strName in
    
            if obj == strName.key {
                currentValue = strName.value
                
                if currentValue < preValue && preValue > 0 {
                    ans = ans - preValue + (preValue - currentValue)
                    preValue = strName.value
                }else{
                    preValue = strName.value
                    ans = ans + strName.value
                }
                 
            }else{
                  ans
            }
        })
    }
    return ans
    

    }

    使用方法:很简单,你要调用这个函数

    示例:convertRomanToInt(strRoman: "LVIII")

    注意:它仅适用于您的号码

    如果你得到更多的数字,请在“dictRomanValue”中添加更大的罗马值。

    【讨论】:

      【解决方案4】:

      这就是使用 for 循环和字典的方法。

      func romanToInt(_ s: String) -> Int {
          
          let numDict: [String: Int] = ["I": 1, "V": 5, "X": 10, "L": 50, "C": 100, "D": 500, "M": 1000]
          
          let stringArray = Array(s)
          
          var result: Int = 0
          
          for index in 0..<stringArray.count {
              for (k, v) in numDict {
                  if String(stringArray[index]) == k {
                      if (index + 1) < stringArray.count {
                          if k == String(stringArray[index + 1]) {
                              result += v
                          } else {
                              let nextValue = stringArray[index + 1]
                              for (nextK, nextV) in numDict {
                                  if String(nextValue) == nextK {
                                      if v < nextV {
                                          result -= v
                                      } else {
                                          result += v
                                      }
                                  }
                              }
                          }
                      } else {
                          result += v
                      }
                  }
              }
          }
          return result
      }
      

      【讨论】:

        猜你喜欢
        • 2011-06-26
        • 2019-01-09
        • 2011-10-25
        • 2012-10-09
        • 1970-01-01
        • 1970-01-01
        • 2020-05-11
        相关资源
        最近更新 更多