在两个数组值之间查找值

时间:2017-10-04 20:41:27

标签: java arrays bisection

我希望我的函数取值x并找到下面显示的数组值:

double[] xlist = {51.8, 10.3, 5.1, 2.6, 1.7, 1.29, 1.03, 0.86, 0.65, 0.52, 0.43, 0.37, 0.32, 0.29};
  • 示例1:当x = 1.5时,高值等于1.7并且低值等于1.29
  • 例2:当x = 12时,高值等于51.8,低值等于10.3

我正在使用二分法的导数来找到这些“高”和“低”值但我的代码有问题。我的代码如下所示:

public static void main(String[] args){
    double[] xlist = {51.8, 10.3, 5.1, 2.6, 1.7, 1.29, 1.03, 0.86, 0.65, 0.52, 0.43, 0.37, 0.32, 0.29};
    double x = 0.9; //or whatever declare x to equal
    int high = xlist.length;
    int mid = 0, low = 0;
    while (low != high) {
            mid = (low + high) / 2;
                if (xlist[mid] > x) {
                    low = mid + 1;
                } else {
                    high = mid;
                }
            }
    System.out.println(xlist[mid - 1] + "\n" + x + "\n" + xlist[mid]);
  }

我的控制台输出如下所示:

51.8
12.0
10.3

它有效,但是当我将x值更改为9.9时,我得到:

5.1
9.9
2.6

我做错了什么?非常感谢任何帮助。

3 个答案:

答案 0 :(得分:0)

当您划分SELECT t.groupId, ( SELECT td.some_data, td.some_other_data FROM some_table td WHERE t.groupId = td.groupId FOR JSON PATH ) As json_data FROM some_table t GROUP BY t.groupId 时,您将结果分配给和int值并丢失一些数据。我在下面做的是将high,mid和low的数据类型更改为“double”,然后在引用double数组中的元素时将值转换为int。请尝试以下代码。

(low + high)/2

答案 1 :(得分:0)

我建议采用一种更简单的方法:

  • 对数组进行排序
  • 使用Arrays.binarySearch(xlist, x)查找可以插入gsutil config的位置p
  • 如果xp >= 0位于数组中的该位置
  • 如果xp < 0是大于-p-1的最小元素的位置,x是小于{{的最大元素的位置1}}。

确保添加相关检查(-p-2等)

答案 2 :(得分:0)

问题出现是因为您正在更新mid,测试,然后更改lowhigh索引。如果在更新high = mid后循环退出,则mid值等于low索引,一切正常mid == low == high。如果在更新low = mid + 1后循环退出,则mid等于low,但现在为mid == low-1 == high-1。这导致了有时看到的一个一个错误。

如果搜索在数组末端附近运行,代码也会遇到ArrayIndexOutOfBoundsException。这是因为访问了xlist[mid-1],其中mid可以达到0high索引从数组末尾开始一个位置,如果用作索引,也会生成ArrayIndexOutOfBoundsException

更好的解决方案是在low0 high处开始xlist.length-1,然后循环到lowhigh限制相差1个指数。那时,它们正是您正在寻找的界限:

    int low = 0, high = xlist.length - 1;
    while (high - low > 1) {
        int mid = (low + high) / 2;
        if (xlist[mid] > x) {
            low = mid;
        } else {
            high = mid;
        }
    }
    System.out.println(xlist[low] + "\n" + x + "\n" + xlist[high]);