gpt4 book ai didi

arrays - Swift:使用二进制搜索在数组中找到最接近的值

转载 作者:搜寻专家 更新时间:2023-11-01 05:31:56 26 4
gpt4 key购买 nike

我尝试使用二进制搜索在数组中找到最接近的值。只要我要查找的值不小于数组中的最小值,一切都正常。

不幸的是,调试器没有产生任何有用的结果。所以我现在问社区。您也可以直接在 Xcode Playground 中尝试代码。我试图将另一个搜索值更改为数组中的较小值,但得到了相同的错误。错误:错误:执行被中断,原因:EXC_BAD_INSTRUCTION(代码=EXC_I386_INVOP,子代码=0x0)。

func closestValue(_ arr: [Int],_ target: Int) -> Int {
var leftPointer = 0
var rightPointer = arr.count-1

while leftPointer < rightPointer {
let middleIndex = (leftPointer + rightPointer) / 2
let middleValue = arr[middleIndex]

if middleValue == target {
return middleValue
}

//Check for out of bounds error
let leftIndex = middleIndex-1
let leftValue = arr[leftIndex]

if leftValue <= target && middleValue >= target {
let leftDistance = abs(leftValue-target)
let rightDistance = abs(middleValue-target)

if leftDistance <= rightDistance {
return leftValue
} else {
return middleValue
}
}
if middleValue <= target {
leftPointer = middleIndex+1
} else {
rightPointer = middleIndex
}
}
guard let first = arr.first, let last = arr.last else {
fatalError()
}

if target <= first {
return first
} else if target >= last {
return last
} else {
fatalError()
}
}
let first = [1,2,3,5,5,5,7,9,19,11] // 6 --> 5
let second = [1,2,3] // 8 --> 3
let third = [9, 10, 22, 59, 67, 72, 100] // 70 --> 72
let fourth = [100, 101, 102] //5 --> 100 => Heres the error

print(closestValue(first, 6))
print(closestValue(second, 8))
print(closestValue(third, 110))
print(closestValue(fourth, 5))

我期望第四个输出 100。因为 100 是第四个数组中最接近 5 的值。

最佳答案

我可以看到您进行了一些边界检查,但它们应该发生在函数的开头而不是结尾。请允许我重写整个函数:

func closestValue(_ arr: [Int],_ target: Int) -> Int {
// Array must not be empty
guard arr.count > 0 else { fatalError("Array must not be empty") }

// If array has only 1 element, that element is the closest
guard arr.count > 1 else { return arr[0] }

// To use binary search, your array must be ever-increasing or ever-decreasing
// Here, we require that the array must be ever-increasing
for index in 1..<arr.count {
if arr[index - 1] > arr[index] {
fatalError("Array must be monotonous increasing. Did you forget to sort it?")
}
}

// If the target is outside of the range of the array,
// return the edges of the array
guard arr.first! <= target else { return arr.first! }
guard target <= arr.last! else { return arr.last! }

// Now some actual searching
var left = 0
var right = arr.count - 1

while left < right {
if left == right - 1 {
return abs(arr[left] - target) <= abs(arr[right] - target) ? arr[left] : arr[right]
}

let middle = (left + right) / 2
switch arr[middle] {
case target:
return target
case ..<target:
left = middle
default:
right = middle
}
}

fatalError("It should never come here")
}


let first = [1,2,3,5,5,5,7,9,11,19] // 6 --> 5
let second = [1,2,3] // 8 --> 3
let third = [9, 10, 22, 59, 67, 72, 100] // 70 --> 72
let fourth = [100, 101, 102] //5 --> 100

print(closestValue(first, 6))
print(closestValue(second, 8))
print(closestValue(third, 70))
print(closestValue(fourth, 5))

一些注意事项:

  • if left == right - 1 { ... }允许 while循环终止。否则,整数除法将取整 middle向左,导致无限循环。
  • case ..<target是“when arr[middle] < target”的简写
  • while应该总能找到解决方案并从内部返回,但我还没有彻底测试过。如果你发现它到达最后一个 fatalError 的情况, 让我知道。
  • 第一个例子有两个答案:5 和 7 都与 target = 6 相差 1 .

关于arrays - Swift:使用二进制搜索在数组中找到最接近的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56926496/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com