2016-09-28 91 views
-1

是否有可能找到數組中是否存在元素序列? 讓我們一些數字,從郫縣,查找數組中是否存在元素序列

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] 

現在,我要找到,如果1,5和9存在如在這種情況下,他們這樣做,一旦基於陣列的序列元件,持倉4 & 5.

理想情況下,我不希望與迭代的循環陣列之上,我想類似array.contains(元件)的東西。

@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

如果您尋找在SWIFT的標準庫做到這一點的東西,我不認爲有... –

+0

有一些特定的文本搜索算法可以使用,例如阿霍Corasic,如果表現是至關重要的。考慮數組是一個長文本,搜索數組是一個子串。如果性能不重要,我可能會使用一個簡單的線性搜索使用'for'。在每個索引上檢查下一個'n'項是否等於您搜索的數組,如果是,則輸出該索引。 – Sulthan

回答

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」匹配兩個範圍,但只有一個報道)。

+0

整潔!我試圖進一步使searchSequence數組的數組,然後打印結果是一個字典(不要告訴我解決方案,我想自己試試:))我試圖找到一個迅速版本的aho-corasick與沒有成功.. – Do2

+0

@ Do2沒有多少字符串搜索算法庫,因爲字符串在標準庫中已經有相同的算法。該算法的概念仍然有效。 – Sulthan

+0

將輸入轉換爲字符串,然後搜索正則表達式'(subarray1 | subarray2 | ...)'的匹配項也是一種方法。 – Sulthan

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).") 
    } 
} 

既然有這個沒有內置的方法,這將是你最好的選擇。

+0

謝謝!我玩弄枚舉但顯然不正確..我也試過這個:對於piDigits元素如果元素== 5 var currentPosition = piDigits.index(of:元素) 如果piDigits [currentPosition!+1] == 9 { print(「true」) } } }但它不會輸出正確的結果,在這種情況下,它會打印真6次,任何想法爲什麼? – Do2

+0

你能編輯你原來的帖子來添加代碼嗎?格式化後更容易排除故障。 – Bawpotter

+0

好的我編輯了原始問題 – Do2

0

裏面包含迭代方法在陣列上,在這裏你必須做同樣的事情。下面一個例子:

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 
+0

嗨Yannick,謝謝你的回答。只要沒有重複,您的解決方案就可以正常工作。但是如果6,8,10重複兩次,它只會給我第一個的位置 – Do2

+0

好的,你的問題不清楚。你只要求「如果數組中的元素序列存在」。如果你想擁有所有的序列,那麼你可以在返回的數組中切下數組,然後重新調用這個方法直到你擁有所有的序列。 –