二进制搜索,数组索引超出界限Java

时间:2014-06-03 23:52:23

标签: java arrays binary-search

首先,我想说我不是要求更多的答案,所以我可以从这个问题中学习。每次运行我的代码时,我都会在ArrayOperations java文件的第254行上获得Array Index Out of Bounds。

if (SearchKey == tempArray[middle])

我已经尽可能多地添加了对此代码的检查,并且尽可能地为您提供了评论。如果可能的话,我正在寻找有关这方面的建议,而不仅仅是直接的答案。错误似乎总是给我我的数据项的1/2的负面版本 例如:100,000个数据项,数组索引超出界限:-49,999。

import javax.swing.*;
// File-related imports

import java.io.IOException;
import java.util.Scanner;
import java.io.File;


public class ArrayOperations
{
// File Parameters
String DataFilePath;
String DataFileName;

String KeysFilePath;
String KeysFileName;

int NumberOfDataItems;
int NumberOfKeys;
int N;
int BucketHashArraySize;
int NoBuckets;
//Array

int[] OriginalArray = new int[1000000];
int[] SortedArray = new int[1000000];
int[] HashedArray = new int[2000000];
int[] BucketHashedArray = new int[2000000];
int[] KeysArray   = new int[1000000];

long SSAverageAccessTime;
long SSAverageCompSuc;
long SSAverageCompFailed;
long SSNumberKeysSuc;
long SSNumberKeysFailed ;

long BSAverageAccessTime;
long BSAverageCompSuc   ;
long BSAverageCompFailed;
long BSNumberKeysSuc    ;
long BSNumberKeysFailed ;

long HSAverageAccessTime;
long HSAverageCompSuc   ;
long HSAverageCompFailed;
long HSNumberKeysSuc    ;
long HSNumberKeysFailed ;

public ArrayOperations()
{   
// File Parameters
DataFilePath = null;
DataFileName = null;

KeysFilePath = null;
KeysFileName = null;

NumberOfDataItems=0;
NumberOfKeys     =0;
N                =0;
BucketHashArraySize = 0;
NoBuckets =0;
// Statistics

SSAverageAccessTime       = 0;
SSAverageCompSuc          = 0;
SSAverageCompFailed       = 0;
SSNumberKeysSuc           = 0;
SSNumberKeysFailed        = 0;

}   


public void ReadDataFile() throws IOException
{
JFileChooser chooser = new JFileChooser();
chooser.setDialogType(JFileChooser.OPEN_DIALOG );
chooser.setDialogTitle("Open Data File");

int returnVal = chooser.showOpenDialog(null);
if( returnVal == JFileChooser.APPROVE_OPTION) 
    {
       DataFilePath = chooser.getSelectedFile().getPath();
       DataFileName = chooser.getSelectedFile().getName();
    }

    // read data file and copy it to original array
if (DataFilePath != null)
{
    try
    {

      int index = 0;
      Scanner integerTextFile = new Scanner(new File(DataFilePath));     
      while (integerTextFile.hasNext())
      {
            // read the next integer
        OriginalArray[index] = integerTextFile.nextInt();
        index++;
      }
        //  end of file detected
      integerTextFile.close();
      NumberOfDataItems = index;
    }
        catch (IOException ioe)
    {
        System.exit(0); 
    }     

}
else
    NumberOfDataItems = 0;
}
public void ReadKeysFile() throws IOException
{
JFileChooser chooser = new JFileChooser();
chooser.setDialogType(JFileChooser.OPEN_DIALOG );
chooser.setDialogTitle("Open Keys File");

int returnVal = chooser.showOpenDialog(null);
if( returnVal == JFileChooser.APPROVE_OPTION) 
    {
        KeysFilePath = chooser.getSelectedFile().getPath();
        KeysFileName = chooser.getSelectedFile().getName();
    }
    // read data file and copy it to original array
if (KeysFilePath != null)
{
    try
    {
      int index = 0;
      Scanner integerTextFile = new Scanner(new File(KeysFilePath));     
      while (integerTextFile.hasNext())
      {
            // read the next integer
        KeysArray[index]= integerTextFile.nextInt();
        index++;
      }
        //  end of file detected
      integerTextFile.close();
      NumberOfKeys = index;
    }
        catch (IOException ioe)
    {
        System.exit(0); 
    }     

}
else
    NumberOfKeys = 0;
}
public void SequentialSearch() 
{
SSAverageAccessTime     = 0;
SSAverageCompSuc        = 0;
SSAverageCompFailed     = 0;
SSNumberKeysSuc         = 0;
SSNumberKeysFailed      = 0;
int SearchKey;
int TotalNumberOfComparisons;
long startTime = System.nanoTime();
boolean found = false;

for (int k=0; k<NumberOfKeys; k++)
{
    found = false;
    SearchKey = KeysArray[k];
    TotalNumberOfComparisons = 0;
    for (int d=0; d<NumberOfDataItems; d++)
    {
        TotalNumberOfComparisons++;
        if (SearchKey == OriginalArray[d])
        {
            found = true;
        }
        if (found)break;
    }
    if(found)
    {
        SSAverageCompSuc = SSAverageCompSuc + TotalNumberOfComparisons;
        SSNumberKeysSuc ++;
    }
    else
    {
        SSAverageCompFailed = SSAverageCompFailed + TotalNumberOfComparisons;
        SSNumberKeysFailed ++;
    }
}
long estimatedTime = System.nanoTime() - startTime;

if (NumberOfKeys != 0)
    SSAverageAccessTime = Math.round((estimatedTime/NumberOfKeys));
else
    SSAverageAccessTime = 0;
if(SSNumberKeysSuc != 0)
    SSAverageCompSuc        = Math.round (SSAverageCompSuc / SSNumberKeysSuc) ;
else
    SSAverageCompSuc        = 0;
if (SSNumberKeysFailed != 0)
    SSAverageCompFailed     = Math.round (SSAverageCompFailed / SSNumberKeysFailed) ;
else
    SSNumberKeysFailed = 0;
return;
}
public void BinarySearch() 
{
// makes a temporary array the length of the number of data items we gave it int[] tempArray = new int[NumberOfDataItems];
// copies a portion of the original array (origionalArray = new int[1000000] above) that has the data inputs
// we are copying only the portion of the original array the was given the data inputs when we opened the data item .txt
for (int i = 0; i < NumberOfDataItems; i ++)
{
    tempArray[i]=OriginalArray[i];
}
// takes the temporary array and sorts it
java.util.Arrays.sort(tempArray);

BSAverageAccessTime     = 0;
BSAverageCompSuc        = 0;
BSAverageCompFailed     = 0;
BSNumberKeysSuc         = 0;
BSNumberKeysFailed      = 0;

int SearchKey;
int TotalNumberOfComparisons;
long startTime = System.nanoTime();
boolean found = false;
int low = 0;
int high = tempArray.length-1;
// sets the midpoint
int middle = (low-high)/2;

for(int k = 0; k<NumberOfKeys; k++)
{
    SearchKey = KeysArray[k];
    TotalNumberOfComparisons = 0;

    for (int d=0; d< Math.log(tempArray.length -1); d++)
    {
        TotalNumberOfComparisons++;
        // makes sure low doesn't go out of bounds
        if (low < 0)
        {
            low = 0;
        }
        // make sure high doesn't go out of bounds
        if(high >= tempArray.length)
        {
            high = tempArray.length-1;
        }
        // checks the midpoint against the key we are using
        if (SearchKey == tempArray[middle])
        {
            found = true;
        }
        // makes sure that if the midpoint doesn't equal the key we get false
        else
        if (low == high && SearchKey != tempArray[middle])
        {
            found = false;
        }
        // if the key is greater than the middle we check the upper portion
        else
        if (SearchKey > tempArray[middle])
        {
            low = (middle +1);
        }
        // if the key is less than the middle we check the lower portion
        else
        if (SearchKey < tempArray[middle])
            high = (middle -1);
        if (found)break;
    }
    if(found)
    {
        BSAverageCompSuc = BSAverageCompSuc + TotalNumberOfComparisons;
        BSNumberKeysSuc ++;
    }
    else
    {
        BSAverageCompFailed = BSAverageCompFailed + TotalNumberOfComparisons;
        BSNumberKeysFailed ++;
    }
}
long estimatedTime = System.nanoTime() - startTime;

if (NumberOfKeys != 0)
    BSAverageAccessTime = Math.round((estimatedTime/NumberOfKeys));
else
    BSAverageAccessTime = 0;
if(BSNumberKeysSuc != 0)
    BSAverageCompSuc        = Math.round (BSAverageCompSuc / BSNumberKeysSuc) ;
else
    BSAverageCompSuc        = 0;
if (BSNumberKeysFailed != 0)
    BSAverageCompFailed     = Math.round (BSAverageCompFailed / BSNumberKeysFailed) ;
else
    BSNumberKeysFailed = 0;
return;
}

public void HashedSearch() 
{
HSAverageAccessTime     = 0;
HSAverageCompSuc        = 0;
HSAverageCompFailed     = 0;
HSNumberKeysSuc         = 0;
HSNumberKeysFailed      = 0;
int SearchKey;
int TotalNumberOfComparisons;
long startTime = System.nanoTime();
boolean found = false;
}
public int FindPrime()
{
return 0;
}
public void Initialize()
{



}
public void BHSearch()
{


}

}   

这是Java GUI代码:

// GUI-related imports

import java.awt.*;
import java.awt.event.*;


// File-related imports

import java.io.IOException;


public class Project04 extends Frame implements ActionListener
{

ArrayOperations arr = new ArrayOperations();

String command = "";

public static void main(String[] args)
{
    Frame frame = new Project04();


    frame.setResizable(false);
    frame.setSize(900,620);
    frame.setVisible(true);

}

public Project04()
{
    setTitle("Search Routines");

    // Create Menu Bar and menu items
    MenuBar mb = new MenuBar();
    setMenuBar(mb);

    // Create Menu Group Labeled "File"

    Menu FileMenu = new Menu("File");

    // Add it to Menu Bar

    mb.add(FileMenu);

    // Create Menu Items
    // Add action Listener 
    // Add to "File" Menu Group

    MenuItem miOpen = new MenuItem("Open");
    miOpen.addActionListener(this);
    FileMenu.add(miOpen);

    MenuItem miExit = new MenuItem("Exit");
    miExit.addActionListener(this);
    FileMenu.add(miExit);

    // Create Menu Group Labeled "File"

    Menu SearchMenu = new Menu("Search");

    // Add it to Menu Bar

    mb.add(SearchMenu);

    // Create Menu Items
    // Add action Listener 
    // Add to "Search" Menu Group

    MenuItem miSequentialSearch = new MenuItem("Sequential Search");
    miSequentialSearch.addActionListener(this);
    SearchMenu.add(miSequentialSearch);

    MenuItem miBinarySearch = new MenuItem("Binary Search");
    miBinarySearch.addActionListener(this);
    SearchMenu.add(miBinarySearch);

    MenuItem miHashedSearch = new MenuItem("Hashed Search");
    miHashedSearch.addActionListener(this);
    SearchMenu.add(miHashedSearch);



    WindowListener l = new WindowAdapter()
    {

        public void windowClosing(WindowEvent ev)
        {
            System.exit(0);
        }

        public void windowActivated(WindowEvent ev)
        {
            repaint();
        }

        public void windowStateChanged(WindowEvent ev)
        {
            repaint();
        }

    };

    ComponentListener k = new ComponentAdapter()
    {
        public void componentResized(ComponentEvent e) 
        {
            repaint();           
        }
    };

    // register listeners

    this.addWindowListener(l);
    this.addComponentListener(k);

}

//******************************************************************************
//  called by windows manager whenever the application window performs an action
//  (select a menu item, close, resize, ....
//******************************************************************************

public void actionPerformed (ActionEvent ev)
    {
        // figure out which command was issued

        command = ev.getActionCommand();

        // take action accordingly

        if("Open".equals(command))
        {
            try
            {
            arr.ReadDataFile();
            arr.ReadKeysFile();
            }
            catch (IOException ioe)
            {
                System.exit(0); 
            }   
            repaint();      
        }

        else
        if("Exit".equals(command))
        {
            System.exit(0);
        }
        else
        if("Sequential Search".equals(command))
        {
            arr.SequentialSearch();
            repaint();
        }
        if("Binary Search".equals(command))
        {
            arr.BinarySearch();     
            repaint();
        }
        if("Hashed Search".equals(command))
        {
            arr.HashedSearch();         
            repaint();
        }
        if("Bucket Hashed Search".equals(command))
        {
            arr.BHSearch();         
            repaint();
        }
    }
//********************************************************
// called by repaint() to redraw the screen
//********************************************************

    public void paint(Graphics g)
    {

        if("Open".equals(command))
        {
            // Acknowledge that file was opened
            if (arr.DataFileName != null)
            {
                g.drawString("File --  "+arr.DataFileName+"  -- was successfully opened", 300, 200);
                g.drawString("Number of Data Items = "+Integer.toString(arr.NumberOfDataItems), 330, 250);
            }
            else
            {
                g.drawString("NO Data File is Open", 300, 200);
            }
            if (arr.KeysFileName != null)
            {
                g.drawString("File --  "+arr.KeysFileName+"  -- was successfully opened", 300, 300);
                g.drawString("Number of Keys = "+Integer.toString(arr.NumberOfKeys), 330, 350);
            }
            else
            {
                g.drawString("NO Keys File is Open", 300, 300);
            }
            return; 
        }

        if("Sequential Search".equals(command) || "Binary Search".equals(command)|| 
                "Hashed Search".equals(command) || "Bucket Hashed Search".equals(command) )
        {
            g.drawRect(100, 100, 700, 420);
            g.drawString("Experiment", 135, 200);
            g.drawLine(250,100,250,520);
            g.drawString("Data File Attributes -- "+Integer.toString(arr.NumberOfDataItems)+" Data Items", 450, 130);
            g.drawString("Key File Attributes -- "+Integer.toString(arr.NumberOfKeys)+" Keys", 450, 155);
            g.drawLine(250,175,800,175);
            g.drawString("Measured Criteria", 475,190 );
            g.drawLine(250,215,800,215);
            g.drawString("Successful Search", 410, 230);
            g.drawString("Unccessful Search", 640, 230);
            g.drawLine(360,245,800,245);


            g.drawLine(100,310,800,310);
            g.drawString("Sequential Search", 110, 325);
            g.drawLine(100,340,800,340);

            g.drawString("Average", 285, 260);
            g.drawString("Access", 285, 275);
            g.drawString("Time", 290, 290);

            g.drawLine(360,215,360,520);
            g.drawString("#", 400, 260);
            g.drawString("Keys", 400, 275);
            g.drawString("Found", 390, 290);

            g.drawLine(470,245,470,520);
            g.drawString("Average", 500, 260);
            g.drawString("No. Of", 500, 275);
            g.drawString("Comparisons", 485, 290);

            g.drawLine(580,215,580,520);
            g.drawString("# ", 620, 260);
            g.drawString("Keys", 620, 275);
            g.drawString("Not Found", 600, 290);

            g.drawLine(690,245,690,520);
            g.drawString("Average", 720, 260);
            g.drawString("No. Of", 720, 275);
            g.drawString("Comparisons", 700, 290);

            g.drawString(Long.toString(arr.SSAverageAccessTime), 255, 325);
            g.drawString(Long.toString(arr.SSNumberKeysSuc), 365, 325);
            g.drawString(Long.toString(arr.SSAverageCompSuc), 475, 325);
            g.drawString(Long.toString(arr.SSNumberKeysFailed), 585, 325);
            g.drawString(Long.toString(arr.SSAverageCompFailed), 695, 325);

            g.drawString("Binary Search", 110, 355);
            g.drawLine(100,370,800,370);

            g.drawString(Long.toString(arr.BSAverageAccessTime), 255, 355);
            g.drawString(Long.toString(arr.BSNumberKeysSuc), 365, 355);
            g.drawString(Long.toString(arr.BSAverageCompSuc), 475, 355);
            g.drawString(Long.toString(arr.BSNumberKeysFailed), 585, 355);
            g.drawString(Long.toString(arr.BSAverageCompFailed), 695, 355);

            g.drawString("Hashed Search", 110, 385);
            g.drawLine(100,400,800,400);

            g.drawString(Long.toString(arr.HSAverageAccessTime), 255, 385);
            g.drawString(Long.toString(arr.HSNumberKeysSuc), 365, 385);
            g.drawString(Long.toString(arr.HSAverageCompSuc), 475, 385);
            g.drawString(Long.toString(arr.HSNumberKeysFailed), 585, 385);
            g.drawString(Long.toString(arr.HSAverageCompFailed), 695, 385);

            // add code to display results for other searches   
        }

    }


}   

1 个答案:

答案 0 :(得分:4)

你的计算错误

更改如下:

int middle = (low-high)/2;

为:

int middle = (high-low)/2;

low总是小于高,所以你得到一个负数,而你的数组中不存在负指数。

虽然我没有检查任何其他可能的问题或算法的有效性,但以上是您遇到的问题的解决方案