简体   繁体   English

需要帮助查看我的二进制搜索程序

[英]Need help reviewing my Binary Search program

I am trying to implement a binary search in Java, but I am having some issues with my code. 我正在尝试用Java实现二进制搜索,但是我的代码存在一些问题。 It works if the element I am looking for exists in the array. 如果我要查找的元素存在于数组中,它将起作用。 If it doesn't, the program doesn't print an error message. 如果不是,则程序不会显示错误消息。 What I mean here is - 我的意思是-

When I run my code - this is the output - 当我运行代码时-这是输出-

Please enter array size
2
Please enter element 0
3
Please enter element 1
4
Sorted array elements[3, 4]


Please enter the element you want to find in the array
3
Match 3 found at index 0

If however, I look for an element that doesn't exist in the array, the program doesn't enter the else loop, and print an error message - It instead does this - 但是,如果我查找数组中不存在的元素,则程序未进入else循环,并显示错误消息-而是这样做-

Please enter array size
2
Please enter element 0
3
Please enter element 1
4
Sorted array elements[3, 4]


Please enter the element you want to find in the array
2
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1
    at arraysPract.BinarySearch.findElement(BinarySearch.java:82)
    at arraysPract.BinarySearch.main(BinarySearch.java:54)

Here is the code - 这是代码-

package arrays;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;

public class BinarySearch {
    static int[] binaryArr = null;

    public static void main(String[] args) {
        BufferedReader br = null;
        String size = "";

        try {
            System.out.println("Please enter array size");
            br = new BufferedReader(new InputStreamReader(System.in));
            size = br.readLine();
            if (size == null) {
                System.out.println("Size can't be null");
                return;
            }
            int ipSize = Integer.parseInt(size);
            binaryArr = new int[ipSize];
            String entry = "";
            for (int i = 0; i < ipSize; i++) {
                System.out.println("Please enter element " + i);
                entry = br.readLine();
                if (entry == null) {
                    System.out.println("Value can't be null");
                    return;
                }
                int arrEntry = Integer.parseInt(entry);
                binaryArr[i] = arrEntry;
            }

            Arrays.sort(binaryArr);
            System.out.println("Sorted array elements"  + Arrays.toString(binaryArr));
            System.out.println("\n");

            System.out.println("Please enter the element you want to find in the array");
            String findArrayElement = br.readLine();
            int find = Integer.parseInt(findArrayElement);      
            boolean elementExists = Arrays.asList(binaryArr).contains(find);            
            if (elementExists==false) {             
                findElement(binaryArr, find);
            }

            else {
                System.out.println("Element does not exist. Please try again");
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static int findElement(int[] test, int keyElement) {
        boolean flag = true;
        int i = 0;
        for (i = test.length / 2; i >= 0 && i < test.length;) {
            if (keyElement == test[i]) {
                flag = false;
                break;
            } else if (keyElement > test[i]) {
                i++;
                if (keyElement == test[i]) {
                    flag = false;
                } else {
                    flag = true;
                }
            } else if (keyElement < test[i]) {
                i--;
                if (keyElement == test[i]) {
                    flag = false;
                } else {
                    flag = true;
                }
            }
        }

        if (flag == false) {
            System.out.println("Match " + keyElement + " found at index " + i);
        }
        return i;
    }
}

Request someone to please guide me if I am overlooking something thats an obvious error? 如果我忽略了明显的错误,请有人指导我。

Also, there are several possible duplicates for this post - Binary search in java , Binary search in java etc. I just need help with reviewing my code, not in implementing the program :) 另外,此帖子可能有重复的内容-Java中的二进制搜索,Java中的二进制搜索等。我只需要帮助查看代码即可,而不是在实现程序时:)

This is not binary search, you should keep dividing indices by two (or recurring, in recursive version). 这不是二进制搜索,您应保持将索引除以二(或递归版本)。 Instead, you are doing linear search, complicated (linear because index is incremented/decremented by 1, a constant, at each step) on the two halves of the array. 相反,您要对数组的两半进行复杂的线性搜索(线性搜索,因为索引在每个步骤上递增/递减1,一个常数)。

Anyway, your problem with 2 is that it is smaller than the smallest element of the array, so i gets decremented until it reaches 0 (first element); 无论如何,您对2的问题是它小于数组的最小元素,所以i递减直到它达到0(第一个元素); at that point, this line is executed: 此时,执行以下行:

i--;

And then, test[i] is called for comparison. 然后,调用test[i]进行比较。 But i will be -1, out of bounds. 但是i将是-1,超出范围。 Call i-- after test, not before. 呼叫i--不是之前的测试后,。

Please throw away your code, read carefully this good reference and implement binary search right: code is very straightforward if you understand how binary search works. 请扔掉您的代码,仔细阅读此参考资料并正确实施二进制搜索:如果您了解二进制搜索的工作原理,那么代码将非常简单。

EDIT: have a look here for linear search. 编辑:看看这里线性搜索。

It is not a binary search because you are merely iterating over the upper or lower half of the array. 这不是二进制搜索,因为您仅在数组的上半部或下半部进行迭代。 This provides performance of O(n/2), or in other words O(n). 这提供了O(n / 2)或换句话说O(n)的性能。 Binary search continuously halves the area that it is searching, which provides O(log n). 二进制搜索将要搜索的区域连续减半,从而提供O(log n)。

In this block of code: 在此代码块中:

        } else if (keyElement > test[i]) {
            i++;
            if (keyElement == test[i]) {

The second if statement in this block does nothing, you know that keyElement is > test[i] , so it can not also be equal! 该块中的第二个if语句什么也不做,您知道keyElement> test[i] ,所以它也不能相等!

Let me try and clear up what a binary tree is and hopefully it can make writing your code a little easier. 让我尝试清除二叉树是什么,希望它可以使编写代码变得更容易。

Binary search can be thought of as a bunch of variables scattered in a tree. 二进制搜索可以看作是分散在一棵树中的一堆变量。 If for example the root or the top of the tree has the number 8, then everything that falls to the left side is less or equal to 8 and everything that branches to the right of that node is greater. 例如,如果树的根或顶部的数字为8,则落在左侧的所有内容都小于或等于8,而分支到该节点右侧的所有内容都更大。

Regardless of whether or not you are using the correct algorithm, the reason that your code is throwing the ArrayOutOfBoundsException is that you continue to increment or decrement i in the case where incrementing or decrementing i sets the flag to false. 无论您是否使用正确的算法,代码都引发ArrayOutOfBoundsException的原因是在i递增或递减将标志设置为false的情况下,您继续递增或递减i。 In the case where entering a loop iteration finds a match, you break out of the loop; 在进入循环迭代找到匹配项的情况下,您就跳出了循环。 in the other two cases, you increment/decrement the loop and then check again, but you don't break if the flag is changed. 在其他两种情况下,您可以递增/递减循环,然后再次检查,但是如果标志更改了,则不会中断。 This would be a case where it would be better to use a while or do/while loop. 在这种情况下,最好使用while或do / while循环。 If you remove the second check after the increment or decrement, you will achieve what it appears you mean to do. 如果在增加或减少之后删除第二张支票,您将实现您打算做的事情。

As far as the algorithm goes, you aren't incrementing an array index, you're cutting your search range in half each time through the array. 就算法而言,您并没有增加数组索引,而是每次将搜索范围减少一半。

The useful thing to take away from this is that the exception and stack trace tell you what's wrong (the array index is -1) and where it happened, method and line (at ArraysPract.BinarySearch.findElement(BinarySearch.java:82) 摆脱此问题的有用之处在于,异常和堆栈跟踪会告诉您问题出在哪里(数组索引为-1)以及发生的位置,方法和行(在ArraysPract.BinarySearch.findElement(BinarySearch.java:82))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM