在Swift 4

时间:2018-11-19 21:40:17

标签: arrays swift string dictionary

我正在学习Swift,为了克服学习extensions

的困难,我遇到了这个挑战
  

创建一个自定义“ indexOf”函数,该函数返回给定String中事件的第一个索引。输入可以混合

因此,以上翻译为:

Text: "Hello, world"
Phrase: "lol"
Output: 2

另一个例子是:

Text: "Hello, playground"
Phrase: " pal,ol"
Output: 2

说明

排列phrase的第一个示例可以采用以下值(由于重复的L,所以每个值两次):

llo
oll
lol

因此,排列之一实际上是Hello单词的一部分,从索引2开始。

第二个示例相同,它以空格开头,结尾处有一个ol,实际上是第一个单词的lo的一部分,然后它有palpla的排列。

我有不同的方法来解决这个问题:

  1. 对每个给定的短语进行所有排列,然后在原始文本中查找它们,但是我发现这种方法的问题是排列数由N!给出,其中{{1 }}是短语中的字母数,很容易用完。

  2. 查找每个字母并将其所有位置存储在N内的原始文本中,然后将值转换为整数数组(Dictionary [Character : [Int]]),以便我们进行排序里面的值并能够比较它们。这是我正在使用的方法,因为它似乎是一个合理的解决方案,但是我一直坚持如何将数组或字典中的值与其他值进行比较...

例如,我正在使用以下代码:

[[Int]]

到目前为止,这给了我以下输出:

import UIKit

var str = "Hello, playground"

extension String {
    func customIndexOf(subword: String) -> Int {
        var lettersDictionary: [Character : [Int]] = [ : ]
        var listOfIndexes: [[Int]] = []

        for letter in subword {
            lettersDictionary[letter] = findAllOccurrencesBy(letter: letter)
        }

        for (_, v) in lettersDictionary {
            listOfIndexes.append(v)
        }

        print(listOfIndexes)

        return -1
    }

    private func findAllOccurrencesBy(letter: Character) -> [Int] {
        var indexes = [Int]()
        var searchStartIndex = self.startIndex

        while searchStartIndex < self.endIndex,
            let range = self.range(of: String(letter), range: searchStartIndex..<self.endIndex),
            !range.isEmpty
        {
            let index = distance(from: self.startIndex, to: range.lowerBound)
            indexes.append(index)
            searchStartIndex = range.upperBound
        }

        return indexes
    }

    private func compareIndexes(listOfIndexes: [[Int]]) {

    }
}

print (str.customIndexOf(subword: "play"))

这应该返回[[7], [9], [10], [2, 3, 8]] -1 ,因为这是7的{​​{1}}所在的位置,因此我想循环遍历每个数组,并将它们与所有其他数组进行比较。如果它们之间的差为1,则表示字母都是连续的(这就是我们想要的),如果它们是连续的,则我们返回最低的索引,否则,如果字母之间的差为2+,则返回-1。

如何遍历所有数组并查找索引之间的差异?还是有更简单的方法来解决此问题?

1 个答案:

答案 0 :(得分:2)

您的扩展语法很好,因此您需要改进算法逻辑。将其分解为两个更简单的问题:检查子字符串中的字符串,以及检查字符串是否匹配字符串的排列

如果我们可以比较两个字符串而不考虑顺序而不检查所有排列怎么办?如果我们可以创建一个只要两个字符串具有相同字母出现就可以返回true的函数,则我们不需要所有排列。我们将此函数称为funA(String)-> Bool

然后我们可以在要检查的String内的移动索引上调用该函数(或者在扩展名是self时)

示例:

文字:您好
短语:哈哈
起始索引:0,长度:3

funA(Hel) = false  
funA(ell) = false  
funA(llo) = true  

返回值2,即当前的起始索引