带有浮点数的流行两和算法问题

时间:2019-09-30 06:25:53

标签: floating-point rounding

存在一个流行的算法问题,称为“两次和”。对于那些不了解它的人,这里有个简短的描述。您会得到一个包含n个元素和目标数字的数字数组。您应该在数组中找到2个数字,以便它们加起来等于目标数字。

此问题可以在Leetcode上找到。

https://leetcode.com/problems/two-sum/

数组中的数字通常以整数形式给出。这是我的问题。如果数组用浮点数代替,该如何解决这个问题?由于舍入错误,此问题更加困难。

我知道这是一个非常笼统的问题陈述。例如,解决此问题的方法实际上取决于目标数是否限于整数或也可以是浮点数。我认为,为了使此问题有意义,目标数必须限制为整数(如果我输入错误,请更正我)。但是,除此之外,可以执行哪些一般性思想/技术来处理此问题的舍入错误?

1 个答案:

答案 0 :(得分:1)

查找浮点和

如果问题是要找到两个数组元素 x y ,使它们的总和成为目标数 z ,则添加浮点数-点算术,那么浮点舍入问题在很大程度上是不相关的。

“两次和”问题的算法是:

  1. 对元素进行排序。 (要记住它们在数组中的原始索引,请将元素与其索引关联,并在排序时保留这些关联。)
  2. 设置L指向最低元素,H指向最高元素。
  3. 虽然L早于H:
    • 如果*L(由L指向的数字)和*H的和为 z ,则停止。所需的元素是*L*H
    • 如果总和小于 z ,请提前L
    • 如果总和大于 z ,请减少H
  4. 停止。没有解决办法。

浮点舍入不是问题,因为浮点加法(弱)是单调的:如果 x 0 < x的浮点和 1 ,则 x 0 y 的浮点和小于或等于到 x = 1 y 的浮点和。这意味着算法中的*L*H的测试总和总是正确地指示必须调整LH才能继续搜索-如果测试总和太低,那么我们需要一个更大的数字,因此必须L进行高级设置。同样,如果测试总和过高,则必须减小H。这样就不会错过任何解决方案。

查找实数总和

如果问题是要找到两个数组元素 x y ,则在将它们与实数相加时,目标和为 z 数字算术,那么上述算法只要对测试进行简单的修改就足够了。

将上面的第3步替换为:

  • 使用舍入到最近的浮点运算来评估s = *L + *H; z = s - *L; t = *H - z;。然后,在实数算法中,s + t就是*L + *H 1 s包含最高有效位和({浮点数中可表示的最接近值)的一部分,并且t包含s*L*H的实数和的误差或偏差。如果s等于 z 并且t等于零,则停止。所需的元素是*L*H
  • 如果s < z s = z t <0,则前进L。 / li>
  • 否则,请减少H

脚注

1 Muller等人,浮点算法手册,2010年,定理4,第126-129页。