Как найти, какое значение ближе всего к числу в C? - PullRequest
5 голосов
/ 23 ноября 2011

У меня есть следующий код в C:

#define CONST 1200
int a = 900;
int b = 1050;
int c = 1400;

if (A_CLOSEST_TO_CONST) {
  // do something
}

Какой удобный способ проверить, является ли a ближайшим значением CONST среди a, b и c?

Edit:

Неважно, если у меня есть 3 переменные или такой массив (это может быть более 3 элементов):

int values[3] = {900, 1050, 1400};

Ответы [ 8 ]

4 голосов
/ 23 ноября 2011

Работает для трех переменных:

if (abs(a - CONST) <= abs(b - CONST) && abs(a - CONST) <= abs(c - CONST)) {
    // a is the closest
}

Работает с массивом из одного или нескольких элементов, где n - количество элементов:

int is_first_closest(int values[], int n) {
    int dist = abs(values[0] - CONST);
    for (int i = 1; i < n; ++i) {
        if (abs(values[i] - CONST) < dist) {
            return 0;
        }
    }
    return 1;
}

Смотрите, как работает онлайн: ideone

3 голосов
/ 23 ноября 2011

Сравните абсолютное значение (a-CONST), (b-CONST) и (c-CONST).Какое бы абсолютное значение ни было наименьшее, это самое близкое.

2 голосов
/ 23 ноября 2011

Вот обобщенный метод. Функция min_element() принимает массив int, размер массива и указатель на функцию сравнения. Предикат сравнения возвращает true , если первые значения меньше второго значения. Функция, которая только что вернула a < b, нашла бы самый маленький элемент в массиве. Предикат сравнения pinouchon() выполняет ваше сравнение близости .

#include <stdio.h>
#include <stdlib.h>

#define CONST 1200

int pinouchon(int a, int b)
{
    return abs(a - CONST) < abs(b - CONST);
}

int min_element(const int *arr, int size, int(*pred)(int, int))
{
    int i, found = arr[0];
    for (i = 1; i < size; ++i)
    {
        if (pred(arr[i], found)) found = arr[i];
    }
    return found;
}

int main()
{
    int values[3] = {900, 1050, 1400};
    printf("%d\n", min_element(values, 3, pinouchon));
    return 0;
}
1 голос
/ 23 ноября 2011

Я добавляю что-то в коде Марка Байреса .....

int is_first_closest(int values[]) {
    int dist = abs(values[0] - CONST),closest;     //calculaing first difference
    int size = sizeof( values )                    //calculating the size of array
    for (int i = 1; i < size; ++i) {
        if (abs(values[i] - CONST) < dist) {       //checking for closest value
             dist=abs(values[i] - CONST);          //saving closest value in dist
             closest=i;                            //saving the position of the closest value
        }
    }
    return values[i];
}

Эта функция будет принимать массив целых чисел и возвращать число, наиболее близкое к CONST.

0 голосов
/ 23 ноября 2011

псевдокод:

closest_value := NULL
closest_distance := MAX_NUMBER
for(value_in_list)              
    distance := abs(value_in_list - CONST)
    if (distance < closest_distance)
        closest_value := value_in_list
        closest_distance := distance
print closest_value, closest_distance        
0 голосов
/ 23 ноября 2011

Для большого отсортированного набора вы должны иметь возможность использовать двоичный поиск, чтобы найти два числа, которые (по модулю краевых случаев) граничат с числом, одно из которых должно быть ближайшим.

Таким образом, вы сможете достичь производительности O (Log n) вместо O (n).

0 голосов
/ 23 ноября 2011

Этот ответ является реакцией на ваше редактирование исходного вопроса и ваш комментарий.(Обратите внимание, что для определения конца массива мы могли бы использовать разные подходы, один из которых я буду использовать в этом конкретном сценарии, является самым простым.)

// I think you need to include math.h for abs() or just implement it yourself.
// The code doesn't deal with duplicates.
// Haven't tried it so there might be a bug lurking somewhere in it.

const int ArraySize = <your array size>;
const int YourConstant = <your constant>;
int values[ArraySize] = { ... <your numbers> ... };
int tempMinimum = abs(YourArray[0] - YourConstant); // The simplest way
    for (int i = 1; i < ArraySize; i++) { // Begin with iteration i = 1 since you have your 0th difference computed already.
        if (abs(YourArray[i] - YourConstant) < tempMinumum) {
            tempMinumum = abs(YourArray[i] - YourConstant);
        }
    }

// Crude linear approach, not the most efficient.
0 голосов
/ 23 ноября 2011

Вам нужно сравнить свою константу с каждым элементом. (хорошо работает для 3 элементов, но это очень плохое решение для большего количества элементов, и в этом случае я предлагаю использовать какой-то метод «разделяй и властвуй»). После того, как вы сравните это, возьмите их различия, самая низкая разница - та, к которой самое близкое значение const)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...