插值搜索?

Interpolation search?

我有一个统一的一维网格,其值为 {0.1, 0.22, 0.35, 0.5, 0.78, 0.92}。这些值从位置 0 到 5 的位置相等,如下所示:

value       0.1      0.22      0.35       0.5      0.78      0.92
             |_________|_________|_________|_________|_________|
    
position     0         1         2         3         4         5

现在我喜欢 extract/interpolated 值定位,比如说 2.3,应该是

val(2.3) = val(2)*(3-2.3) + val(3)*(2.3-2)
         = 0.35*0.7 + 0.5*0.3
         = 0.3950

那么我应该如何在 C++ 中以优化的方式进行呢?我在 Visual Studio 2017.

我可以想到二分查找,但是有没有更好的方法 methods/or 来完成这项工作?谢谢

您可以获得插值的整数部分,并使用它来索引您需要在其间进行插值的两个值。无需使用二进制搜索,因为您始终知道在哪两个值之间进行插值。如果可能发生,只需要注意值之外的索引。

这仅在值始终映射到从零开始的整数索引时有效。

#include <cmath>

float get( const std::vector<float>& val, float p )
{
  // let's assume p is always valid so it is good as index
  const int a = static_cast<int>(p); // round down
  const float t = p - a;
  return std::lerp(val[a], val[a+1], t); 
}

编辑:

std::lerp 是一个 c++20 特性。如果您使用早期版本,您可以使用以下应该足够好的实现:

float lerp(float a, float b, float t)
{
   return a + (b - a) * t;
}