从统一网格中找到最接近的数字

时间:2014-02-17 10:55:30

标签: c++ algorithm

我有一个整数正数n。我们假设n=5为例。如果我们查看n的乘法,我们会看到这些数字(我们称之为n-grid)[... -15,-10,-5,0,5,10,15,...]。现在我需要编写一个函数F(n, N),给定一个整数N,从该n-grid输出一个最接近的数字。例如,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;
}

它似乎有效,但不喜欢它的样子。任何人都可以提出任何改进吗?

5 个答案:

答案 0 :(得分:0)

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

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

答案 1 :(得分:0)

这可能很容易理解并且看起来很均匀,

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

以下是ideone结果。

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

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

您可以在http://ideone.com/NlJiPt

找到给定测试用例集的ideone输出

答案 4 :(得分:0)

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

                                                       // 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
}