从统一网格中找到最接近的数字
Posted
技术标签:
【中文标题】从统一网格中找到最接近的数字【英文标题】:Find closest number from uniform grid 【发布时间】:2014-02-17 10:55:30 【问题描述】:我有一个整数正数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) = 5
、F(5, 7) = 5
、F(5, 8) = 10
、F(5, -13) = -15
等等。
我写了这个函数:
int const x = ((::abs(N) + (n / 2)) / n) * n;
if (N > 0)
return x;
else
return -x;
它似乎有效,但不喜欢它的外观。有人可以提出任何改进建议吗?
【问题讨论】:
F(4,2)的结果是什么? IE。这种舍入方法是向上还是向下舍入?那么 F(4,-2) 呢?它是向上取整还是远离零? 如果您只是想改善外观,这应该是一个品味问题。您可以更改为: int const x = (N>0?1:-1)*(::abs(N) + (n / 2)) / n) * n; 【参考方案1】:您可以通过将 x 乘以 (N/abs(N))
并立即返回计算值来摆脱 if
语句,甚至无需将其保存在 x
中。
我不会这样做,因为它会损害可读性。
【讨论】:
【参考方案2】:这可能很容易理解并且看起来很均匀,
int grid(int n, int N)
if (N == 0) return N;
return n * (N > 0 ? (n + N)/n : (n + abs(N))/n );
这是ideone 结果。
【讨论】:
【参考方案3】: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】:这是简单的数学解决方案:-
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;
【讨论】:
让 k = 5, x = 6. abs(6-6/5) 设 k = 5, x = 121。abs(121-121/5)=abs(121-24) > 5/2。你的公式给出 (121/5)*5 + sign(121)*5 = 125 这是错误的。正确答案是 120。 @Nick 很抱歉再次忘记在不等式中乘以 k。检查我的编辑【参考方案5】:您正在描述一种舍入算法;您需要指定舍入是否对称,然后是向上还是向下(或朝向/远离零对称)。 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
【讨论】:
以上是关于从统一网格中找到最接近的数字的主要内容,如果未能解决你的问题,请参考以下文章