【问题标题】:Appending string much faster than appending character附加字符串比附加字符快得多
【发布时间】:2016-05-27 02:45:17
【问题描述】:

我在黑客等级上做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)")
    }
}

最初我使用了注释掉的代码。这会导致超时。总而言之,我的问题是对字符串使用下标系统会导致它比索引字符数组慢得多。这让我大吃一惊,如果不是黑客级别的讨论组,我不会找到解决方案。现在它激怒了我,因为我不知道为什么这会有所作为。

【问题讨论】:

    标签: arrays string swift character


    【解决方案1】:

    问题不在于追加字符串与追加字符的速度。问题是定位要附加的值需要多长时间。

    索引数组是 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)
        }
    }
    

    【讨论】:

    • 谢谢。既然您告诉我,我能够找到该特征的文档。
    猜你喜欢
    • 2016-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-14
    • 2019-09-30
    相关资源
    最近更新 更多