Reputation: 1965
This function works correctly when I don't implement it generically (just with ints), but when I go to make it generic, changing only a few letters with no obvious errors, Swift is unable to compile it; I don't even use the func, simply having the file in my project crashes it.
Xcode says that "an internal error has occurred." I checked the stack trace, and the error is listed as "Segmentation Fault: 11." I'll post my code below.
I can also post the stack trace upon request.
import Foundation
func BinSearch<T : Comparable>(elements: [T], target: T) -> Int?{
let maxIndex = elements.count - 1
var rightIndex = maxIndex
var leftIndex = 0
var middleIndex : Int {return lround(Double((rightIndex + leftIndex)) / 2)}
var maxVal : T {return elements[rightIndex]}
var middleVal : T {return elements[middleIndex]}
var minVal : T {return elements[leftIndex]}
while elements[middleIndex] != target {
//test if in infinite loop for target within range of array but DNE
if leftIndex == middleIndex || rightIndex == middleIndex && rightIndex != 1{
return nil
}
//prevent infinite loop due to rounding method
if rightIndex == 1 {
return leftIndex
}
//core code
if target > middleVal {
leftIndex = middleIndex
}else {
rightIndex = middleIndex
}
}
return middleIndex
}
Upvotes: 4
Views: 3238
Reputation: 4918
In my case I got this error when using typealias
in old Swift 2 format in a Swift 3 environment, for instance :
(Void -> Void)
instead of
(() -> ())
Upvotes: 1
Reputation: 539745
The compiler should not crash, no matter how "wrong" the source code is, so you might consider to file a bug report.
In this case, the problem seems to be that middleVal
is a computed
property. If you replace
//core code
if target > middleVal {
leftIndex = middleIndex
}else {
rightIndex = middleIndex
}
by
//core code
if target > elements[middleIndex] {
leftIndex = middleIndex
}else {
rightIndex = middleIndex
}
then the code compiles. However, it does not work correctly. For example
BinSearch(elements: [3, 4, 5], target: 2)
returns 0
instead of nil
. (Also I see no advantage in using
computed properties for middleIndex
and middleVal
.
maxVal
and minVal
are not used at all in your code.)
Here is an example of a correctly working implementation (inspired by http://rosettacode.org/wiki/Binary_search#Swift):
func binarySearch<T : Comparable>(elements: [T], target: T) -> Int? {
var leftIndex = 0
var rightIndex = elements.count - 1
while leftIndex <= rightIndex {
let middleIndex = (leftIndex + rightIndex) / 2
if elements[middleIndex] < target {
leftIndex = middleIndex + 1 // Continue search in upper half.
} else if target < elements[middleIndex] {
rightIndex = middleIndex - 1 // Continue search in lower half.
} else {
return middleIndex // Found.
}
}
return nil // Not found.
}
Upvotes: 1