Trying to check the words within one file in another - java

I'm setting up a spell checker for a class assignment.
I'm trying to check the words within one file with another.
I'm currently experiencing an error:
spelling.java:29: error: cannot find symbol
if(checkMe.next().equals(dicArr[i])){
^
symbol: variable dicArr
location: class spelling
1 error
Could you please advise me on what I'm doing wrong or what I could potentially improve with my approach? Many thanks.
import java.util.*;
import java.io.*;
public class spelling{
public static void main(String args[]) throws FileNotFoundException {
//read the dictionary file
Scanner dicIN = new Scanner(new File("dictionary.txt"));
Scanner spellCheckFile = new Scanner(new File("checkMe.txt"));
String inputWord;
int i = 0;
//create arraylist to pass dictionary through, then I can define the size of my array
ArrayList<String> dicList = new ArrayList<String>();
while(dicIN.hasNext()){
dicList.add(dicIN.next());
String[] dicArr = dicList.toArray(new String[dicList.size()]);
}
//Scan through checkMe file to see if the words occur in the dictionary
Scanner checkMe = (spellCheckFile);
while(checkMe.hasNext())
{
if(checkMe.next().equals(dicArr[i])){
i++;
} else{
System.out.println("The word " + checkMe + "doesn't exist in the dictionary");
}
}
//System.out.println(dicList);
}
}

your i++ is confusing - you should have 2 loops:
one to iterate checkme, like you do: while(checkMe.hasNext())
the other to iterate through all dicArr. Only if you check every dicArr[i], you can tell The word doesn't exist in the dictionary
Prefer this:
1 use a Set for your dictionnary
2 to check each word, you only need to do set_string.contains(new_word)
For example
Set set_string=new HashSet();
set_string.add(new_string);
if (set_string.contains(another_string)) ...
Set keeps unique elements. searching is straightforward.

You declare dicArr in the body of a while loop. It is not visible outside the body of the while loop.
I am not certain what you are trying to do, but I think you need to close the while loop before the declaration of dicArr:
while(dicIN.hasNext()){
dicList.add(dicIN.next());
} // <-- Add closing brace here.
String[] dicArr = dicList.toArray(new String[dicList.size()]);
// } // <-- Remove closing brace here.

Try to declare this String[] dicArr = null; before all loop like this:
String[] dicArr = null;
ArrayList<String> dicList = new ArrayList<String>();
while(dicIN.hasNext()){
dicList.add(dicIN.next());
dicArr = dicList.toArray(new String[dicList.size()]);
}
//Scan through checkMe file to see if the words occur in the dictionary
Scanner checkMe = (spellCheckFile);
while(checkMe.hasNext())
{
if(checkMe.next().equals(dicArr[i])){
.....}

Related

How to read a file and pass the information to separately saved class objects?

I'm setting a java application that has 3 separately saved classes WordApp, WordProcessor, and WordType. WordApp reads the file and is suppose to pass the data to the other classes. I can read the file but I can't the data to pass to the other classes. How to pass the information via a string?
I've searched this and every example I find has all the classes saved to the same file. I'm using textpad and I tried passing the string to the WordProcessor class which has constructs an ArrayList of WordType objects. This method is not working for me.
This is the first part of the WordApp class for reading the file.
import java.io.*; // Import IO package
import java.util.Scanner; // Import Scanner utility
import java.util.ArrayList; // Import ArrayList utility
public class WordApp // Declared WordApp Class
{
public static void main (String[] args) // Main
{
// Declared Variables
String again;
String initial = "";
String inputFileName;
String outputFileName;
// Declared Objects
Scanner input = new Scanner(System.in);
do
{
try
{
System.out.println(" Welcome to the Word Processor App! ");
System.out.println("**********************************************************************\n");
System.out.println("Enter file names with .txt extension.");
System.out.print("Please Enter File Name to Read: ");
inputFileName = input.nextLine().trim();
File mcFile = new File(inputFileName);
Scanner scan = new Scanner(mcFile);
System.out.println("Enter file names with .txt extension.");
System.out.print("Please Enter File Name to Save: ");
outputFileName = input.nextLine().trim();
File deFile = new File(outputFileName);
PrintWriter out = new PrintWriter(deFile);
System.out.println("Reading file...\n");
while(scan.hasNext())
{
initial = scan.next();
}
scan.close();
System.out.println("Scanning Paragraph.....\n");
WordProcessor x = new WordProcessor();
x.addWord(initial);
I'm trying to pass the words in the file here:
import java.util.ArrayList;
import java.util.Collections;
public class WordProcessor
{
private ArrayList<WordType> words;
private int totSentences;
private int totUnique;
public WordProcessor()
{
words = new ArrayList<WordType>();
totSentences = 0;
totUnique = 0;
}
and here:
public class WordType implements Comparable
{
// instance data
private String word;
private int count;
private int syllables;
// Constructors
public WordType(String newWord)
{
word = newWord;
count = 1;
syllables = countSyllables();
}
I'm expecting that that words pass to the other classes but when I save the file it is blank. Sorry if I didn't post the code correctly
You're reading the file and getting the items it holds but discarding all but the last.
while(scan.hasNext()) {
initial = scan.next();
// You do **nothing** with the String read in
}
scan.close();
System.out.println("Scanning Paragraph.....\n");
WordProcessor x = new WordProcessor();
x.addWord(initial); // until here where you add the last one
Instead create the WordProcessor object before the while loop, and add words within the while loop
WordProcessor x = new WordProcessor();
while(scan.hasNext()) {
initial = scan.next();
x.addWord(initial);
}
scan.close();
There may be other errors, especially problems in your code not shown (addWord(...) comes to mind), but this error was immediately obvious.
Also what type of looping are you doing and why? You appear to have a do-while loop -- why? Again if this does not solve your problem, then you still will need to create and post a valid mcve so we don't have to guess what the problem truly is. Please understand that I am not asking for all your code but rather for something completely different -- please read the link and understand it fully if your problem has not been solved and you still need help.

Do I have to assign the data from sc.nextLine() to a variable before I use it?

So far, every time I have used a scanner object I have assigned the input to a new string variable like:
String word = reader.nextLine();
and then if I want to use the input in an if statement I would write:
if(word.isEmpty()){}
but this seems almost like an extra step instead of just doing:
if(reader.nextLine().isEmpty()){}
however, when I try this I usually get some kind of problem in my program function. Is there a way to do this by skipping the String that I will never use again?
This is the code that I am trying to use without the String objects:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;
public class WordsInReverseOrder {
public static void main(String[] args) {
Scanner reader = new Scanner(System.in);
ArrayList<String> words = new ArrayList<String>();
while(true){
System.out.println("Type a word: ");
if(reader.nextLine().isEmpty()){
Collections.reverse(words);
for(String word1 : words){
System.out.println(word1);
}
break;
}
else{
words.add(reader.nextLine());
}
}
}
}
If you need to do something with the scanned word and want to check isEmpty() than you need a variable to access the word twice.
So, if you do more than one thing, you need a variable. If you do just one thing, you can 'inline' the variable.
The answer to your question is 'Yes'. When you do not need the content of the first word / line, the you can 'inline' your variable, which means that there is no need for a variable.

How do I avoid ConcurrentModificationException in ArrayList ONLY when iterating?

For clarification - I DO NOT want to remove anything from the ArrayList. Therefore 90% of all the answers I have found don't actually apply. I can't find anything here, or elsewhere that helps me out much!
I'm writing a Java Application to play Hangman where the opponent (computer) is essentially cheating, in the sense where it does not 'choose' a word, it has a group of words and decides if the player's guess is correct, or incorrect, depending on which of those leaves the more difficult group of words to guess from.
In a nutshell, my problem is this:
I have an ArrayList, masterList, where I have a set of words, a dictionary if you will, and various methods iterate through this to perform various tasks. My code is single threaded and one of these methods is throwing a ConcurrentModificationException when trying to access the next object in the ArrayList in the second iteration. However, I cannot find anything that actually changes the ArrayList during the iteration.
import java.io.*;
import java.util.*;
public class Main {
private ArrayList<String> masterList;
private ArrayList<String> contains;
private ArrayList<String> doesNotContain;
private HashMap<Integer, ArrayList<String>> wordLengthList;
private HashMap<Integer, ArrayList<String>> difficultyList;
private int guesses = 10;
private Scanner sc;
private FileReader fr;
private BufferedReader br;
private String guessString;
private char guessChar;
private static final String DICTIONARY = "smalldictionary.txt";
private String wordLengthString;
private int wordLengthInt = 0;
public Main(){
masterList = new ArrayList<String>();
contains = new ArrayList<String>();
doesNotContain= new ArrayList<String>();
wordLengthList = new HashMap<Integer, ArrayList<String>>();
difficultyList = new HashMap<Integer, ArrayList<String>>();
sc = new Scanner(System.in);
importTestDictionary(); //does not use masterList
br = new BufferedReader(fr);
importWords(); //Adds to masterList. Both readers closed when finished.
catalogLengths(); //Iterates through masterList - does not change it.
do{
setWordLength(); //does not use masterList
}while(!(validateLengthInput(wordLengthString))); //validation will change the set of masterList if valid.
//Main loop of game:
while(guesses > 0){
do{
getUserInput();
}while(!(validateInput(guessString)));
splitFamilies();//will change set of masterList when larger group is found. Changes occur AFTER where Exception is thrown
printDifficultyList();
}
}
private void importWords(){ //Adds to masterList. Both readers closed when finished.
try{
while(br.readLine() != null){
line = br.readLine();
masterList.add(line);
}
br.close();
fr.close();
}catch(IOException e){
System.err.println("An unexpected IO exception occurred. Check permissions of file!");
}
}
private boolean validateLengthInput(String length){ //validation will change the set of masterList if valid.
try{
wordLengthInt = Integer.parseInt(length);
if(!(wordLengthList.containsKey(wordLengthInt))){
System.out.println("There are no words in the dictionary with this length.\n");
return false;
}
}catch(NumberFormatException e){
System.out.println("You must enter a number.\n");
return false;
}
masterList = wordLengthList.get(wordLengthInt);
return true;
}
private void splitFamilies(){ //will change set of masterList when larger group is found. Changes occur AFTER where Exception is thrown
Iterator<String> it = masterList.iterator();
int tempCount = 0;
while(it.hasNext()){
tempCount++;
System.out.println("tempCount: " + tempCount);
String i = it.next(); //Still throwing ConcurrentModification Exception
if(i.contains(guessString)){
contains.add(i);
}else{
doesNotContain.add(i);
}
}
if(contains.size() > doesNotContain.size()){
masterList = contains;
correctGuess(); //does not use masterList
profileWords();
}
else if(doesNotContain.size() > contains.size()){
masterList = doesNotContain;
incorrectGuess(); //does not use masterList
}
else{
masterList = doesNotContain;
incorrectGuess(); //does not use masterList
}
}
private void printMasterList(){ //iterates through masterList - does not change it.
for(String i : masterList){
System.out.println(i);
}
}
private void catalogLengths(){ //Iterates through masterList - does not change it.
for(String i : masterList){
if(i.length() != 0){
if(!(wordLengthList.containsKey(i.length()))){
wordLengthList.put(i.length(), new ArrayList<String>());
}
wordLengthList.get(i.length()).add(i);
}
}
}
}
The line the exception is thrown from is marked above in the code. Any method using masterList is also marked, any method included that does not use it, there is no comment against.
I did read some answers and some of them suggested using Iterator to avoid the exception. This is implemented above in splitFamilies(). The original code was as below:
private void splitFamilies(){ //will change set of masterList when larger group is found. Changes occur AFTER where Exception is thrown
int tempCount = 0;
for(String i : masterList){ //This line throws ConcurrentModificationException
tempCount++;
System.out.println("tempCount: " + tempCount);
if(i.contains(guessString)){
contains.add(i);
}else{
doesNotContain.add(i);
}
}
....continue as before
tempCount is always 2 when the exception is thrown.
Maybe I'm missing something really simple, but I've tried tracing this, and cannot find out why I'm getting this exception!
I've tried to remove everything irrelevant from the code, but if anyone really wants to view the full thing, I guess I could dump all my code in the question!
The issue comes from the fact that masterList is a reference to either contains or doesNotContain after a first split. When you iterate on masterList, you actually also iterate at the same time on that other list.
So, then you add items to the lists:
if(i.contains(guessString)){
contains.add(i);
}else{
doesNotContain.add(i);
}
Here you do not only add items to contains or doesNotContain, but also potentially to masterList, which leads to the conccurentException.
To solve your issue, just make a copy of your lists, instead of : masterList = contains;
do a copy with: masterList = new ArrayList<>(contains);
And the same for doesNotContains.
Another solution which comes to mind is to reset the two lists contains and doesNotContains for each split. Since you only use them in this method, and nowhere else, remove these two lists from your Class, and defines them as private variables inside splitFamilies

Issue With writing to File

import java.util.*;
import java.io.*;
public class comparing{
static ArrayList <compare> events = new ArrayList<compare>();
public static void main(String[]args){
try{
Scanner in = new Scanner(new File("events.txt"));
File output = new File("chines.txt");
Scanner sc = new Scanner(output);
PrintWriter printer = new PrintWriter(output);
while(in.hasNext()){
int temp = in.nextInt();
String temptwo = in.nextLine();
//String s = ;
events.add(new compare(temp,temptwo));
//System.out.println("Next word is: " + temp);
Collections.sort(events);
for(int i = 0;i<events.size();i++){
printer.write(events.get(i));
System.out.println(events.get(i));
}
}
}
catch(Exception e){
System.out.println("Invalid file name");
}
}
My code above reads from a file it sorts the data then prints it out. What I would like to do is write this sorted data to another file but I keep getting the following error:
comparing.java:27: error: no suitable method found for write(compare)
printer.write(events.get(i));
You're declaring events to be an ArrayList, meaning that it contains java.lang.Object elements, thus printer.write(java.lang.Object) is what's being searched for by the compiler.
You're adding an object of your undisclosed class compare, so even declaring ArrayList<compare> wouldn't help. Hopefully your compare class has a meaningful toString, so that you can use ArrayList<compare> events, combined with printer.write(event.toString());
See the docs.
There is no write(Object) method. You can change it to write(events.get(i).toString()) to convert it to a String first.
Alternatively, use print instead of write for more input options. See write() vs print().
It can take a object as argument and calls the String.valueOf(obj) method for you:
printer.print(events.get(i));
Add this code instead of your loop
for (int i = 0; i < events.size(); i++)
{
printer.write(String.valueOf(events.get(i)));
out.write(" ");
}

How to only get one output from a loop when testing a HashSet

I am building a program which is supposed to tell if a list of words from a text file are all unique or if there is a duplicate using a HashSet. If there is a duplicate, the only output should be "NOT_UNIQUE", and if there are no duplicates, the output should be "UNIQUE".
I believe the way to do this is to add the words from the file to the HashSet, and if a word can't be added it is because that word is a duplicate. I have already started building the program, but the program outputs "UNIQUE" for every word as opposed to just once at the end of the program. I think this has to do with my use of a while-loop and infile.readLine(), but I'm not sure what else to do here. Thank you for your help. My code is below:
import java.io.*;
import java.util.*;
public class Lab5
{
public static void main (String[] args) throws Exception
{
HashSet<String> set = new HashSet<String>();
BufferedReader infile = new BufferedReader( new FileReader( args[0] ) );
while ( infile.ready() )
{
String word = infile.readLine();
if ( !set.add(word) )
System.out.println("NOT_UNIQUE \n");
else
System.out.println("UNIQUE \n");
}
}
}
Flags aren't elegant, but in this case I think it's a pragmatic solution. You can set a flag and bail out of the loop if you don't want it to display for every word:
import java.io.*;
import java.util.*;
public class Lab5
{
public static void main (String[] args) throws Exception
{
boolean isUnique = true;
HashSet<String> set = new HashSet<String>();
BufferedReader infile = new BufferedReader( new FileReader( args[0] ) );
while ( infile.ready() )
{
String word = infile.readLine();
if ( !set.add(word) ) {
isUnique = false;
break;
}
}
System.out.println(isUnique ? "UNIQUE \n" : "NOT_UNIQUE \n");
}
}
Remember to close out your file descriptor if you put this into an application.
You are printing your UNIQUE or NOT_UNIQUE outputs in a loop while your BufferedReader is ready to be read, at each line read, so it'll print a value for each line that's been read.
You probably want to refactor your design here.
The logic below applies only if you want to actually keep the whole of the data read from file, otherwise there will be more efficient solutions, (see Max Mammel's).
Read all the lines from the file
Store them in a List (allows duplicates)
When done reading, initialize a new Set passing your List in its constructor (that'll trim it into a set of unique Strings)
Then compare the sizes of both - if they're different, you have non-unique items
Off-topic: remember to close your streams!

Categories