钳位到系列中的下一个最小值

Posted

技术标签:

【中文标题】钳位到系列中的下一个最小值【英文标题】:Clamping to next lowest value in a series 【发布时间】:2018-02-21 03:50:50 【问题描述】:

我正在尝试将一个数字限制为一系列数字的较低值。例如,如果我有一个系列(抱歉记号不好)

[pq] 其中p 是任意整数,q 是任意正数。

说如果q is 50 我的系列将是...-150, -100, -50, 0, 50, 100, 150...

现在我想要一个函数f(y),它将任何数字夹在系列中的下一个最低数字。

例如,如果我有号码 37,我期待的是 f(37) = 0,我期待的是 f(-37) = -50

我尝试了许多涉及模数和整数除法的算法,但我似乎无法弄清楚。例如,我尝试过的最新版本是

(37 / q) * q 适用于正数,但不适用于 -50 到 0 之间的任何数字。

我也尝试过((37 - q) / q) * q,但这不适用于完全属于该系列的负面案例。

编辑

假设我没有整个系列,而只有系列的乘数 p

【问题讨论】:

你不能用if处理负数和正数之间的差异吗? @MarkRansom `if(x 我不知道整数除法,但让我们看看是否有人比我更聪明。 @Archmede:但什么是“纯数学”,什么不是?您需要的表达式是f(y) = [y / q] * q,其中[] 代表“向负无穷舍入”。这种四舍五入是否符合“纯数学”的条件? 【参考方案1】:

您只需使用整数欧几里得除法将y 除以q,然后再将结果乘以q

f(y) = (y / q) * q

其中/ 表示欧几里得除法。

在不立即支持欧几里得除法的编程语言中,您必须手动实现它或调整该语言支持的任何除法的结果。

例如,在 C 和 C++ 中,对于正除数 q 的欧几里得除法可以通过原生的“Fortran 风格”除法实现为

 (y >= 0 ? y : y - q + 1) / q

所以在 C 或 C++ 中,整个表达式看起来像

f(y) = (y >= 0 ? y : y - q + 1) / q * q

37 你得到

f(37) = 37 / 50 * 50 = 0

-37 你得到

f(-37) = (-37 - 50 + 1) / 50 * 50 = -86 / 50 * 50 = -50

【讨论】:

【参考方案2】:

如果您想要一种纯粹的数学方式,而不考虑计算效率,您可以通过添加一个大于或等于 |p| 并且是q 的倍数,然后通过减法将其移回。 p^2*q 满足这一点。

这给出: ((p + p^2*q) / q) * q - p^2*q

【讨论】:

【参考方案3】:

确定模数结果为正数后,您可以减去该模数结果。在某些语言中,它总是是肯定的,但如果不是:

mod = p % q
positive_mod = (mod + q) % q
answer = p - positive_mod

C++ 中的结果:https://ideone.com/kIuit8

Python 中的结果:https://ideone.com/w6wUgZ

【讨论】:

以上是关于钳位到系列中的下一个最小值的主要内容,如果未能解决你的问题,请参考以下文章

按要求编写字符界面(算法初阶最小值和最大值)填充每个节点的下一个右侧节点指针(树深度优先搜索)最大矩形(栈数组)

三角形最小路径和

算法系列——寻找旋转排序数组中的最小值

算法系列——寻找旋转排序数组中的最小值

算法系列——寻找旋转排序数组中的最小值(剑指offer)

算法系列——寻找旋转排序数组中的最小值(剑指offer)