【问题标题】:Search int Array with Binary Search Java使用二分搜索 Java 搜索 int 数组
【发布时间】:2017-04-16 13:52:27
【问题描述】:

我有一个 int 数组,我需要对其执行二进制搜索。如果在数组中找到用户输入的数字,则应该返回它所在的索引。该索引对应于另一个数组中的索引,然后将其输出。问题是,对于第一次搜索,提供结果的唯一输入数字是 1。如果我进行多次搜索,我的程序将失败并且不显示任何结果。我不明白为什么我的搜索不起作用,有人可以提供一些关于我做错了什么的输入吗?

public class childrensclassics extends javax.swing.JFrame {
 int[] refInts;

...

private void searchButtonActionPerformed(java.awt.event.ActionEvent evt) {                                             
    //declare variables
    int refNumBinary = Integer.parseInt(refInput.getText());
    String refNum = refInput.getText();
    int binary;

    //binary search
    binary = binarySearch(refInts, 0, refInts.length-1, refNumBinary);

    //check binary search results
    if (binary == -1){
        errorLabel.setText("Data not found. Please Try again.");
    }
    else {
        binaryOutput.setText("#" + refNum + ": " + titlesArray[binary]);
    }

public static Integer binarySearch(int [] A, int left, int right, int V){
     if (left > right) {
         return -1;
     }
     int middle = left + (right - left) / 2;
     if (V == A[middle]) {
         return middle;
     }
     if (V < A[middle]) {
         return binarySearch(A, left, middle-1, V);
     } else {
         return binarySearch(A, middle + 1, right, V);
     }
 }

编辑

refInts 数组中包含的数据示例:

1, 2、 4、 6、 10, 12, 14, 20, 24, 26、

titlesArray 中包含的数据示例:

汤姆索亚历险记, 哈克贝利·芬恩, 石中剑, 斯图尔特小, 宝藏岛, 秘密花园, 爱丽丝梦游仙境, 海底两万里, 彼得潘, 夏洛特的网,

如果有帮助,这是我的添加过程,数据来自一个包含混合参考编号和标题的文本文件,所有这些都在自己的行上。在我的初始代码中,我从文本文件中获取数据并将其全部放入一个名为 bookList 的数组中。出于二进制搜索的目的,我很确定我需要将两种不同的数据类型分开。这是一种迂回的方式,但我对 java 比较陌生,想不出不同的方式。

原始数组中的数据格式

1
The Adventures of Tom Sawyer
2
Huckleberry Finn
3
The Sword in the Stone
...

添加过程:

取包含参考号的偶数索引号和包含标题的奇数索引号并将它们分开。

//separate data for binary search
for (int i = 0; i < bookList.length; i++) {
     if (i%2==0) {
         refNums.add(bookList[i]);
     } else{
         titles.add(bookList[i]);
     }
} 

//create searchable arrays
titlesArray = new String[(bookList.length)/2];
titles.toArray(titlesArray);

refsArray = new String[(bookList.length)/2];
refNums.toArray(refsArray);

//create int array
int[] refInts = new int[refsArray.length];

//send reference number to int array
for (int i = 0; i < refsArray.length; i++) {
    refInts[i] = Integer.parseInt(refsArray[i]);
}

【问题讨论】:

  • 可能包含一些您正在使用的示例数据。
  • 使用现有的实现(java.util.Arrays.binarySearch)怎么样?
  • 提示:将跟踪打印添加到您的代码中;或学习使用调试器。
  • 您使用的是排序数据对吗?
  • @denis int 数组中的数据已经按顺序排列,从最小到最大,它来自文本文件。

标签: java arrays search binary-search


【解决方案1】:

我看到你在源代码中省略了两件事

  1. 二分查找仅适用于已排序的数组
  2. 这里:

 middle = (left + right)/2;

是一个非常危险的溢出操作,你必须验证

【讨论】:

    【解决方案2】:

    这是您正在寻找的样本吗?

    public class TestIndex {
    
        TestIndex()  {
            //Sample arrays after file load
            int[] refInts = {
                    1, 2, 3, 4, 5, 6, 7, 8, 9, 10
            };
            String[] titlesArray = {
                    "The Adventures of Tom Sawyer", 
                    "Huckleberry Finn", 
                    "The Sword in the Stone", 
                    "Stuart Little", 
                    "Treasure Island",
                    "The Secret Garden", 
                    "Alice's Adventures in Wonderland", 
                    "Twenty Thousand Leagues Under the Sea", 
                    "Peter Pan", 
                    "Charlotte's Web"
            };
    
            // Sample input captured to perform search on
            int refNumBinary = 3;
    
            //binary search
            int binary = binarySearch(refInts, 0, refInts.length-1, refNumBinary);
    
            //check binary search results
            if (binary == -1){
                System.out.println("Data not found. Please Try again.");
            }
            else {
                System.out.println("#" + refNumBinary + ": " + titlesArray[binary+1]);
            }
        }
    
        public static Integer binarySearch(int [] A, int left, int right, int V){
             int middle;
             if (left > right || right < 0) {
                 return -1;
             }
             middle = (left + right)/2;
             if (V == A[middle]) {
                 return middle;
             }
             if (V < A[middle]) {
                 return binarySearch(A, left, middle-1, V);
             } else {
                 return binarySearch(A, middle + 1, right, V);
             }
         }
    
        public static void main(String[] args) {
            new TestIndex();
        }
    }
    

    【讨论】:

    • @flip 不完全是我不认为,我的数据来自文本文件,因此不能这样声明,请参阅原始帖子中的编辑以获取更多信息
    • 我的意思是演示搜索原理。无论您是否从文件加载数据这一事实都无关紧要,因为最终您使用的是数据和索引数组。我调整了上面的示例数据以反映这一点。
    • 你能澄清我错过了什么吗?我认为问题是关于无法正常工作的搜索机制。对我来说,这似乎工作正常,因为上面的代码使用与您的代码相同的搜索机制,但在一个孤立的上下文中
    • @flip 我实际上设法修复了它。你说得对,搜索机制运行正常,问题是我犯了一个愚蠢的错误,我的添加过程与搜索按钮混合在一起,因此每次按下搜索按钮时都会尝试添加更多数据,在第一次搜索后导致错误。我将添加过程移至 initComponents();现在工作正常。感谢您的帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-05
    • 1970-01-01
    相关资源
    最近更新 更多