【发布时间】:2020-05-24 01:03:52
【问题描述】:
今天我做了一份作业的测试,并被要求通过一系列整数搜索,这是问题:
这个练习的目的是检查一个数字在一个 数组。
规格:
项目是按升序顺序排列的整数。
数组最多可以包含 100 万个项目
实现函数existsInArray(_ numbers: [Int], _ k: Int) 所以 它返回 true 如果 k 属于 numbers ,否则该函数 应该返回 false。
例子:
let numbers = [-9, 14, 37, 102] existsInArray(numbers, 102) // returns true existsInArray(numbers, 36) //returns false注意:尽量节省 CPU 周期
好的,所以我给出了我的答案,即下面的代码并等待结果
func existsInArray(_ numbers: [Int], _ k: Int) -> Bool {
if numbers.isEmpty {
return false
}
let numbersHalfIndex: Int = (numbers.count/2)
if k == numbers[numbersHalfIndex] {
return true
} else if k != numbers[0] && numbers.count == 1 {
return false
} else if k <= numbers[numbersHalfIndex] {
let leftHalfNumbersArray = numbers[0 ..< numbersHalfIndex]
return existsInArray(Array(leftHalfNumbersArray), k)
} else if k > numbers[numbersHalfIndex] {
let rightHalfNumbersArray = numbers[numbersHalfIndex ..< numbers.count]
return existsInArray(Array(rightHalfNumbersArray), k)
} else {
return false
}
}
事实证明 “解决方案在合理的时间内无法处理 100 万个项目” 现在我不知道我做错了什么,因为二进制搜索速度快到 f*ck .
我唯一的猜测是可能 number.count 或 numbers[0 ... 或 numbers[numbersHalfIndex ...使一切都比预期慢。
我是绊倒了还是怎么了?
编辑: 如果有人好奇,我测试了我的代码和 Martin R 代码,看看使用 ArraySlice 对时间的影响有多大。 从0开始,我使用一系列100.000.000 Itens的升序。 我是这样记录时间的:
print("////////// MINE //////////")
var startTime = CFAbsoluteTimeGetCurrent()
print(existsInArray(numbers, 0))
var timeElapsed = CFAbsoluteTimeGetCurrent() - startTime
print("Time elapsed for mine: \(timeElapsed) s.")
print("////////// Martin R //////////")
counter = 0
startTime = CFAbsoluteTimeGetCurrent()
print(existsInArrayOptimal(numbers, 0))
timeElapsed = CFAbsoluteTimeGetCurrent() - startTime
print("Time elapsed for Martin R: \(timeElapsed) s.")
结果如下:
/////////////////////////////
是的
我的时间过去了:
1.2008800506591797秒。
//////////马丁R //////////
是的
Martin R的时间:0.00012993812561035156 s。
大约快 1000 倍!
【问题讨论】:
-
你是在操场上测试吗?您是否尝试过使用endIndex而不是Count? span>
-
顺便说一句,您正在使用其切片初始化一个新数组
-
使用
Array(...)将切片转换回数组是您在其中做的最慢的事情。如果您在切片上的所有工作 span>
标签: arrays swift algorithm testing binary-search