swift Int和String的Swift扩展,用于转换为罗马和阿拉伯数字,并检查给定的罗马数字String是否为

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了swift Int和String的Swift扩展,用于转换为罗马和阿拉伯数字,并检查给定的罗马数字String是否为相关的知识,希望对你有一定的参考价值。

// Extensions of Int and String for converting to and from Roman and Arabic digits and
// checking to see if a given Roman numeral String is valid. Only designed to work in
// the range [0, 3999]. Output given from outside of this range will not be correct.
// 
// Created by Michael MacCallum
// CC0 License

public extension Int {
    public func toRoman() throws -> String {
        guard 0..<4000 ~= self else {
            if self == 0 {
                return "nulla"
            } else {
                throw NSError(
                    domain: "ArabicToRomanDomain",
                    code: 1,
                    userInfo: ["error": "toRoman called on a number outside of the range [0, 3999]"]
                )
            }
        }

        var copySelf = self
        let arabic = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1]
        let roman = ["M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"]
        var result = ""

        for (index, arabicDigit) in arabic.enumerate() {
            while copySelf >= arabicDigit {
                copySelf -= arabicDigit
                result += roman[index]
            }
        }

        return result
    }
}

public extension String {
    public func toArabic() throws -> Int {
        var copySelf = self.uppercaseString

        guard copySelf != "NULLA" else {
            return 0
        }

        guard copySelf.stringByTrimmingCharactersInSet(NSCharacterSet(charactersInString: "IVXLCDM")).isEmpty else {
            throw NSError(
                domain: "RomanToArabicDomain",
                code: 1,
                userInfo: ["error": "toArabic was supplied with a non Roman character. Use only IVXLCDM"]
            )
        }

        let arabic = [1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900, 1000]
        let roman = ["I", "IV", "V", "IX", "X", "XL", "L", "XC", "C", "CD", "D", "CM", "M"]
        var sum = 0

        for (index, romanDigit) in roman.enumerate() {
            while copySelf.hasSuffix(romanDigit) {
                sum += arabic[index]
                copySelf = copySelf.substringToIndex(copySelf.endIndex.advancedBy(-romanDigit.characters.count))
            }
        }

        return sum
    }

    public func isValidRomanNumeral() -> Bool {
        do {
            let arabic = try toArabic()
            let roman = try arabic.toRoman()

            return roman.caseInsensitiveCompare(self) == .OrderedSame
        } catch {
            return false
        }
    }
}

let x = try! 3999.toRoman()
try! x.toArabic()

try! "mxiii".toArabic()
try! "nulla".toArabic()

try! 0.toRoman()

do {
    try "dfghjm".toArabic()
} catch let error as NSError {
    print(error.userInfo)
}

"MMCLXVIII".isValidRomanNumeral()
"MMCLXIVI".isValidRomanNumeral()

以上是关于swift Int和String的Swift扩展,用于转换为罗马和阿拉伯数字,并检查给定的罗马数字String是否为的主要内容,如果未能解决你的问题,请参考以下文章

在 Swift 中归档自定义对象 - 扩展

Swift 中 Int 的前导零

Swift标准库的高级扩展EZSwiftExtensions

Swift - 协议类扩展(extension) 访问控制(fileprivate,private,internal,public,open)

使用 Swift 将 String 转换为 Int

在 Swift 中将 Int 转换为 String