二进制搜索最近匹配的最接近匹配

时间:2014-11-25 11:26:16

标签: c algorithm binary-search upperbound last-occurrence

我正在实施有效的算法来搜索最后一次出现的事件(密钥或最近的匹配(上限))。

到目前为止,我得到了这个。

long bin_search_closest_match_last_occurance ( long  * lArray, long sizeArray, long lnumber)
{
    long left, right, mid, last_occur;

    left = 0;
    right = sizeArray - 1;
    last_occur = -1;

    while ( left <= right )
    {
        mid = ( left + right ) / 2;

        if ( lArray[mid] == lnumber  )
        {
            last_occur = mid;
            left = mid +1;
        }

        if ( lArray[mid] > lnumber ) 
            right = mid - 1;
        else 
            left = mid + 1;
    }
    return last_occur!=-1?last_occur:mid;
}

我们有一个数组{0,0,1,5,9,9,9,9},关键是6 Fce应返回索引7,但我的fce返回4

请注意,我不想线性迭代到最后一个匹配的索引。

记住我有解决方案,其中我更改参数fce(添加开始,结束索引)并使用fce从找到的上限到数组末尾执行另一个二进制搜索(仅当我找不到完全匹配时,{{1} })。

我想询问是否有更好/更清洁的解决方案来实施它?

1 个答案:

答案 0 :(得分:0)

nm的2-search方法将起作用,并且它保持最佳的时间复杂度,但是如果你开始第二次搜索,它可能会将常数因子增加大约2或大约1.5从第一次搜索结束的地方开始。

如果你选择&#34;普通&#34;二进制搜索,找到lnumber第一个实例(或者,如果它不存在,则为下限),并对其进行更改,以便算法在逻辑上反转&#34; #34;通过将每个数组访问lArray[x]更改为lArray[sizeArray - 1 - x](对于任何表达式x),以及&#34;反向&#34;通过将> lnumber测试更改为< lnumber来排序,然后仅需要单个二进制搜索。这个算法实际执行的唯一数组访问是对lArray[mid]的两次查找,如果它可以证明没有任何东西会改变访问之间的值,那么优化编译器很可能只评估一次(这可能需要添加{{} 3}}到long * lArray的声明;或者,您可以将元素加载到局部变量中并测试它两次)。无论哪种方式,如果每次迭代只需要一次数组查找,那么将索引从mid更改为sizeArray - 1 - mid每次迭代只会增加2次额外减法(如果--sizeArray之前只增加1次进入循环),我预计它不会像nm的方法那样增加常数。当然,和任何事情一样,如果表现至关重要,那就要测试一下;如果不是,那么就不要太担心保存微秒。

你还需要&#34;反向&#34;返回值也是:

return last_occur!=-1?last_occur:sizeArray - 1 - mid;