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

时间:2013-11-23 19:01:20

标签: 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

1 个答案:

答案 0 :(得分:2)

看看这一节:

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. 您可能只想在表达式为true时增加sentenceCount,对吧?这不是代码所说的。这个“if”语句没有正文(因为与“if”语句在同一行上的分号)。一个好的做法,特别是初学者,是总是使用花括号来包围if块的主体,即使它们只是一行。

  3. 对于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;
    

    尝试使用和不使用强制转换来加倍以查看差异。