Swift - 高效的数字到字符转换

Swift - Efficient Number to Character Conversion

如果我有很长的数字范围,例如 1...1000000,使用以下映射将它们转换为字符串的有效方法是什么?

1->A, 2->B, 3->C, ... 10->A0, 11->AA, 12->AB 等

我采用了将每个数字拆分为数字(使用模数)并使用它从数组中获取字符以构建字符串的方法。 1...1000 大约需要 5 秒。有更快的方法吗?

我的代码:

let numbers = 1...1000000
let charArray:[Character] = ["0","A","B","C","D","E","F","G","H","I"]
var results: [String] = []

func transformNumbers() {
    for number in numbers {
        var string = ""
        var i = number
        while i > 0 {string.insert(charArray[(i%10)], at: string.startIndex); i/=10}
        results.append(string)
    }
}

不确定这是否是最快的方法,但切换到 map 表达式而不是改变结果列表会使我的机器上的速度提高 10 多倍:

let results = numbers.map { (val: Int) -> String in
    var string = ""
    var i = val
    while i > 0 {string.insert(charArray[(i%10)], at: string.startIndex); i/=10}
    return string
}

你的代码在我的旧 MacBook 上用了大约 15 秒 1...1000000,而下面的代码不到 1 秒:

(在 macOS 10.12.5 上使用 Xcode 8.3.3 和 Release build)

let unicodeScalarArray:[UnicodeScalar] = ["0","A","B","C","D","E","F","G","H","I"]
let utf16CodeUnitArray:[UInt16] = unicodeScalarArray.map{UInt16([=10=].value)}
var results: [String] = []

func transformNumbers7() {
    results = numbers.map {number in
        var digits: [UInt16] = []
        var i = number
        while i > 0 {digits.append(utf16CodeUnitArray[i%10]); i/=10}
        digits.reverse()
        return String(utf16CodeUnits: digits, count: digits.count)
    }
}

一般来说,

  • 重复insert(_:at:)可能比重复append(_:)reverse()
  • 使用 Character 的效率可能低于 UnicodeScalar、UTF-16 代码单元或 UTF-8 代码单元。