先看图:
需求很明确,要根据左边的值,显示右边的值。
比如,现在拿到的值是 17.12,那么应该显示成 15;拿到 17.599 ,那么应该显示成 20.
先找规律:
为了便于说明,暂且将左边的值设为 x, 右边的值设为 y.
- 第一行和最后一行可以写死成 0 与 1500;
- 余下的每行,x 的区间是 (min, min+5] , 对应的 y == min + 2.5,
那么,根据规律 2 ,也就是说 y-2.5==min; y+2.5 == max
。虽然这里有点投机取巧之嫌(因为刚好是 ± 2.5)。
根据 x 计算 y,如何计算呢?
思考 666 分钟之后,发现这个很难计算,虽然规律是显而易见的,但是,一个任意的 x ,又怎么去匹配到对应的行呢,似乎有点困难。
如果说弄一个 list 之类的容器去记录 x 的区间,这样似乎就失去了计算的意义,跟直接 switch case 也没什么区别了。
于是决定换个思路,从 y 下手,因为 y 的值更少,而且规律更显而易见。
我们这么看,拿到一个 x, 就去跟 (y-2.5, y+2,5] 比较, 因为 y 的数量是有限的,那么
就遍历查找 [0, 1500, step=5] ,只要 x 在 (y-2.5, y+2.5] 这个区间内,说明 这个 y 就是匹配的 y, 如果当前这个 y 不是,就继续遍历下去即可,反正总有一个 y 是能匹配上的。
以上的解决方案是可行的。但是,这样有一点点低效。
那么,我们可以使用一个简单的二分查找算法,我们不要 0, 5, 10, … 这样去递增 y , 而是 二分查找,从 750 开始,然后根据比较的结果去看看应该是去找 375 还是 1125, 依次类推,这样可以在 logn 的时间内找到对应的 y。
ok, 思路分析完毕,后面就是具体的代码实现了。 代码实现只要考虑一下细节即可。比如 不应该是 [0, 1500, 5] 这样去二分,而应该是 [0, 300, 1] 这样去二分。
static int binarySearch(double source) {
final double maxSource = 1500 - 2.5