这是一项家庭作业。我正在尝试制作一个程序,在文本文件中搜索特定的单词,然后打印出单词的频率。
public class WordFreq extends Echo{
ArrayList<WordCount>array1=new ArrayList<WordCount>();
String[] words;
int wordsTotal=0;
public WordFreq(String f, String x) throws IOException
{
super(f);
words=x.toLowerCase().split(" ");
}
public void processLine(String line){
String[] lines=line.toLowerCase().split(" ");
wordsTotal=wordsTotal+lines.length;
for(int j=0; j<lines.length; j++){
WordCount alpha=new WordCount(lines[j]);
alpha.incCount();
array1.add(alpha);}
for(int x=0; x<array1.size(); x++){
for(int y=0; y<array1.size(); y++){
if(array1.get(x).equals(array1.get(y))&&(x!=y)){
for(int i = 0; i< array1.get(y).getCount(); i++){
array1.get(x).incCount();
}
array1.remove(y);
}
}
}
}
public void reportFrequencies(){
for(int i = 0; i<array1.size();i++){
// System.out.println(array1.get(i).getWord()+" "+array1.get(i).getCount());
}
int currentWord=0;
for(int x=0; x<words.length; x++){
for(int y=0; y<array1.size(); y++){
if(words[x].equals(array1.get(y).getWord())){
currentWord=array1.get(y).getCount();}}
System.out.print(words[x]+" ");
System.out.printf("%.4f",(double)currentWord/wordsTotal);
}
}
}
这是我的主要方法:
public class FreqStudy{
public static void main(String[] args) throws IOException
{
Scanner scan = new Scanner(System.in);
System.out.println("enter file name");
String fileName = scan.next();
Scanner scan2 = new Scanner(System.in);
System.out.println("enter words to search for");
System.out.println("enter lower case, separated by spaces");
String wordString = scan2.nextLine();
WordFreq f = new WordFreq(fileName,wordString);
f.readLines();
f.reportFrequencies();
}
}
我正在使用Jane Austen所着的Emma一书的.txt文件。这是我运行程序并尝试搜索单词时收到的错误消息:
java.lang.IndexOutOfBoundsException: Index: 906, Size: 906
at java.util.ArrayList.RangeCheck(ArrayList.java:547)
at java.util.ArrayList.get(ArrayList.java:322)
at WordFreq.processLine(WordFreq.java:26)
at Echo.readLines(Echo.java:16)
at FreqStudy.main(FreqStudy.java:15)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at edu.rice.cs.drjava.model.compiler.JavacCompiler.runCommand(JavacCompiler.java:272)"
以下是Echo和WordCount的代码:
public class WordCount{
private String word;
private int count;
public WordCount(String w){
word = w;
count = 0;
}
public String getWord(){
return word;}
public int getCount(){
return count;}
public void incCount(){count++;}
public String toString() {
return(word + " --- " + count);
}
public boolean equals(Object other){
WordCount i = (WordCount)other;
return (this.word.equals(i.word));
}
}
回声:
import java.util.Scanner;
import java.io.*;
public class Echo{
String fileName; // external file name
Scanner scan; // Scanner object for reading from external file
public Echo(String f) throws IOException
{
fileName = f;
scan = new Scanner(new FileReader(fileName));
}
public void readLines(){ // reads lines, hands each to processLine
while(scan.hasNext()){
processLine(scan.nextLine());
}
scan.close();
}
public void processLine(String line){ // does the real processing work
System.out.println(line);
}
}
我的代码第26行是:
for(int i = 0; i< array1.get(y).getCount(); i++)
答案 0 :(得分:0)
在嵌套的for
循环中,您在操作array1
的同时循环大小array1
。在迭代时不要改变你用来迭代的任何东西。您可以考虑复制array1
进行迭代。
for(int x=0; x<array1.size(); x++){
for(int y=0; y<array1.size(); y++){
if(array1.get(x).equals(array1.get(y))&&(x!=y)){
for(int i = 0; i< array1.get(y).getCount(); i++){
array1.get(x).incCount();
}
array1.remove(y); // NO NO NO
}
}
}
答案 1 :(得分:0)
我认为您的问题是,您在for循环中使用array1.size()
作为边界,而您正在从array1
中移除值。所以你的y计数器正在递增,你的边界总是在减少。在循环中的特定点,此递增/递减将导致Y
将变得大于array1.size
的情况,因此当您尝试执行get(y)
时,您将超出界限。
尝试类似
的内容int size = array1.size(); //outside the for loops
....
for(int y=0; y<size; y++){
答案 2 :(得分:0)
如果您想要更改正在迭代的对象,我建议使用Iterator。
您可以通过以下操作获取ArrayList
上的迭代器:
Iterator<WordCount> iterator = array1.iterator();
这可能会解决您的问题并简化您的代码。请务必使用:
iterator.remove()
代替array1.remove(index)
等