2016-05-27 111 views
1

我正在做的黑客排名https://www.hackerrank.com/challenges/30-review-loop的問題,我也陷入了超時的問題是在四圍的方式解決的要快得多。我希望這裏有人能向我解釋爲什麼一個人比另一個人快。或者指向我解釋這種現象的文檔追加字符串不是追加字符

如果您沒有帳戶,那麼您需要輸入測試用例的數量,然後輸入一個字符串,您的代碼將創建一個包含所有奇數索引中的字符和偶數索引中的所有字符組成的字符串。例如輸入

2 
Hacker 
Rank 

回報

Hce akr 
Rn ak 

簡單吧?這是我所做的代碼。

if let line = readLine(), numOftests = Int(line) { 
    for iter in 0..<numOftests { 
     var evenString = "" 
     var oddString = "" 
     var string = readLine()! 
     var arrChars = [Character](string.characters)       //1 
     for idx in 0..<string.characters.count { 
      if idx % 2 == 0 { 
       oddString.append(arrChars[idx])         //1 
       //oddString.append(string[string.startIndex.advancedBy(idx)]) //2 <= Times out 
      } 
      else { 
       evenString.append(arrChars[idx])        //1 
       //evenString.append(string[string.startIndex.advancedBy(idx)]) //2 <= Times out 
      } 
     } 
     print("\(oddString) \(evenString)") 
    } 
} 

最初我使用了註釋掉的代碼。這導致超時。總結我的問題是,使用下標系統處理字符串會導致它比索引字符數組慢得多。它令我吃驚,如果不是黑客級別的討論組,我不會找到解決方案。現在它招來我,因爲我不知道爲什麼這會有所作爲。

回答

2

問題不追加一個字符串與附加字符的速度。問題是需要多長時間才能找到您要添加的值。

索引的陣列是O(1),這意味着它發生在相同的時間是否要訪問的第一個字符或第97。這很有效,因爲Swift知道數組元素的大小,所以它可以將索引乘以元素的大小以找到第n個元素。

string.startIndex.advancedBy(idx)是O(IDX)。這取決於你進入字符串的距離有多長。訪問第97個字符將需要訪問第一個字符的約97倍。爲什麼?因爲Swift中的字符大小不統一。 Swift字符串是完全unicode兼容的,並且「」需要比「A」更多的字節來表示。因此,有必要查看從startIndex到您正在訪問的每個角色。

也就是說,沒有理由讓你在每次啓動startIndex。如果你在一個變量保持當前的索引,你可以通過1每次這將使大約相同的速度字符數組索引版本字符串索引版本提前了。

var currentIndex = string.startIndex 

for idx in 0..<string.characters.count { 
    if idx % 2 == 0 { 
     oddString.append(string[currentIndex]) 
    } 
    else { 
     evenString.append(string[currentIndex]) 
    } 
    currentIndex = currentIndex.successor() 
} 

這就是說,我可能會寫這樣的:

for (idx, char) in string.characters.enumerate() { 
    if idx % 2 == 0 { 
     oddString.append(char) 
    } 
    else { 
     evenString.append(char) 
    } 
} 
+0

謝謝。現在你告訴我,我能找到該特性的文檔。 – Biclops