簡體   English   中英

枚舉快速字符串時獲取“ String.Index”

[英]Getting “String.Index” while enumerating swift string

目前,我們迭代字符串如下:

let greeting = "Hello"
for (intIndex, char) in greeting.enumerated() {
    let currentIndex = greeting.index(greeting.startIndex, offsetBy: intIndex)
    let indexAfterCurrentIndex = greeting.index(after: currentIndex)
    print(greeting[indexAfterCurrentIndex...])
}

我覺得用下面的代碼寫是多余的。

let currentIndex = greeting.index(greeting.startIndex, offsetBy: intIndex)

還有其他方法可以在迭代時直接獲取“ String.Index”嗎?

像這樣

let greeting = "Hello"
for (stringIndex, char) in greeting.enumeratedXXX() {
    let indexAfterCurrentIndex = greeting.index(after: stringIndex)
    print(greeting[indexAfterCurrentIndex...])
}

沒有內置功能。 您可以將其包裝在一個自定義的迭代器中,但是然后您只能將相同類型的計算封裝在不同的位置,所以這不是一個答案:)

代碼復雜度

但是,您可以提高當前代碼的性能:

greeting.index(greeting.startIndex, offsetBy: intIndex)
  • 這將為每次循環迭代計算從startIndex到結果索引的索引。
  • 使用index(_:offsetBy:)的索引計算實際上只是另一個循環本身,其中每個索引+1 沒有O(1)方式可以“計算”索引; 通過O(n)的循環找到它

因此,您自己的外部循環與O(n)成線性關系,共進行n次迭代,每個字符一個。

然后使用內部循環計算索引意味着有1+2+3+4+5+6+...n = (n^2 + n)/2次迭代,其中nintIndex

這意味着該算法具有*免除*回旋的復雜度O(n + n^2) 二次部分是有問題的!

更好的方法

您可以將復雜度降低到每個迭代2個操作,即O(2n) 只需將先前計算的索引保留在內存中,然后自己+1,就可以避免重新編寫代碼。

這是代碼:

let greeting = "Hello"
var index = greeting.startIndex
for char in greeting {
    let indexAfterCurrentIndex = greeting.index(after: index)
    print(greeting[indexAfterCurrentIndex...])
    index = indexAfterCurrentIndex
}

仍然不是一個簡單的內置解決方案,但是您可以包裝這種更有效的算法,然后就可以使用!

extension String {
    func forEachCharacterWithIndex(iterator: (String.Index, Character) -> Void) {
        var currIndex = self.startIndex
        for char in self {
            iterator(currIndex, char)
            currIndex = self.index(after: currIndex)
        }
    }
}

let greeting = "Hello"
greeting.forEachCharacterWithIndex { (index, char) in
    let indexAfterCurrentIndex = greeting.index(after: index)
    print(greeting[indexAfterCurrentIndex...])
}

如果需要字符串索引,則可以枚舉greeting.indices

let greeting = "Hello"
for index in greeting.indices {
    // ...
}

如果需要每個字符及其索引,則可以並行枚舉字符串和索引:

let greeting = "Hello"
for (char, currentIndex) in zip(greeting, greeting.indices) {
    let indexAfterCurrentIndex = greeting.index(after: currentIndex)
    print(char, "-", greeting[indexAfterCurrentIndex...])
}

輸出:

H - ello
e - llo
l - lo
l - o
o -

一個更簡單的變體是

let greeting = "Hello"
for (char, nextIndex) in zip(greeting, greeting.indices.dropFirst()) {
    print(char, "-", greeting[nextIndex...])
}

僅在沒有最后一個字符/索引對的情況下產生幾乎相同的結果:

H - ello
e - llo
l - lo
l - o

為什么不將currentIndex增加1?

let greeting = "Hello"
for (stringIndex, char) in greeting.enumerated() {
    let currentIndex = stringIndex
    let nextIndex = currentIndex + 1
    print(nextIndex)
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM