2017-07-16 65 views
0

如果我有一個很長的數字範圍,例如1 ... 1000000,那麼用下面的映射將它們轉換爲字符串的有效方法是什麼?Swift - 有效數字到字符轉換

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

我帶分割的方法的每個號碼轉換爲數字(使用模數)並使用它從數組中獲取字符來構建字符串。花費大約5秒1 ... 1000。有更快的方法嗎?

我的代碼:

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) 
    } 
} 
+0

_對於1 ... 1000_大約需要5秒鐘,似乎太長了。 _爲1 ... 1000000'在第一行? – OOPer

+0

「數字」數組是否按順序排列? –

+0

您可以嘗試將數字轉換爲一串數字。然後使用'replaceOccurances()',將每個'1'替換爲'A'('2'替換爲'B'等)。看看性能是否提高。 – AgRizzo

回答

0

你的代碼,把我的舊的MacBook約15秒1...1000000,和下面的代碼,小於1秒:

(使用XC賦與8.3.3在MacOS 10.12.5發佈版本)

let unicodeScalarArray:[UnicodeScalar] = ["0","A","B","C","D","E","F","G","H","I"] 
let utf16CodeUnitArray:[UInt16] = unicodeScalarArray.map{UInt16($0.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 s工作可能比不太有效UnicodeScalar,UTF-16代碼單元或UTF-8代碼單元。
+0

這導致編譯項目中我的機器增加了2倍。最大的區別似乎來自追加+反向。謝謝! –

+0

@RomanSheydvasser,也許** _ 2x _ **在調試版本中找到。使用Release版本,差異會更大。請嘗試。 – OOPer

0

不知道這是最快的方法,但切換到一個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 
} 
+0

謝謝馬特!我在操作系統上的機器上看到類似的10倍增長,比OOPer的代碼快,但是在編譯的項目中運行後,實際上它比我的原始代碼稍慢。我猜環境造成了很大的變化。無論如何,我欣賞關於地圖表達的提示。 –