Reputation: 85
So I am trying to create a program which takes a text file, creates an index (by line numbers) for all the words in the file and writes the index into the output file. Here is the main class:
import java.util.Scanner;
import java.io.*;
public class IndexMaker
{
public static void main(String[] args) throws IOException
{
Scanner keyboard = new Scanner(System.in);
String fileName;
// Open input file:
if (args.length > 0)
fileName = args[0];
else
{
System.out.print("\nEnter input file name: ");
fileName = keyboard.nextLine().trim();
}
BufferedReader inputFile =
new BufferedReader(new FileReader(fileName), 1024);
// Create output file:
if (args.length > 1)
fileName = args[1];
else
{
System.out.print("\nEnter output file name: ");
fileName = keyboard.nextLine().trim();
}
PrintWriter outputFile =
new PrintWriter(new FileWriter(fileName));
// Create index:
DocumentIndex index = new DocumentIndex();
String line;
int lineNum = 0;
while ((line = inputFile.readLine()) != null)
{
lineNum++;
index.addAllWords(line, lineNum);
}
// Save index:
for (IndexEntry entry : index)
outputFile.println(entry);
// Finish:
inputFile.close();
outputFile.close();
keyboard.close();
System.out.println("Done.");
}
}
The program contains two more classes: IndexEntry
which represents one index entry, and the DocumentIndex
class which represents the entire index for a document: the list of all its index entries. The index entries should always be arranged in alphabetical order. So the implementation for these two classes are shown below
import java.util.ArrayList;
public class IndexEntry {
private String word;
private ArrayList<Integer> numsList;
public IndexEntry(String w) {
word = w.toUpperCase();
numsList = new ArrayList<Integer>();
}
public void add(int num) {
if (!numsList.contains(num)) {
numsList.add(num);
}
}
public String getWord() {
return word;
}
public String toString() {
String result = word + " ";
for (int i=0; i<numsList.size(); i++) {
if (i == 0) {
result += numsList.get(i);
} else {
result += ", " + numsList.get(i);
}
}
return result;
}
}
import java.util.ArrayList;
public class DocumentIndex extends ArrayList<IndexEntry> {
public DocumentIndex() {
super();
}
public DocumentIndex(int c) {
super(c);
}
public void addWord(String word, int num) {
super.get(foundOrInserted(word)).add(num);
}
private int foundOrInserted(String word) {
int result = 0;
for (int i=0; i<super.size(); i++) {
String w = super.get(i).getWord();
if (word.equalsIgnoreCase(w)) {
result = i;
} else if (w.compareTo(word) > 0) {
super.add(i, new IndexEntry(w));
result = i;
}
}
return result;
}
public void addAllWords(String str, int num) {
String[] arr = str.split("[^A-Za-z]+");
for (int i=0; i<arr.length; i++) {
if (arr[i].length() > 0 ) {
addWord(arr[i], num);
}
}
}
}
When I run this program I'm getting an error and I'm not sure where the error came from.
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index 0 out of bounds for length 0
at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:64)
at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:70)
at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:248)
at java.base/java.util.Objects.checkIndex(Objects.java:372)
at java.base/java.util.ArrayList.get(ArrayList.java:459)
at DocumentIndex.addWord(DocumentIndex.java:14)
at DocumentIndex.addAllWords(DocumentIndex.java:35)
at Main.main(Main.java:53)```
Upvotes: 1
Views: 221
Reputation: 32002
There is where the problem arises:
String line;
int lineNum = 0;
while ((line = inputFile.readLine()) != null)
{
lineNum++;
index.addAllWords(line, lineNum);
}
You add lineNum
by 1 before executing the line after. At the last loop, lineNum
will be 1 more than the maximum, because the loop starts at line 1
, and it is 0 index based.
Instead, use:
String line;
int lineNum = 0;
while ((line = inputFile.readLine()) != null)
{
index.addAllWords(line, lineNum);
lineNum++;
}
Upvotes: 1