Swift - 搜索数组中的数字模式

时间:2017-04-26 09:44:51

标签: arrays swift algorithm numbers pattern-matching

我在Swift中组合了一个算法,其中一部分需要检查给定的数组并确定是否有任何2(或3,4 - 注释掉)数字的序列重复。我的来源是来自Java的代码块,据我所知,我试图将其转换为Swift - Playgrounds。它有点工作,但在运行代码后会抛出错误

“无法使用upperBound< lowerBound”形成范围

在崩溃之前,输出是正确的并传递模式的序列。怎么可以阻止这个?

let array1 = [12, 4, 5, 7, 1, 2]
let array2 = [1, 2, 3, 1, 2, 3, 1, 2, 3]
let array3 = [1, 1, 1, 1, 1, 1 ]
let array4 = [1, 2, 4, 12, 13, 1, 8, 4, 12, 4 ]
let array5 = [17,39,78,324,43,33,234,99,34,555,39,78,324,43,45,92 ]

func hasPattern(c:Array<Int>) {
for i in 0..<c.count {
    var jj = i + 1

    let step2 = (c.count - i) 
    for j in jj..<step2 {

        if(c[j] == c[i]){

            // pattern of 4 numbers repeating
            /*if(c[j+1] == c[i+1] && c[j+2] == c[i+2] && c[j+3] == c[i+3]){
                print("\(c[i]), \(c[i+1]), \(c[i+2]), \(c[i+3])")                    
            }*/

            // pattern of 3 numbers repeating
            /*
            if(c[j+1] == c[i+1] && c[j+2] == c[i+2]){
             print("\(c[i]), \(c[i+1]), \(c[i+2])")
             }
             */

            // pattern of 2 numbers repeating
            if(c[j+1] == c[i+1]){
                print("\(c[i]), \(c[i+1])")
            }
         }
      }
   }
}
/*
print(hasPattern(c: array1))
print(hasPattern(c: array2))
print(hasPattern(c: array3))*/
//print(hasPattern(c: array4))

print(hasPattern(c: array5))

我错过了什么?谢谢。

2 个答案:

答案 0 :(得分:1)

我仍然觉得你的问题并不完全清楚。数组[2,3,2,3,2]是否有[2,3,2]的2个重复子序列,即使它们共享一个共同的元素?

如果您想避免“无法形成范围...”错误,请使用stride

// A more convenient way to check if two arrays are equal
func ==(lhs: [Int], rhs: [Int]) -> Bool {
    guard lhs.count == rhs.count else { return false }

    for (l, r) in zip(lhs, rhs) {
        if l != r { return false }
    }
    return true
}

// If there's no matching pattern, this function will return nil
// instead of an aempty array. Change it if you want to
func hasPattern(array: [Int], length: Int) -> [[Int]]? {
    guard array.count >= length * 2 else { return nil }

    var result = [[Int]]()
    for i in 0..<(array.count - length) {
        let subarray1 = array[i..<(i+length)]

        for j in stride(from: i+1, to: array.count - length, by: 1) {
            let subarray2 = array[j..<(j+length)]
            if subarray1 == subarray2 {
                result.append(Array(subarray1))
            }
        }
    }
    return result.isEmpty ? nil : result
}

if let patterns = hasPattern(array: array5, length: 3) {
    print(patterns) // [[39, 78, 324], [78, 324, 43]]
} else {
    print("No repeating pattern found")
}

答案 1 :(得分:0)

你的问题在于你的内循环。对于大小为5的数组,循环如下:

for i in 0..<5
    for j in i+1..<5-i

+i-i会发生冲突,你的下限会大于你的上限。

如果您没有明确需要推广自己的算法,最好使用以下方式执行搜索:

func hasPattern(elements :Array<Int>) -> Bool {
    var index = 0
    while index < (array.count - elements.count) {
        let subarray = array[index ..< (index + elements.count)]
        if subarray.elementsEqual(elements) {
            return true
        }
        index += 1
    }
    return false
}

array是您要搜索的数组。