【问题标题】:Error launching my program, how can i fix it?启动我的程序时出错,我该如何解决?
【发布时间】:2019-06-24 03:06:17
【问题描述】:

我的大学https://cs1331.gitlab.io/fall2018/hw2/hw2-source-model.html 有这个任务。我编写了代码,但是当我运行程序时,我在控制台收到了这条消息:

Exception in thread "main" java.lang.StringIndexOutOfBoundsException: begin 0, end -1, length 2
    at java.base/java.lang.String.checkBoundsBeginEnd(String.java:3107)
    at java.base/java.lang.String.substring(String.java:1873)
    at homework1.SourceModel.main(SourceModel.java:127)

这是我的 cmets 作业代码:

 package homework1;

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


public class SourceModel {

    //initialize variables so they can be accessed everywhere
    private String modelName;
    private int[][] characterCount;
    private double[] rowCount;
    private double[][] probability;

    /**
     * 
     * @param name takes the name of the corpus
     * @param fileName takes the filesName of corpus
     */
    public SourceModel(String name, String fileName) {
        modelName = name;
        characterCount = new int[26][26];
        rowCount = new double[26];
        probability = new double[26][26];
        System.out.println("Training " + name + "model...");

        try {
            Scanner scan = new Scanner(new File(fileName));
            String temp = "";

            //append all of the text
            while (scan.hasNext()) {
                temp += scan.next();
            }

            //only keeps the letters and makes them lowercase
            temp = temp.replaceAll("[^A-Za-z]+", "").toLowerCase();
System.out.println(temp);
            //iterates trough each letter then puts the letters
            //sequence to the respective row and column

            for (int i = 0; i < (temp.length() - 1); i++) {
                char firstLetter = temp.charAt(i);
                char secondLetter = temp.charAt(i + 1);

                //index based on ASCII values
                characterCount[(int) firstLetter - 97][(int) secondLetter - 97]++;
                rowCount[(int) firstLetter - 97]++;
            }

            //calculates the probability by dividing the count
            //by the total counts in each row 
            for (int i = 0; i < probability.length; i++) {
                for (int j = 0; j < probability[i].length; j++) {
                    if (rowCount[i] == 0) {
                        rowCount[i] = 0.01;
                    }
                    probability[i][j] = (((double) characterCount[i][j]) / rowCount[i]);

                    if (probability[i][j] == 0) {
                        probability[i][j] = 0.01;
                    }
                }
            }
            System.out.println("done");

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

    /**
     * 
     * @return a string which contains the name
     */
    public String getName() {
        return modelName;
    }

    /**
     * @return a string with the matrix 
     */
    public String toString() {
        String matrix = "";
        matrix += "";
        for (int i = 97; i < 123; i++) {
            matrix += "  ";
            matrix += (char) i;
        }
        matrix += ("\n");
        for (int i = 0; i < probability.length; i++) {
            matrix += ((char) (i + 97) + " ");
            for (int j = 0; j < probability[i].length; j++) {
                matrix += String.format("%.2f", probability[i][j]);
                matrix += ("");
            }
            matrix += "\n";
        }
        return matrix;
    }

    /**
     * 
     * @param test a set of letters to test
     * @return the probability for the word 
     */
    public double probability(String test) {
        test = test.replaceAll("[^A-Za-z]+", "").toLowerCase();
        double stringProbability = 1.0;
        for (int i = 0; i < test.length() - 1; i++) {
            int firstIndex = (int) (test.charAt(i)) - 97;
            int secondIndex = (int) (test.charAt(i + 1)) - 97;
            stringProbability *= probability[firstIndex][secondIndex];
        }
        return stringProbability;
    }

    /**
     * 
     * @param args the command line arguments 
     */
    public static void main(String[] args) {
        SourceModel[] models = new SourceModel[args.length - 1];
        for (int i = 0; i < args.length - 1; i++) {
            models[i] = new SourceModel(args[i].substring(0, args[i].indexOf(".")), args[i]);
        }
        System.out.println("Analyzing: " + args[args.length - 1]);
        double[] normalizedProbability = new double[args.length - 1];
        double sumProbability = 0;
        for (int i = 0; i < args.length - 1; i++) {
            sumProbability += models[i].probability(args[args.length - 1]);
        }
        //normalize the probability in respect to the values given
        for (int i = 0; i < normalizedProbability.length; i++) {
            normalizedProbability[i] = models[i].probability(args[args.length - 1]) / sumProbability;
        }
        int highestIndex = 0;
        for (int i = 0; i < args.length - 1; i++) {
            System.out.print("Probability that test string is");
            System.out.printf("%9s: ", models[i].getName());
            System.out.printf("%.2f", normalizedProbability[i]);
            System.out.println("");
            if (normalizedProbability[i] > normalizedProbability[highestIndex]) {
                highestIndex = i;
            }
        }
        System.out.println("Test string is most likely " + models[highestIndex].getName() + ".");
    }
}

【问题讨论】:

  • 请包含您的代码
  • 那么“HipHop”和“Lisp”现在是语言了吗?大声笑
  • substring(0, args[i].indexOf(".")) 如果args[i] 没有. 怎么办? indexOf(".") 将返回 -1,这是 substring 的无效值,正如您在异常消息中看到的那样。
  • @Pshemo 击败我,我只是在写一个答案来指出这一点。是否应该回答或标记为重复?
  • @EJoshuaS 我正在寻找副本。如果您发现它更快,请联系我,以便我对其进行投票。

标签: java


【解决方案1】:

在你的主要方法中,你有:

args[i].indexOf(".")

点 (.) 未找到,因此返回 -1。

你尝试创建一个子字符串:

models[i] = new SourceModel(args[i].substring(0, args[i].indexOf(".")), args[i]);

但是由于args[i].indexOf(".")无效,所以会抛出异常。

您可以做的是检查点 (.) 是否存在,如果存在则继续:

if(args[i].contains(".")){
models[i] = new SourceModel(args[i].substring(0, args[i].indexOf(".")), args[i]);
}

【讨论】:

  • 你确定吗?您可以将 args[i] 打印到控制台并向我们展示输出吗?
  • @GabrielaI.Haras “但它甚至还有一个点”是什么让你这么认为?请注意,使用for (int i = 0; i &lt; args.length - 1; i++),您正在迭代和测试除最后一个以外的所有参数。所有这些论点都存在点吗?
【解决方案2】:

其他人已经指出了这一点,但是对于这一行:

models[i] = new SourceModel(args[i].substring(0, args[i].indexOf(".")), args[i]);

substring 方法显然会导致问题,因为如果找不到 .indexOf 会返回 -1。

但是,在这种情况下,代码实际上不是问题,因为分配声明您可以假设文件名的格式为&lt;source-name&gt;.corpus。话虽这么说,真的,所有命令行参数都应该有一个.,所以这不应该发生。

我会检查您传递的命令行参数。我的一个猜测是,您可能有一个文件名,其中包含空格或其他内容。例如,如果您传递了 English GB.corpus,那么这将显示为 2 个单独的参数(其中一个没有 .)。

编辑:正如@Pshemo 在 cmets 中指出的那样,如果您的文件名中包含空格,则可以将其放在引号中,以便将其解释为单个命令行参数 - 例如,不要写 English GB.corpus,而是写 "English GB.corpus"。这样可以防止异常。

【讨论】:

  • 如果像 English GB.corpus 这样的文件用引号括起来,同时将其作为命令行参数传递,以确保控制台将其视为单个参数。
  • 我把它放在引号中,但现在它在控制台上写了线程“main”中的异常分析:cdr。” java.lang.NullPointerException at homework1.SourceModel.main(SourceModel.java:138)
  • @GabrielaI.Haras 哪一行是 138?
  • @halfer 是的,我有点困惑。
  • @halfer 删除代码对我来说似乎不合理 - 没有它,问答就没有意义。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-15
  • 1970-01-01
  • 2021-12-13
  • 2021-06-04
  • 2019-06-28
  • 2018-07-12
相关资源
最近更新 更多