我编写了这个二进制搜索函数来定位索引序列中的特定值:
def locate(xs: IndexedSeq[Int], x: Int, l: Int, h: Int): Int = {
(l + h) / 2 match {
case m if h - l <= 1 => l
case m if x >= xs(m) => locate(xs, x, m, h)
case m => locate(xs, x, l, m)
}
}
当我有一个如下序列时,它会起作用:
Vector(1,2,3,9,15,26,89)
即,有序的独特元素序列。但是当有序序列中存在重复元素时,它不起作用,如:
Vector(1,2,3,3,15,15,89)
无法保证选择重复子序列的第一个元素。例如,如果我想搜索3,它可能不会给我序列中前3个的索引。
哪种算法可以有效地做到这一点?或者我可以修改我的二进制搜索序列,以便我轻松实现这一目标(同时仍然是尾递归)。
答案 0 :(得分:1)
基于C++'s lower_bound的算法,我认为这种改变就足够了:
def locate(xs: IndexedSeq[Int], x: Int, l: Int, h: Int): Int = {
l+(h-l)/2 match {
case m if h - l == 0 => l
case m if xs(m) < x => locate(xs, x, m+1, h)
case m => locate(xs, x, l, m)
}
}
我还更改了m
的计算代码,因为在极端情况下原始代码容易出现整数溢出。