【问题标题】:Swift - Search for pattern of numbers in an arraySwift - 在数组中搜索数字模式
【发布时间】:2017-04-26 09:44:50
【问题描述】:

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

“不能用upperBound

在它崩溃之前,输出是正确的并提供模式的序列。请问如何预防?

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))

我在这里错过了什么?谢谢。

【问题讨论】:

  • 你的问题很不清楚。您期望输出什么?您的 hasPattern 函数没有返回任何内容。您的 5 个样本阵列的预期结果是什么?
  • 你说得对,我应该解释得更好。我在 Swift-Playgrounds 中编写了这个块,所以我能够看到 print() 行的输出。在这一行上,我将添加一个数组并附加结果编号。然后将返回该数组。因此,目标是扫描数组以查找重复数字的模式,将模式添加到数组中并返回它。所以对于 array4 它将返回数组 [4, 12] 中的数字
  • 也就是说,您正在检查每个数组是否包含一个多次出现的子数组(最长为 4)?您想要满足条件的最长子数组还是满足条件的所有子数组?
  • 是的,正确,所有子数组都需要。因此,对于数组 5,它将返回 2 个数字 39、78 和 78、324 的 2x 模式。如果我选​​择 3 个数字的模式,它将只返回一个模式 39、78、324

标签: arrays swift algorithm numbers pattern-matching


【解决方案1】:

我仍然觉得你的问题并不完全清楚。数组 [2,3,2,3,2] 是否有 2 个重复的 [2,3,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")
}

【讨论】:

  • 谢谢。一个出色而快速的解决方案。正是我想要达到的目标!
【解决方案2】:

您的问题在于您的内部循环。对于一个大小为 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 是您要搜索的数组。

【讨论】:

  • 谢谢。但是这个块缺少我认为的东西。首先,我传递一个数组以在您的函数中进行搜索,您将其指定为“元素”。你的意思是“数组”吗?如果是这样,元素数组来自哪里以及如何更新?我认为缺少一行,将带有模式的数字附加到元素数组中,因此计数也会更新。
  • 当我将元素更改为括号中的数组时,它总是返回true,即使它应该是false。另一件事是,我实际上需要模式编号来进一步使用它们。我不需要坚持我的版本,你的承诺是更清洁的方法,但我如何让它正常工作?
  • 它被命名为elements 是有原因的。在通用语言中,将函数命名为 hasPattern: of elements 而不是 hasPattern: of array 更有意义。您不是在寻找数组模式,而是在寻找元素模式。这是一种设计选择,但不会影响功能,因为 Array 对象仍作为参数传递。为什么要附加任何东西?元素数组是一个参数。当您想确定数组是否包含元素模式时调用该函数。该函数返回一个布尔值,因为您的问题是“检查给定数组并确定...”
  • 很抱歉显得愚蠢,但在这种情况下,“数组”是什么?它来自哪里以及它是如何增加它的计数的?您发布的“数组”是我正在搜索的数组,但它应该是“元素”这让我感到困惑
猜你喜欢
  • 1970-01-01
  • 2015-03-28
  • 2016-03-11
  • 1970-01-01
  • 1970-01-01
  • 2010-09-21
  • 2012-04-10
  • 2019-10-23
  • 1970-01-01
相关资源
最近更新 更多