我有一个数组“a”,如下所示:
let a = [1.0, 2.0, 10.0, 0.0, 5.0] // original array
我希望使用二进制搜索在“a”中找到数字10.0。
为此,我对数组进行排序以获得数组“asr”:
let asr = a.sorted()
print(asr)
// [0.0, 1.0, 2.0, 5.0, 10.0]
在“asr”中二进制搜索10.0将返回index = 4.而我正在查找原始数组“a”中的index = 2。而且我也在寻找速度,因为我的阵列很长。
有什么建议吗?
我粘贴在我正在使用的二进制搜索算法下面:
func binarySearch<T:Comparable>(inputArr:Array<T>, searchItem: T)->Int{
var lowerIndex = 0;
var upperIndex = inputArr.count - 1
while (true) {
let currentIndex = (lowerIndex + upperIndex)/2
if(inputArr[currentIndex] == searchItem) {
return currentIndex
} else if (lowerIndex > upperIndex) {
return -1
} else {
if (inputArr[currentIndex] > searchItem) {
upperIndex = currentIndex - 1
} else {
lowerIndex = currentIndex + 1
}
}
}
}
我给出了我的x(时间)和y(值)数组的示例。对于多个这样的数组,我需要在y中找到最大值并存储相关的唯一x值。
let x = [230.0, 231.0, 232.0, 233.0, 234.0, 235.0, 236.0, 237.0, 238.0, 239.0, 240.0, 241.0, 242.0, 243.0, 244.0, 245.0, 246.0, 247.0, 248.0, 249.0, 250.0, 251.0, 252.0, 253.0, 254.0, 255.0, 256.0, 257.0, 258.0, 259.0, 260.0, 261.0, 262.0, 263.0, 264.0, 265.0, 266.0, 267.0, 268.0, 269.0, 270.0, 271.0, 272.0, 273.0, 274.0, 275.0, 276.0, 277.0, 278.0, 279.0, 280.0, 281.0, 282.0, 283.0, 284.0, 285.0, 286.0, 287.0, 288.0, 289.0, 290.0, 291.0, 292.0, 293.0, 294.0, 295.0, 296.0, 297.0, 298.0, 299.0, 300.0, 301.0, 302.0, 303.0, 304.0, 305.0, 306.0, 307.0, 308.0, 309.0, 310.0, 311.0, 312.0, 313.0, 314.0, 315.0, 316.0, 317.0, 318.0, 319.0, 320.0, 321.0, 322.0, 323.0, 324.0, 325.0, 326.0, 327.0, 328.0, 329.0, 330.0, 331.0, 332.0, 333.0, 334.0, 335.0, 336.0, 337.0, 338.0, 339.0, 340.0, 341.0, 342.0, 343.0, 344.0] // unique ascending time stamps
let y = [-0.0050202642876176198, 0.022393410398194001, 0.049790254951834603, 0.077149678828730195, 0.104451119608423, 0.131674058448602, 0.15879803550636501, 0.185802665315146, 0.21266765210574901, 0.239372805059962, 0.26589805348529699, 0.29222346189943499, 0.31832924501308402, 0.34419578259991401, 0.36980363424246498, 0.39513355394291599, 0.42016650458771598, 0.444883672255248, 0.46926648035572899, 0.49329660359275201, 0.51695598173596602, 0.54022683319452802, 0.56309166838114799, 0.58553330285668204, 0.60753487024536401, 0.62907983491101405, 0.65015200438466503, 0.67073554153427395, 0.690814976467372, 0.71037521815772098, 0.72940156578721904, 0.74787971979453605, 0.765795792622184, 0.783136319153938, 0.79988826683476, 0.816039045465632, 0.83157651666592303, 0.84648900299618601, 0.86076529673452795, 0.87439466829995904, 0.88736687431637595, 0.89967216531114802, 0.91130129304248497, 0.92224551745010597, 0.93249661322397404, 0.94204687598616199, 0.95088912808120296, 0.95901672397057403, 0.96642355522725798, 0.97310405512663301, 0.979053202830236, 0.98426652715924901, 0.98874010995489703, 0.99247058902319396, 0.99545516066186102, 0.99769158176748995, 0.99917817152138799, 0.99991381265282298, 0.99989795227872502, 0.99913060231921702, 0.99761233948865402, 0.99534430486218395, 0.99232820301815805, 0.98856630075702201, 0.98406142539766805, 0.97881696265251605, 0.97283685408292797, 0.96612559413686105, 0.95868822677099297, 0.95053034165985795, 0.94165806999482904, 0.93207807987612601, 0.92179757130129403, 0.91082427075393002, 0.89916642539671898, 0.88683279687313799, 0.87383265472251104, 0.86017576941332496, 0.84587240500008198, 0.83093331140918203, 0.81536971635963695, 0.79919331692469797, 0.78241627074072795, 0.76505118686993401, 0.74711111632382299, 0.72860954225449404, 0.70956036982116599, 0.68997791573951905, 0.66987689752174295, 0.649272422415344, 0.62817997604904996, 0.60661541079433601, 0.584594933851312, 0.56213509506794002, 0.53925277450172504, 0.51596516973324402, 0.49228978294099801, 0.46824440774739501, 0.44384711584564701, 0.41911624341769299, 0.39407037735334999, 0.36872834128103499, 0.34310918142055002, 0.31723215226859403, 0.291116702127733, 0.26478245848970899, 0.23824921328407, 0.21153690800324301, 0.18466561871516801, 0.157655540974798, 0.130526974645817, 0.10330030864392201, 0.07599600561323, 0.048634586547227202, 0.0212366153658834] // y values (could be repeating)
答案 0 :(得分:0)
使用另一个保存索引的数组。像:
let indexArray = [0, 1, 2, 3, 4]
然后,无论何时切换原始数组中的数字,都要在indexArray中切换等效值。
最后,索引数组将是:
[3, 0, 1, 4, 2]
使用此功能可以轻松获取原始索引。 如果您发送用于排序的代码,我可以更改代码并告诉您如何操作..
另一种方法:
您可以保留原始数组的副本:
let copyArray = a.copy()
然后使用它来查找每个值的索引:
let indexOfA = copyArray.index(of: "aValue")
copyArray[indexOfA] = nil
// OR if the values are all positive
copyArray[indexOfA] = -1
答案 1 :(得分:0)
将二元搜索表达为递归算法是很自然的 - 并且通常更清晰,至少在您对递归感到满意时。怎么样:
func binarySearchHelper <T:Comparable> (array: Array<T>, item:T, lower:Int, upper:Int) -> Int? {
guard lower <= upper else { return nil }
let center = (lower + upper) / 2
return array[center] == item
? center
: ((lower == center ? nil : binarySearchHelper (array: array, item: item, lower: lower, upper: center)) ??
(upper == center + 1 ? nil : binarySearchHelper (array: array, item: item, lower: center + 1, upper: upper)))
}
func binarySearch <T:Comparable> (array: Array<T>, item:T) -> Int? {
return binarySearchHelper (array: array, item: item, lower: array.startIndex, upper: array.endIndex)
}