如何在C语言中找到最接近某个数字的值?

5

我在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中最接近的值吗?

编辑:

无论我有3个变量还是像这样的数组(它可能有超过3个元素),都没有关系:

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

7
这是一个搜索练习。通常是找到最小的(val-CONST的绝对值)。 - bioffe
这更像是一个数学问题,而不是C编码问题。尝试将您的CONST和数字之间的差的绝对值最小化。 - Basile Starynkevitch
我不想要最接近的值,我想知道一个特定选择的变量(比如说a)是否是最接近的。 - Benjamin Crouzier
在第二行,将您的a与搜索结果进行比较(为了更好的结果,请缓存您的搜索结果)。 - bioffe
8个回答

4

这适用于三个变量:

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


这是个想法。我在想你是否可以轻松地将其推广到更多变量(例如4个变量)。 - Benjamin Crouzier
2
@pinouchon:如果您使用n个元素的数组而不是n个变量,那将会更好。 - Mark Byers
1
如果您想使用这种线性方法,可以将常量插入到数组中,并循环遍历它,比较每个元素。 - ScarletAmaranth
@markByers 我修改了我的问题,如果您有一个适用于数组的通用解决方案,我会很高兴。 - Benjamin Crouzier
让这个函数更通用的一种方法是传递第三个参数,表示我们感兴趣的整数的位置。如果您想保持 is_first_closest() 中的逻辑不变,只需在开始时将第一个值与所需位置的值交换,然后在返回之前再次交换即可。 - Taylor Price

3

比较 (a-CONST)、(b-CONST) 和 (c-CONST) 的绝对值。其中最小的绝对值就是最接近的。


2

这里有一个通用的方法。函数min_element()接收一个整型数组、数组大小和一个指向比较函数的指针。比较谓词如果第一个值小于第二个值,则返回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

我正在Mark Byres的代码中添加一些内容......

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];
}

这个函数将接受一个整数数组,并返回最接近常量的数字。


0

你需要将你的常量与每个元素进行比较。(对于3个元素来说效果很好,但对于更大的元素数量来说,这是一个非常糟糕的解决方案,此时建议使用某种分治方法)。在比较后,取它们之间的差值,最小的差值就是该常量最接近的值。


0
对于一个大的排序集合,你应该能够使用二分查找来找到两个数字,它们(除了边缘情况)围绕着这个数字,其中一个必须是最接近的。
因此,你可以实现O(Log n)的性能,而不是O(n)。

0

这个回答是针对您对原始问题的编辑和您的评论而做出的反应。(请注意,在确定数组结束时,我们可以使用不同的方法,我在这个特定的情况下将使用最简单的方法。)

// 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
伪代码:
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        

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接