C 与最后一次匹配的二进制搜索

C 与最后一次匹配的二进制搜索,c,algorithm,binary-search,upperbound,last-occurrence,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; w

我正在实现有效的算法来搜索最后一次出现的(关键点或最近的匹配(上界))

到目前为止,我知道了

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;
}
long bin\u search\u closest\u match\u last\u occurrence(long*lArray,long sizeArray,long lnumber)
{
长左、右、中、最后出现;
左=0;
右=sizeArray-1;
最后发生=-1;
while(左编号)
右=中-1;
其他的
左=中+1;
}
最后一次返回=-1?最后一次发生:中期;
}
让我们有一个数组
{0,0,1,5,9,9,9,9}
,键是
6
Fce应该返回索引
7
,但我的Fce返回
4

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

请记住,我有一个解决方案,我可以更改参数fce(添加开始、结束索引),并使用fce从找到的上限到数组的结尾进行另一个二进制搜索(仅当我没有找到精确匹配时,
last\u occurrent==-1


我想问一下,是否有更好/更干净的解决方案来实现它?

n.m.的2-search方法会起作用,并保持最佳的时间复杂度,但如果从第一次搜索结束的地方开始第二次搜索,则可能会将常数因子增加2左右,或增加1.5左右

相反,如果您进行“普通”二进制搜索,找到
lnumber
的第一个实例(或者,如果它不存在,则为下限),并对其进行更改,以便算法通过将每个数组访问
lArray[x]
更改为
lArray[sizerray-1-x]
(对于任何表达式
x
),从逻辑上“反转”数组,还可以通过将
>lnumber
测试更改为
来“反转”排序,然后只需要一次二进制搜索。此算法实际执行的唯一数组访问是对
lArray[mid]
的两次查找,如果优化编译器能够证明访问之间的值不会发生任何变化,则很可能只对其进行一次评估(这可能需要添加到
long*lArray
的声明中;或者,您可以将元素加载到局部变量中,并对其进行两次测试)。无论哪种方法,如果每次迭代只需要一个数组查找,那么将索引从
mid
更改为
sizerray-1-mid
将在每次迭代中仅添加2个额外减法(或者如果在进入循环之前
--sizerray
,则仅添加1个),我预计这不会像n.m.的方法那样增加常数。当然,与其他方法一样,如果性能很关键,那么测试它;如果性能不关键,那么不要太担心节省微秒

您还需要“反转”返回值:

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

不确定为什么它应该返回7。它要求查找该键的最后一次出现或最近的匹配,因此,如果该键不在列表中(这是您的示例)-根据我对任务描述的理解,返回4应该可以。@amit编辑了该问题。现在您打开{在您的while指令之后,您从未关闭它。@DanielDaranas是的,对不起,我一点也不知道为什么它会有用,但解决方法是运行两次上限搜索。