平均字长和平均句子长度的Java代码

好吧,所以,我是一个相对较新的程序员,我在这项任务中遇到了很大的困难。 该任务是创建一个2类java代码,该代码将在文件中读取,特别是一本书,并将分析它以计算平均句子长度和平均字长。 正确的输出应该如下所示:

> java WordMapDriver enter name of a file Analyzed text: /Users/moll/CS121/AliceInWonderland.txt words of length 1: 7.257% words of length 2: 14.921% words of length 3: 24.073% words of length 4: 20.847% words of length 5: 12.769% words of length 6: 7.374% words of length 7: 6.082% words of length 8: 3.012% words of length 9: 1.812% words of length 10: 0.820% words of length 11: 0.501% words of length 12: 0.236% words of length 13: 0.134% words of length 14: 0.083% words of length 15 or larger: 0.001% average sentence length: 16.917 

我一直在研究这段代码但是当我运行它时,我只是得到了很多愤怒的红色错误消息。 以下是长长的投诉清单:

 java.lang.StringIndexOutOfBoundsException: String index out of range: 239 at java.lang.String.charAt(Unknown Source) at WordMap.processLine(WordMap.java:26) at Echo.readLines(Echo.java:16) at WordMapDriver.main(WordMapDriver.java:10) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at edu.rice.cs.drjava.model.compiler.JavacCompiler.runCommand(JavacCompiler.java:272) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at edu.rice.cs.dynamicjava.symbol.JavaClass$JavaMethod.evaluate(JavaClass.java:362) at edu.rice.cs.dynamicjava.interpreter.ExpressionEvaluator.handleMethodCall(ExpressionEvaluator.java:92) at edu.rice.cs.dynamicjava.interpreter.ExpressionEvaluator.visit(ExpressionEvaluator.java:84) at koala.dynamicjava.tree.StaticMethodCall.acceptVisitor(StaticMethodCall.java:121) at edu.rice.cs.dynamicjava.interpreter.ExpressionEvaluator.value(ExpressionEvaluator.java:38) at edu.rice.cs.dynamicjava.interpreter.ExpressionEvaluator.value(ExpressionEvaluator.java:37) at edu.rice.cs.dynamicjava.interpreter.StatementEvaluator.visit(StatementEvaluator.java:106) at edu.rice.cs.dynamicjava.interpreter.StatementEvaluator.visit(StatementEvaluator.java:29) at koala.dynamicjava.tree.ExpressionStatement.acceptVisitor(ExpressionStatement.java:101) at edu.rice.cs.dynamicjava.interpreter.StatementEvaluator.evaluateSequence(StatementEvaluator.java:66) at edu.rice.cs.dynamicjava.interpreter.Interpreter.evaluate(Interpreter.java:77) at edu.rice.cs.dynamicjava.interpreter.Interpreter.interpret(Interpreter.java:47) at edu.rice.cs.drjava.model.repl.newjvm.InterpreterJVM.interpret(InterpreterJVM.java:246) at edu.rice.cs.drjava.model.repl.newjvm.InterpreterJVM.interpret(InterpreterJVM.java:220) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at sun.rmi.server.UnicastServerRef.dispatch(Unknown Source) at sun.rmi.transport.Transport$1.run(Unknown Source) at sun.rmi.transport.Transport$1.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at sun.rmi.transport.Transport.serviceCall(Unknown Source) at sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(Unknown Source) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Source) at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at java.lang.Thread.run(Unknown Source) 

这是我的代码。 我非常感谢任何帮助:

 1 import java.util.Scanner; 2 import java.io.*; 3 4 public class Echo{ 5 String fileName; // external file name 6 Scanner scan; // Scanner object for reading from external file 7 8 public Echo(String f) throws IOException 9 { 10 fileName = f; 11 scan = new Scanner(new FileReader(fileName)); 12} 13 14 public void readLines(){ // reads lines, hands each to processLine 15 while(scan.hasNext()){ 16 processLine(scan.nextLine()); 17 } 18 scan.close(); 19 } 20 21 public void processLine(String line){ // does the real processing work 22 System.out.println(line); 23} 24} ___________________ 1 import java.util.*; 2 import java.io.*; 3 public class WordMap extends Echo { 4 String fileName; //external text file name 5 Scanner scan; //scanner object to read external text 6 int sentencecount = 0; 7 int wordcount = 0; 8 int charcount = 0; 9 //creates an array that will be used to count average word length 10 double[] wlength = new double[15]; 11 int fifteenless = 0; 12 int fifteenplus = 0; 13 public WordMap(String f) throws IOException 14 { 15 super(f);} 16 17 public void processLine(String line) 18 //creates a string array of every word 19 {String [] words = line.split("\\s+"); 20 for(int a = 0; a < words.length; a++){ 21 words[a] = words[a].replaceAll("[\\w]","");} 22 23 //counts words 24 wordcount = words.length; 25 26 //counts sentences by searching for sentence enders 27 for(int c = 0; c < line.length(); c++){ 28 char ca = line.charAt(c); 29 if((line.charAt(ca) == '.')|| (line.charAt(ca) =='!') || (line.charAt(ca) =='?')); 30 sentencecount++ ;} 31 32 //if wordlength matches, adds one to wlength at d and to words less than 15 chars 33 for(int d = 1; d < 15; d++){ 34 for(int g = 0; g < words.length; g++){ 35 String temp = words[g]; 36 if(d == temp.length()){ 37 wlength[d]++; 38 fifteenless++;}}}} 39 40 public void calculatePercentages(){ 41 {//calculate percentages with words of 15 or more characters 42 fifteenplus = wordcount - fifteenless; 43 fifteenplus = fifteenplus / wordcount; 44 fifteenplus = fifteenplus*100;} 45 46 //calculate percentages for words with 1-14 characters 47 for(int h = 1; h<15; h++){ 48 wlength[h] /= wordcount; 49 wlength[h]*=100;} 50 } 51 public void reportLength(){ 52 //prints out average sentence length 53 double length = wordcount / sentencecount; 54 System.out.printf("average sentence length: "+ "%5.3f",length);} 55 56 public void getWordLength(){ 57 //prints out word of length percentages with a loop for 1-14 and a final one for 15+ 58 for(int i = 1; i <15; i++){ 59 System.out.printf("words of length " + i + ": %5.3f%%\n",wlength[i]);} 60 System.out.printf("words of 15 or more characters length: " + "%5.3f%%\n",fifteenplus); 61 }} _______ 1 import java.util.*; 2 public class WordMapDriver { 3 public static void main(String[] args) { 4 try{ 5 String fileName; 6 Scanner textfile = new Scanner(System.in); 7 System.out.println("enter name of file"); 8 fileName = textfile.nextLine(); //scans in file 9 WordMap k = new WordMap(fileName);//creates wordmap object 10 k.readLines(); //processes 11 k.calculatePercentages(); 12 k.getWordLength(); //reports all wordlength percentages 13 k.reportLength(); //prints out average sentence length 14 } 15 catch(Exception e) //catches the ioexception 16 {e.printStackTrace(); 17 }}} 

*编辑:我添加了行号。 此外,这可能是愚蠢的,但我不知道什么SSCCE ** EDIT2:好的,所以我按照建议,现在它打印这个,然后更愤怒的红色消息:

 words of length 1: 50620.000% words of length 2: 15690.000% words of length 3: 2020.000% words of length 4: 300.000% words of length 5: 620.000% words of length 6: 70.000% words of length 7: 20.000% words of length 8: 10.000% words of length 9: 0.000% words of length 10: 10.000% words of length 11: 10.000% words of length 12: 10.000% words of length 13: 10.000% words of length 14: 0.000% words of 15 or more characters length: java.util.IllegalFormatConversionException: f != java.lang.Integer 

看看这一节:

 for(int c = 0; c < line.length(); c++){ char ca = line.charAt(c); if((line.charAt(ca) == '.')|| (line.charAt(ca) =='!') || (line.charAt(ca) =='?')); sentencecount++ ;} 

这里有两个问题:

  1. 变量“ca”是索引c处的字符。 但是你将“ca”传递给line.charAt ... Java正在“帮助”将char转换为int,并尝试返回该索引处的字符。 这不是你想要的,这就是你得到StringIndexOutOfBoundsException的原因。

  2. 你可能只想在表达式为真的情况下增加sentenceCount,对吗? 这不是代码所说的。 这个“if”语句没有正文(因为与“if”语句在同一行上的分号)。 一个好的做法,特别是对于初学者来说, 总是使用花括号来包围if块的主体,即使它们只是一行。

至于IllegalFormatConversionException,它告诉你%5.3f不是整数的有效转换模式(“f”是浮点数和双精度数)。 fifteenplus被声明为int; 是正确的类型? 如果是这样,你可以像这样打印:

 System.out.println("words of 15 or more characters length: " + fifteenplus); 

如果你的意思是像所有其他线一样的百分比,那么你应该把它声明为浮点数或双数(通常你应该更喜欢双浮点数,因为双精度提供更高的精度,性能差异通常是微不足道的)。

最后一点:所有百分比都以.000%结束并不奇怪吗? 在Java中,将int除以int总是会给出一个int。 如果需要浮点结果,则必须将其中一个参数转换为float或double,如下所示:

 int a = 1; int b = 2; double result = (double) a / b; 

尝试使用和不使用演员来加倍看看差异。