【问题标题】:Finding elements in array with binary search使用二分搜索查找数组中的元素
【发布时间】:2014-04-22 09:30:45
【问题描述】:

尝试使用Arrays.binarySearch() 在数组中搜索字符串并返回索引。但是每次我打电话给Arrays.binarySearch() 我都会得到以下异常 -

Exception in thread "main" java.lang.NullPointerException
at java.util.Arrays.binarySearch0(Unknown Source)
at java.util.Arrays.binarySearch(Unknown Source)
at project.ArrayDirectory.lookupNumber(ArrayDirectory.java:97)
at project.test.main(test.java:12)

这是我的ArrayDirectory class -

    public class ArrayDirectory implements Directory {

static Entry[] directory = new Entry[50];

@Override
public void addEntry(String surname, String initials, int extension) {

    int n = 0;
    for (int i = 0; i < directory.length; i++) { // counting number of
                                                    // entries in array
        if (directory[i] != null) {
            n++;
        }

    }

    if (n == directory.length) {
        Entry[] temp = new Entry[directory.length * 2]; // if array is full
                                                        // double the
                                                        // length.

        for (int i = 0; i < directory.length; i++)
            temp[i] = directory[i];
        directory = temp;
    }

    int position = -1;
    for (int i = 0; i < directory.length; i++) {

        position = i;

        if (directory[i] != null) { // sorting the array into alphabetical
                                    // order by surname.

            int y = directory[i].getSurname().compareTo(surname);
            if (y > 0) {
                break;
            }
        }

        else if (directory[i] == null) {
            break;
        }

    }

    System.arraycopy(directory, position, directory, position + 1,
            directory.length - position - 1);

    directory[position] = new Entry(initials, surname, extension); // placing
                                                                    // new
                                                                    // entry
                                                                    // in
                                                                    // correct
                                                                    // position.

}

@Override
public int lookupNumber(String surname, String initials) {
    // TODO Auto-generated method stub

    Entry lookup = new Entry(surname, initials);
    int index = Arrays.binarySearch(directory, lookup);
    return index;
}

} 任何想法如何使用二进制搜索来找到正确的索引?

感谢您的帮助。

编辑 -

我还在我的Entry 类中覆盖了comapreTo-

public int compareTo(Entry other) {
    return this.surname.compareTo(other.getSurname());
}

【问题讨论】:

    标签: java arrays binary-search


    【解决方案1】:

    在您调用

    int index = Arrays.binarySearch(directory,lookup);
    

    directory 似乎只包含 null 元素。检查您是否正确初始化元素。

    【讨论】:

    • 查看我的测试类后,我意识到我没有正确初始化我的Entry 对象。当我纠正这个问题时,它最初似乎解决了我的问题,但经过进一步测试,当我多次调用 lookupNumber(surname,initials) 时,我再次遇到相同的异常。关于我做错了什么的任何想法?谢谢
    • @Nick 目录或其元素为空。这些行中的任何其他内容都不会导致 NPE。在使用它们之前尝试记录它们的值。
    【解决方案2】:

    我注意到两件事:

    static Entry [] directory = new Entry [1];
    

    首先,该代码为数组中的一个条目分配空间。它实际上并没有实例化一个条目。也就是说,directory[0]null。其次,对具有一个条目的数组进行二分搜索是疯狂。只有一个元素。它必须是directory[0]。最后,您应该对数组进行排序以对其进行二进制搜索。

    【讨论】:

    • 刚刚注意到,抱歉,这是一个错误,数组应该设置为更大的长度,例如 50 左右,之前正在测试将数组的大小加倍。
    【解决方案3】:

    二分搜索背后的基本概念是以下步骤的递归(注意搜索假设元素列表或数组以某种形式排序并且元素存在于其中。):

    1. 转到数组的中间元素。

    2. 检查搜索到的元素是否等于中间的元素。如果是则返回其索引。

    3. 如果不是,则检查搜索到的元素是否比中间的元素“小”或“大”。

    4. 如果它更小,则仅使用数组的下半部分/前半部分而不是整个数组进入第 1 步。

    5. 否则,仅使用数组的上半部分/后半部分而不是整个数组,转到第 1 步。

    随着数组不断被分成 2,它最终会达到 1 的大小并给出结果。

    现在,假设您正在 int 数组中查找整数。下面是代码的样子:

    public static int binarySearch(int number, int[] array)
    {
        boolean isHere = false;
        Integer index =0;
    
        for(int i=0;i<array.length;i++)
        {
            if(array[i] == number)
            {
                isHere = true;
                i = array.length;
            }
        }
        if(!isHere)
        {
            index = -1;
        }
        else
        {
            int arrayStart = 0;
            int arrayEnd = array.length;
             index = binarySearch(number, arrayStart, arrayEnd, array);
        }
    
        return index;
    }
    
    
    private static int binarySearch(int number, int start, int end, int[] array)
    {
        // this formula ensures the index number will be preserved even if 
               // the array is divided later.
        int middle = (start+ end)/ 2;
    
        if(array[middle] == number)
        {
            return middle;
        }
        else
        {
            if(number < array[middle])
            {
                //searches the first half of the array
            return binarySearch(number, start, middle, array);
            }
            else
            {
                // searches the last half of the array
                return binarySearch(number, middle, end, array);
            }
        }
    }
    

    您可以在示例中使用 compareTo() 方法代替 , & == 运算符。逻辑应该还是一样的。

    【讨论】:

      猜你喜欢
      • 2020-11-01
      • 2021-01-20
      • 1970-01-01
      • 2019-11-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-13
      相关资源
      最近更新 更多