Java数组索引超出界限异常

时间:2012-03-29 23:02:51

标签: java arrays

我浏览了整个代码。我能够输入一个简单的.txt文件来搜索一个单词。在它要求一个单词后,它返回

线程“main”中的异常java.lang.ArrayIndexOutOfBoundsException:-48     在SearchEngine.main(SearchEngine.java:150)

第150行是(int j = 0; j

任何帮助调试?

这是一个基本的搜索引擎程序,应该能够在.txt文件中搜索任何单词。

作业链接:http://cis-linux1.temple.edu/~yates/cis1068/sp12/homeworks/concordance/concordance.html


import java.util.*;
import java.io.*;


public class SearchEngine {


    public static int getNumberOfWords (File f) throws FileNotFoundException {
        int numWords = 0;
        Scanner scan = new Scanner(f);
        while (scan.hasNext()) {
        numWords++;
        scan.next();
        }
        scan.close();

        return numWords;
    }

    public static void readInWords (File input, String [] x) throws FileNotFoundException {
        Scanner scan = new Scanner(input);
        int i = 0;
        while (scan.hasNext() && i<x.length) {
            x[i] = scan.next();
            i++;
            }
        scan.close();
    }

    public static int getNumOfDistinctWords (File input, String [] x) throws FileNotFoundException {
        Scanner scan = new Scanner(input);
        int count = 0;
        int i = 1;
        while (scan.hasNext() && i<x.length) {
        if (!x[i].equals(x[i-1])) {
        count++;
        }
        i++;
        }
        scan.close();
        return count;
    }

    public static void readInDistinctWords (String [] x, String [] y) {
        int i = 1;
        int k = 0;
        while (i<x.length) {
            if (!x[i].equals(x[i-1])) {
            y[k] = x[i];
            k++;
            }
        i++;
        }
    }

    public static int getNumberOfLines (File input) throws FileNotFoundException {
        int numLines = 0;
        Scanner scan = new Scanner(input);
        while (scan.hasNextLine()) {
            numLines++;
            scan.nextLine();
            }
        scan.close();
        return numLines;
    }

    public static void readInLines (File input, String [] x) throws FileNotFoundException {
        Scanner scan = new Scanner(input);
        int i = 0;
        while (scan.hasNextLine() && i<x.length) {
            x[i] = scan.nextLine();
            i++;
            }
        scan.close();
    }



public static void main(String [] args) {

     try {

        //gets file name
    System.out.println("Enter the name of the text file you wish to search");
        Scanner kb = new Scanner(System.in);
        String fileName = kb.nextLine();
        String TXT = ".txt";
        if (!fileName.endsWith(TXT)) {
            fileName = fileName.concat(TXT);
        }

        File input = new File(fileName);

    //First part of creating index
    System.out.println("Creating vocabArray");
    int NUM_WORDS = getNumberOfWords(input);
    //System.out.println(NUM_WORDS);
    String [] wordArray = new String[NUM_WORDS];
    readInWords(input, wordArray);
    Arrays.sort(wordArray);
    int NUM_DISTINCT_WORDS = getNumOfDistinctWords(input, wordArray);
    String [] vocabArray = new String[NUM_DISTINCT_WORDS];
    readInDistinctWords(wordArray, vocabArray);
    System.out.println("Finished creating vocabArray");



    System.out.println("Creating concordanceArray");
    int NUM_LINES = getNumberOfLines(input);
    String [] concordanceArray = new String[NUM_LINES];
    readInLines(input, concordanceArray);
    System.out.println("Finished creating concordanceArray");



    System.out.println("Creating invertedIndex");
    int [][] invertedIndex = new int[NUM_DISTINCT_WORDS][10];
    int [] wordCountArray = new int[NUM_DISTINCT_WORDS];
    int lineNum = 0;
        while (lineNum<concordanceArray.length) {
            Scanner scan = new Scanner(concordanceArray[lineNum]);
            while (scan.hasNext()) {
                int wordPos = Arrays.binarySearch(vocabArray, scan.next());
                wordCountArray[wordPos]+=1;
                for(int i = 0; i < invertedIndex.length; i++) {
                for(int j = 0; j < invertedIndex[i].length; j++) {
                if (invertedIndex[i][j] == 0) {
                invertedIndex[i][j] = lineNum;
                break;
                } } }
                }
            lineNum++;
            }
    System.out.println("Finished creating invertedIndex");

    }
System.out.println("Enter a word to be searched (type quit to exit program)");
    Scanner keyboard = new Scanner(System.in);
    String searchWord = keyboard.next();
    while (!searchWord.equals("quit")) {
        int counter = 0;

                    int wordPos = Arrays.binarySearch(allWordsArray, searchWord);
            for (int j = 0; j<invertedIndex[wordPos].length; j++) {
                if(invertedIndex[wordPos][j] != 0) {
                       int number = invertedIndex[wordPos][j];
                       String printOut = concordanceArray[number];
                                               System.out.print(number);
                                               System.out.print(" :");
                                               System.out.println(printOut);
                                    }
            }

            }        



        catch (FileNotFoundException exception) {
        System.out.println("File Not Found");
    }




    } //main
} //class

2 个答案:

答案 0 :(得分:1)

从我所看到的getNumOfDistinctWords(String[] x)是错误的。这将返回比应有的值少的值。以下是代码的修改版本:

import java.util.*;
import java.io.*;


public class SearchEngine {


    //Counts the number of words in the file
    public static int getNumberOfWords (File f) throws FileNotFoundException {
        int numWords = 0;
        Scanner scan = new Scanner(f);
        while (scan.hasNext()) {
            numWords++;
            scan.next();
        }
        scan.close();

        return numWords;
    }


    public static void readInWords (File input, String[] x) throws FileNotFoundException {
        Scanner scan = new Scanner(input);
        int i = 0;
        while (scan.hasNext() && i < x.length) {
            x[i] = scan.next();
            i++;
        }
        scan.close();
    }

    public static String[] getNumOfDistinctWords (String[] x) throws FileNotFoundException {

        HashSet<String> distinctWords = new HashSet<String>();
        for(int i=0; i<x.length; i++){
            distinctWords.add(x[i]);
        }

        String[] distinctWordsArray = new String[distinctWords.size()];
        int i = 0;
        for(String word : distinctWords){
            distinctWordsArray[i] = word;
            i++;
        }


        return distinctWordsArray;
    }

    public static int getNumberOfLines (File input) throws FileNotFoundException {
        int numLines = 0;
        Scanner scan = new Scanner(input);
        while (scan.hasNextLine()) {
            numLines++;
            scan.nextLine();
        }
        scan.close();
        return numLines;
    }

    public static void readInLines (File input, String [] x) throws FileNotFoundException {
        Scanner scan = new Scanner(input);
        int i = 0;
        while (scan.hasNextLine() && i<x.length) {
            x[i] = scan.nextLine();
            i++;
        }
        scan.close();
    }



    public static void main(String [] args) {

        try {

            //gets file name
            System.out.println("Enter the name of the text file you wish to search");
            Scanner kb = new Scanner(System.in);
            String fileName = kb.nextLine();
            String TXT = ".txt";
            if (!fileName.endsWith(TXT)) {
                fileName = fileName.concat(TXT);
            }

            File input = new File(fileName);

            //First part of creating index

            System.out.println("Creating vocabArray");
            int NUM_WORDS = getNumberOfWords(input);

            //Output the number of words in the file
            System.out.println("Number of words is: " + NUM_WORDS);


            String[] allWordsArray = new String[NUM_WORDS];
            readInWords(input, allWordsArray);
            Arrays.sort(allWordsArray);
            String[] distinctWordsArray = getNumOfDistinctWords(allWordsArray);

            //Output the number of distinct words
            System.out.println("Number of distinct words is: " + distinctWordsArray.length);
            System.out.println("Finished creating distinctWordsArray");

            System.out.println("Creating concordanceArray");
            int NUM_LINES = getNumberOfLines(input);
            String[] concordanceArray = new String[NUM_LINES];
            readInLines(input, concordanceArray);
            System.out.println("Finished creating concordanceArray");

            System.out.println("Creating invertedIndex");
            int [][] invertedIndex = new int[distinctWordsArray.length][10];
            int [] wordCountArray = new int[distinctWordsArray.length];


            int lineNum = 0;
            while (lineNum < concordanceArray.length) {
                Scanner scan = new Scanner(concordanceArray[lineNum]);

                while (scan.hasNext()) {
                    //Find the position the word appears on the line, if word not found returns a number less than 0
                    int wordPos = Arrays.binarySearch(distinctWordsArray, scan.next());

                    if(wordPos > -1){
                        wordCountArray[wordPos] += 1;
                    }


                    for(int i = 0; i < invertedIndex.length; i++) {
                        for(int j = 0; j < invertedIndex[i].length; j++) {
                            if (invertedIndex[i][j] == 0) {
                                invertedIndex[i][j] = lineNum;
                                break;
                            } } }
                }
                lineNum++;
            }
            System.out.println("Finished creating invertedIndex");

        }
        catch (FileNotFoundException exception) {
            System.out.println("File Not Found");
        }

    } //main
} //class

我还应该指出,如果在该行上找不到该词,Arrays.binarySearch(distinctWordsArray, scan.next());将返回小于0的数字。这就是为什么你得到Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1,因为{1}在索引-1被引用,当然不存在!

此后的代码看起来也很麻烦,但我会让你解决这个问题!!

答案 1 :(得分:0)

如果不确切知道第126行的位置,找到这个特定的错误就太麻烦了。但我对其余的代码有一些建议:

int NUM_DISTINCT_WORDS = getNumOfDistinctWords(input, wordArray);

通常,all-caps中的变量是在编译时分配的常量。这是一个来自C日的传统,当时很难知道哪些“变量”实际上被预处理器取代了。但事实证明,该约定在其他语言中很有用,大多数程序员都希望在编译时为NUM_DISTINCT_WORDS分配一个特定的值。

此代码根本不可读:

            for(int i = 0; i < invertedIndex.length; i++) {
            for(int j = 0; j < invertedIndex[i].length; j++) {
            if (invertedIndex[i][j] == 0) {
            invertedIndex[i][j] = lineNum;
            break;
            } } }

显示这些嵌套循环的更惯用的方法是:

for (int i = 0; i < invertedIndex.length; i++) {
    for (int j = 0; j < invertedIndex[i].length; j++) {
        if (invertedIndex[i][j] == 0) {
            invertedIndex[i][j] = lineNum;
            break;
        }
    }
}

因为我使用标准的Lindent脚本进行重新缩进,所以我得到了标签。你没有拥有来使用标签,但只需按一下键就可以方便地添加和删除标签,而且它们足够深,即使是小型的面孔也很明显可见。如果你遵循标准的缩进习语,你会发现你的代码更容易使用。

下面这段代码非常不幸:

catch(FileNotFoundException exception) {
    System.out.println("File Not Found");
}

最好捕获更高级别的异常并包含异常消息。如果您在层次结构中捕获更高的异常,则可以更轻松地处理许多错误,并且错误消息将提供更多信息。

您的main()方法执行详细工作的批次。我认为如果将代码分解为更多方法,您的代码将更容易测试,更容易调试,更容易阅读。尝试让main()几乎像对代码的高级描述一样阅读。


现在很容易看到带有bug的行,我可以发现问题:

            int wordPos = Arrays.binarySearch(vocabArray, scan.next());
            wordCountArray[wordPos]+=1;

您已查询wordPos中的vocabArray,但修改了wordCountArray中的内容。你确定他们是the same size and have the same meanings吗?