📌  相关文章
📜  在C中实现upper_bound()和lower_bound()(1)

📅  最后修改于: 2023-12-03 15:07:52.784000             🧑  作者: Mango

在C中实现upper_bound()和lower_bound()

在C++ STL中,有两个非常常用的函数:lower_bound()upper_bound()。这两个函数都是用来在有序的容器中查找一个特定值的位置,但它们的返回值有所不同。lower_bound()返回的是第一个大于等于该值的位置,而upper_bound()则返回的是第一个大于该值的位置。

在C语言中,虽然没有STL库,但是我们可以自己实现这两个函数。

lower_bound()的实现

我们先来看看lower_bound()的实现,我们可以使用二分查找来实现:

int lower_bound(int *arr, int n, int value) {
    int left = 0, right = n - 1;
    while (left <= right) {
        int mid = (left + right) / 2;
        if (arr[mid] < value) {
            left = mid + 1;
        } else {
            right = mid - 1;
        }
    }
    return left;
}

这个函数的参数说明如下:

  • arr表示有序数组的指针;
  • n表示数组的长度;
  • value表示要查找的值。

在这个函数中,我们通过二分查找来找到第一个大于等于value的位置,最后返回该位置。

upper_bound()的实现

接下来我们看看upper_bound()的实现。我们同样可以使用二分查找,但是需要稍作修改:

int upper_bound(int *arr, int n, int value) {
    int left = 0, right = n - 1;
    while (left <= right) {
        int mid = (left + right) / 2;
        if (arr[mid] <= value) {
            left = mid + 1;
        } else {
            right = mid - 1;
        }
    }
    return left;
}

这个函数与lower_bound()类似,只不过在比较大小时,要将小于等于value的情况都归为大于value的情况。最后返回的是第一个大于value的位置。

使用示例

为了验证这两个函数的正确性,我们可以编写如下的测试代码:

#include <stdio.h>

int lower_bound(int *arr, int n, int value) {
    // 略去
}

int upper_bound(int *arr, int n, int value) {
    // 略去
}

int main() {
    int arr[] = {1, 2, 4, 4, 4, 5, 7, 8, 10};
    int n = sizeof(arr) / sizeof(int);
    int value = 4;
    int lower_idx = lower_bound(arr, n, value);
    int upper_idx = upper_bound(arr, n, value);

    printf("lower_bound() = %d\n", lower_idx);
    printf("upper_bound() = %d\n", upper_idx);

    return 0;
}

运行结果如下:

lower_bound() = 2
upper_bound() = 5

这表明我们的函数实现是正确的。

上述代码中,我们先定义了一个有序数组,然后分别调用了lower_bound()upper_bound()函数来计算出要查找的值在数组中的位置。最后打印出这两个位置。

总结

本文介绍了如何在C语言中实现lower_bound()upper_bound()这两个在STL中非常常用的函数。虽然C语言没有STL库,但是我们可以通过二分查找来实现这些函数。这样可以让我们在C语言中也能够愉快地进行查找和排序。