Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> C++

Chương trình C++ tìm K phần tử gần giá trị X trong mảng đã sắp xếp

Cho mảng A đã sắp xếp, giá trị X và k. Tìm k phần tử gần X nhất. Nếu X có trong mảng thì không hiển thị. A=[12,16,22,30,35,39,42,45,48,50,53,55,56], X=35, k=4 → 30,39,42,45.

Dùng tìm kiếm nhị phân tìm điểm giao (crossover point). Sau khi tìm được chỉ số crossover, in k phần tử gần nhất trong O(k).

Ví dụ mã nguồn

#include <iostream>
using namespace std;

int getCrossoverPoint(int arr[], int left, int right, int x) {
    if (arr[right] <= x)
        return right;
    if (arr[left] > x)
        return left;
    int mid = (left + right) / 2;
    if (arr[mid] <= x && arr[mid+1] > x)
        return mid;
    if (arr[mid] < x)
        return getCrossoverPoint(arr, mid+1, right, x);
    return getCrossoverPoint(arr, left, mid-1, x);
}

void findKClosestNumbers(int arr[], int x, int k, int n) {
    int l = getCrossoverPoint(arr, 0, n-1, x);
    int r = l+1;
    int count = 0;
    if (arr[l] == x) l--;
    while (l >= 0 && r < n && count < k) {
        if (x - arr[l] < arr[r] - x)
            cout << arr[l--] << " ";
        else
            cout << arr[r++] << " ";
        count++;
    }
    while (count < k && l >= 0) {
        cout << arr[l--] << " ";
        count++;
    }
    while (count < k && r < n) {
        cout << arr[r++] << " ";
        count++;
    }
}

int main() {
    int arr[] = {12, 16, 22, 30, 35, 39, 42, 45, 48, 50, 53, 55, 56};
    int n = sizeof(arr)/sizeof(arr[0]);
    int x = 35, k = 5;
    findKClosestNumbers(arr, x, k, n);
}

Kết quả đầu ra

39 30 42 45 48