【问题标题】:Java Array Index Out of Bounds Exception [duplicate]Java数组索引越界异常[重复]
【发布时间】:2012-03-29 23:02:51
【问题描述】:

我浏览了整个代码。我可以输入一个简单的 .txt 文件来搜索单词。在它询问一个单词后,它返回

线程“主”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

【问题讨论】:

  • 一般来说,只是更新您现有的问题,不要发布新问题...
  • 我知道豆腐建议您应该开始一个新问题,这通常是个好建议,但您有责任表明您的最后一个问题已解决是一个逻辑上不同的问题。
  • user1302023,我们需要知道第 126 行在哪里,以便我们为您提供帮助。您的错误意味着您从数组中请求了一个不存在的值。这是一个示例: int[] x= new int array[1] int y= x[10] 因为数组中没有 10,所以它会给您错误。找到你在哪里做的,你可以修复它,或者告诉我们哪一行是 126。
  • 我认为第 126 行是:y[k] = x[i];虽然我用我的双手来测量它。
  • 第 126 行是 wordCountArray[wordPos]+=1;那是为了指令:在 wordPos 位置的 wordCountArray 的元素上加 1。

标签: java arrays


【解决方案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,因为wordCountArray 在索引-1 处被引用,这当然不存在!

这之后的代码看起来也有问题,但我会让你修复它!

【讨论】:

  • 好的,我编辑了帖子以包含我的最后一个问题。
【解决方案2】:

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

int NUM_DISTINCT_WORDS = getNumOfDistinctWords(input, wordArray);

通常,全大写的变量是在编译时分配的常量。这是来自 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() 读起来就像是对代码的高级描述。


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

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

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

【讨论】:

  • cis-linux1.temple.edu/~yates/cis1068/sp12/homeworks/concordance/… 这是我正在遵循的说明的链接。当我同时初始化 vocabArray 和 wordCountArray 时,它们都是使用相同的变量创建的,并且应该是相同的大小。
  • 啊,这也解释了变量名。 :) 很公平。我会对binarySearch() 方法进行大量测试;确保它始终返回您期望的结果。也许您的数组没有正确排序?
  • 而就方法而言,我喜欢将每个部分都写在main中,然后将其分解为方法。我只是还没走到那一步。到目前为止,下面的答案似乎已经解决了这个问题。
猜你喜欢
  • 2013-03-05
  • 2015-06-28
  • 1970-01-01
  • 2016-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多