是否有可能找到数组中的元素序列是否存在? 让我们从Pi中取一些数字,
let piDigits=[3,1,4,1,5,9,2,6,5,3,5,8,9,7,9,3,2,3,8,4,6,2,6,4,3,3,8,3,2,7,9,5,0,2,8,8,4,1,9,7,1,6,9,3,9,9,3,7,5,1,0,5,8,2,0,9,7,4,9,4,4]
现在,我想找出,5和9是否作为阵列中的序列元素存在 - 在这种情况下,它们一次在4和4位置进行。 5。
理想情况下,我不想用循环迭代数组,我想要类似于array.contains(element)。
@Bawpotter,代码片段:
for element in piDigits{ //check every element
if element == 5 { //if element is equal with the element i want
var currentPosition = piDigits.index(of: element) //get the position of that element
if piDigits[currentPosition!+1] == 9 { //if the element at the next position is equal to the other element i want
print("true") // it prints true 7 times, instead of 1!
}
}
}
答案 0 :(得分:1)
在contains方法中迭代数组,在这里你必须做同样的事情。这是一个例子:
extension Array where Element: Equatable {
func contains(array elements: [Element]) -> Int {
guard elements.count > 0 else { return 0 }
guard count > 0 else { return -1 }
var ti = 0
for (index, element) in self.enumerated() {
ti = elements[ti] == element ? ti + 1 : 0
if ti == elements.count {
return index - elements.count + 1
}
}
return -1
}
}
以下是如何使用它:
let index = [1, 4, 5, 6, 6, 9, 6, 8, 10, 3, 4].contains(array: [6, 8, 10])
// index = 6
let index = [1, 4, 5, 6, 6, 9, 6, 8, 10, 3, 4].contains(array: [6, 8, 1])
// index = -1
答案 1 :(得分:1)
您可以过滤其子序列elementsEqual为true的索引:
extension Collection where Element: Equatable, Index == Int {
func contains(_ subSequence: SubSequence) -> Bool {
let size = subSequence.count
for i in indices.dropLast(size-1) {
if self[i..<i+size].elementsEqual(subSequence) {
return true
}
}
return false
}
}
[1, 2, 3].contains([1, 2]) // true
如果您只需要检查集合是否包含子序列:
KTable
答案 2 :(得分:0)
let firstSeqNum = 5
let secondSeqNum = 9
for (index, number) in array.enumerated() {
if number == firstSeqNum && array[index+1] == secondSeqNum {
print("The sequence \(firstSeqNum), \(secondSeqNum) was found, starting at an index of \(index).")
}
}
由于没有内置方法,这将是您的最佳选择。
答案 3 :(得分:0)
使用线性搜索的一个非常简单的实现:
let piDigits: [Int] = [3,1,4,1,5,9,2,6,5,3,5,8,9,7,9,3,2,3,8,4,6,2,6,4,3,3,8,3,2,7,9,5,0,2,8,8,4,1,9,7,1,6,9,3,9,9,3,7,5,1,0,5,8,2,0,9,7,4,9,4,4]
let searchedSequence: [Int] = [5, 9]
var index = 0
var resultIndices: [Int] = []
while index < (piDigits.count - searchedSequence.count) {
let subarray = piDigits[index ..< (index + searchedSequence.count)]
if subarray.elementsEqual(searchedSequence) {
resultIndices.append(index)
}
index += 1
}
print("Result: \(resultIndices)")
还有其他变体,例如,您可以在迭代期间继续从piDigits
删除第一个字符,并检查piDigits
是否以searchedSequence
开头。
如果性能至关重要,我建议使用字符串搜索算法,例如Aho-Corasick(见https://en.wikipedia.org/wiki/String_searching_algorithm)首先构建状态机以进行快速比较(类似于正则表达式)。
让我们看看如何使用正则表达式:
let searchedSequences: [[Int]] = [[5, 9], [7], [9, 2]]
let stringDigits = piDigits.map { String($0) }.joined()
let stringSearchedSequences = searchedSequences.map { sequence in sequence.map { String($0) }.joined() }
let regularExpressionPattern = stringSearchedSequences.joined(separator: "|")
let regularExpression = try! NSRegularExpression(pattern: regularExpressionPattern, options: [])
let matches = regularExpression.matches(in: stringDigits, options: [], range: NSRange(location: 0, length: stringDigits.characters.count))
let matchedIndices = matches.map { $0.range.location }
print("Matches: \(matchedIndices)")
该方法的缺点是它不会搜索重叠范围(例如“592”匹配两个范围,但只报告一个范围)。