从均匀网格中查找最接近的数字

Find closest number from uniform grid

本文关键字:最接近 数字 查找 网格      更新时间:2023-10-16

我有一个整数正数n。例如,假设n=5。如果我们看一下 n 的乘法,我们看到这些数字(我们称之为 n-grid) [... -15, -10, -5, 0, 5, 10, 15, ...]。现在我需要编写一个函数F(n, N),给定一个整数N,从该 n 网格输出最接近的数字。例如,F(n, 0) = 0(对于任何 n)。 F(5, 4) = 5F(5, 7) = 5F(5, 8) = 10F(5, -13) = -15等。

我已经编写了这个函数:

int const x = ((::abs(N) + (n / 2)) / n) * n;
if (N > 0)
{
    return x;
}
else
{
    return -x;
}

似乎有效,但不喜欢它的外观。有人可以提出任何改进建议吗?

您可以通过将 x 乘以 (N/abs(N)) 并无限地返回计算值来摆脱 if 语句,甚至无需将其保存在 x 中。

但是,我不会这样做,因为这会损害可读性。

这可能很容易理解,甚至看起来都很容易,

int grid(int n, int N){
   if (N == 0) return N; 
   return n * (N > 0 ? (n + N)/n : (n + abs(N))/n );
}

这是 ideone 结果。

int closest_number(int n,int N)
{
    if(N==0)
        return N;
    else if(N > 0)
    {
       int temp = N % n;
       if(temp > (n/2))
           return (n*((N/n)+1));
       else
           return (n*(N/n));
    }
    else
    {
        int temp = N % n;
        if(abs(temp) > (n/2))
            return (n*((N/n)-1));
        else
            return (n*(N/n));
    }
}

您可以在此处找到给定测试用例集的 ideone 输出 http://ideone.com/NlJiPt

这是简单的数学解决方案:-

F(k,x) = (x/k)*k      if  abs(x-(x/k)*k) <= k/2

       = (x/k)*k + sign(x)*k    otherwise

C 实现 :-

#include<stdio.h> 
#include<math.h>
int func(int k,int x) {
 int a = (x/k)*k; 
 int sign = x/abs(x); 
  if(abs(x-a)<=k/2) 
     return(a); 
  else return(a+sign*k); 
}
int main() {
 printf("%d",func(5,121));
 return 0;
} 

您正在描述舍入算法; 您需要指定舍入是否对称,然后指定舍入是向上还是向下(或向/远离零表示对称)。 以下代码的 ideone 演示。

                                                       // F(4, 6)    F(4, -6)
int symmetricTowardZero(int n, int N) {
    return n * (int)(N / n);                           //    4         -4
}
int symmetricAwayFromZero(int n, int N) {
    return n * (int)(N / n + (N < 0 ? -0.5 : +0.5));   //    8         -8
}
int unsymmetricDownward(int n, int N) {
    return n * floor((double)N / n);                   //    4         -8
}
int unsymmetricUpward(int n, int N) {
    return n * ceil((double)N / n);                    //    8         -4
}