Alright, so I'm taking on this little personal project for my teacher (Not my Computer Science teacher) and I'm trying to make a test from a fairly large list of questions. So far I've been able to read in the first question, ask the answer, and tell if they're right or not. The only problem is, it repeats the same question over and over.
Sadly, I'm stumped as to how I can make the program check to see if the question has been answered or not. My initial thought was to take the line from the question file that says "QUESTION #", separate the number, parse it into an integer and somehow make the BufferedReader skip that question.
Here is the quizTest:
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.Scanner;
public class quizTest {
public static void main (String[] args) throws IOException{
BufferedReader reader = null;
reader = new BufferedReader(new FileReader("C:/Users/Kevin/Desktop/eclipse/WorkspaceCompTIA.ActualTests.220-802.v2012-11-05.by.Caitto.txt/"));
String line, userAnswer;
int i = 0;
Scanner scan = new Scanner(System.in);
String questionNum = "";
String question = "", choiceA = "", choiceB = "", choiceC = "", choiceD = "", answer = "";
while((line = reader.readLine()) != null){
if(line.contains("?")){
question = line;
}
if(line.contains("A.")){
choiceA = line;
}
if(line.contains("B.")){
choiceB = line;
}
if(line.contains("C.")){
choiceC = line;
}
if(line.contains("D.")){
choiceD = line;
}
if(line.contains("Correct Answer: ")){
String[] a = line.split(": ");
answer = a[1];
}
}
while(i < 274){
quizClass run = new quizClass(i, question, choiceA, choiceB, choiceC, choiceD, answer);
System.out.print(questionNum);
System.out.println(run.getQuestion());
System.out.println();
System.out.println(run.getChoiceA());
System.out.println(run.getChoiceB());
System.out.println(run.getChoiceC());
System.out.println(run.getChoiceD());
System.out.println();
System.out.print("Your Answer: ");
System.out.println();
userAnswer = scan.next();
if(userAnswer.equalsIgnoreCase(answer)){
System.out.println("Correct!");
i++;
}
}
if(i == 274){
reader.close();
scan.close();
}
}
}
Here is quizClass:
public class quizClass {
private String question, answer, choiceA, choiceB, choiceC, choiceD;
private int questionNum;
public quizClass(int questionNum, String question, String choiceA, String choiceB, String choiceC, String choiceD, String answer){
this.question = question;
this.answer = answer;
this.choiceA = choiceA;
this.choiceB = choiceB;
this.choiceC = choiceC;
this.choiceD = choiceD;
}
public String getQuestion(){
return question;
}
public String getAnswer(){
return answer;
}
public String getChoiceA(){
return choiceA;
}
public String getChoiceB(){
return choiceB;
}
public String getChoiceC(){
return choiceC;
}
public String getChoiceD(){
return choiceD;
}
public int getQuestionNum(){
return questionNum;
}
}
And finally here is the format of the question file:
http://puu.sh/5nJhS.png
EDIT:
So after fiddling around with it, I've managed to get it working now(I'm sure there are better ways to go about it, but this way works, so I'm happy :P):
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.Scanner;
public class QuizTest {
public static void main (String[] args) throws IOException{
String question = "";
String choiceA = "";
String choiceB = "";
String choiceC = "";
String choiceD = "";
String answer = "";
String line;
String userAnswer;
int i = 0;
BufferedReader reader = null;
reader = new BufferedReader(new FileReader("C:/Users/Kevin/Desktop/eclipse/Workspace/CompTIA.ActualTests.220-802.v2012-11-05.by.Caitto.txt/"));
Scanner scan = new Scanner(System.in);
QuizClass run = new QuizClass(i, question, choiceA, choiceB, choiceC, choiceD, answer);
while((line = reader.readLine()) != null){
//Finds the question
if(line.contains("?")){
run.question = line;
System.out.println(run.getQuestion() + "\n");
}
//Finds answer "A"
if(line.contains("A.")){
run.choiceA = line;
System.out.println(run.getChoiceA());
}
//Finds answer "B"
if(line.contains("B.")){
run.choiceB = line;
System.out.println(run.getChoiceB());
}
//Finds answer "C"
if(line.contains("C.")){
run.choiceC = line;
System.out.println(run.getChoiceC());
}
//Finds answer "D"
if(line.contains("D.")){
run.choiceD = line;
System.out.println(run.getChoiceD() + "\n");
}
//Finds the correct answer for the question
if(line.contains("Correct Answer: ")){
String[] a = line.split(": ");
answer = a[1];
run.answer = answer;
System.out.print("Your Answer: ");
userAnswer = scan.next();
//Checks if the user's input matches the correct answer from the file
if(userAnswer.equalsIgnoreCase(answer)){
System.out.println("Correct!\n");
i++;
}
//Checks if the user's input doesn't match the correct answer from the file
else if (!userAnswer.equalsIgnoreCase(answer)) {
System.out.println("Wrong, the correct answer was: " + run.getAnswer());
i++;
}
}
}
if(i == 274){
reader.close();
scan.close();
}
}
}
You're reading in the whole file in your initial while loop and writing over your variables. So, to simplify, the program will read the line
A. NETSTAT
and set choiceA to "A. NETSTAT". It will then continue looping until it sees
A. Windows XP
and then update choiceA to be "A. Windows XP".
In the end, it will be like your program only read the last question.
How should you solve this? My first thought would be to encode your questions in XML, from which you load a set of questions. This is a less clunky solution but requires a bit more infrastructure.
If you want to stay with your current set up, you should have two loops: one outer loop the runs until your reach EOF, and an inner that loops until the "Correct Answer" line.
Extra tips/comments:
Add a toString() method QuizClass (note the standard Java naming scheme -- always captialize) like this:
public toString() {
System.out.print(questionNum);
System.out.println(question);
System.out.println();
System.out.println(choiceA);
System.out.println(choiceB);
System.out.println(choiceC);
System.out.println(choiceD);
System.out.println();
}
and then call it in main with
System.out.print(run);
answer variable in your QuizClass class does nothing. You instead use another variable, userAnswer, in the main class. Why?
What is 274? Don't use magic numbers that don't mean anything. There's probably a constant defined in the classes you are using that are more informative.
I see, your answer variable is declared all the way to the right in a long line of multiple variable declarations -- please don't do that. Whitespace is cheap, and so use it (but don't over-use it and sacrifice readability) -- give each variable its own line.
As for your problem, you have two while loops, in one, you read in your data, but discard it, and in the second you try to use the data, but can't since it's already been discarded.
To solve this, you could do it using only one while loop, not two. And in that while loop, read in your question data and act on it, and then loop to the next. If you must use two loops, then you'll need to first fill an ArrayList of quizClass (ArrayList<quizClass>) while reading in from the file, and then in the second loop, use a for loop, not a while loop (since you'll know the size of the ArrayList), and use the quizClass objects held in the ArrayList second loop to ask your questino and get your answers.
Related
My bad for the title, I am usually not good at making those.
I have a programme that will generate all permutations of an inputted word and that is supposed to check to see if those are words (checks dictionary), and output the ones that are. Really I just need the last the part and I can not figure out how to parse through a file.
I took out what was there (now displaying the "String words =") because it really made thing worse (was an if statement). Right now, all it will do is output all permutations.
Edit: I should add that the try/catch was added in when I tried turning the file in a list (as opposed to the string format which it is currently in). So right now it does nothing.
One more thing: is it possible (well how, really) to get the permutations to display permutations with lesser characters than entered ? Sorry for the bad wording, like if I enter five characters, show all five character permutations, and four, and three, and two, and one.
import java.util.List;
import java.util.Scanner;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.io.IOException;
import org.apache.commons.io.FileUtils;
import static java.lang.System.out;
public class Permutations
{
public static void main(String[] args) throws Exception
{
out.println("Enter anything to get permutations: ");
Scanner scan = new Scanner(System.in);
String io = scan.nextLine();
String str = io;
StringBuffer strBuf = new StringBuffer(str);
mutate(strBuf,str.length());
}
private static void mutate(StringBuffer str, int index)
{
try
{
String words = FileUtils.readFileToString(new File("wordsEn.txt"));
if(index <= 0)
{
out.println(str);
}
else
{
mutate(str, index - 1);
int currLoc = str.length()-index;
for (int i = currLoc + 1; i < str.length(); i++)
{
change(str, currLoc, i);
mutate(str, index - 1);
change(str, i, currLoc);
}
}
}
catch(IOException e)
{
out.println("Your search found no results");
}
}
private static void change(StringBuffer str, int loc1, int loc2)
{
char t1 = str.charAt(loc1);
str.setCharAt(loc1, str.charAt(loc2));
str.setCharAt(loc2, t1);
}
}
If each word in your file is actually on a different line, maybe you can try this:
BufferedReader br = new BufferedReader(new FileReader(file));
String line = null;
while ((line = br.readLine()) != null)
{
... // check and print here
}
Or if you want to try something else, the Apache Commons IO library has something called LineIterator.
An Iterator over the lines in a Reader.
LineIterator holds a reference to an open Reader. When you have finished with the iterator you should close the reader to free internal resources. This can be done by closing the reader directly, or by calling the close() or closeQuietly(LineIterator) method on the iterator.
The recommended usage pattern is:
LineIterator it = FileUtils.lineIterator(file, "UTF-8");
try {
while (it.hasNext()) {
String line = it.nextLine();
// do something with line
}
} finally {
it.close();
}
The program that I am trying to create is a program that takes words from a user defined file, saves those words as variables and then searches a different user defined file for those words, outputting there location.
The program works up to and including the point where the program takes the words and saves them as variables. The problem with the program is that the search method returns a null result. My main suspicions are that the code in the search method is incompatible with the code in the read method, or that the 2 methods aren't running simultaneously.
The search method is in the searching class and the read method is in the reading class.
Here is my code (Containing all 3 of my classes), please excuse all of the imports.
This is the first class:
import java.io.FileNotFoundException;
import java.util.Scanner;
public class Combination{
public static void main(String[] args) throws FileNotFoundException{
Scanner userInput = new Scanner(System.in);
Reading ReadingObject = new Reading();
System.out.println("Please enter the file that you wish to open");
String temp = userInput.nextLine();
ReadingObject.setFileName(temp);
ReadingObject.read();
Scanner searchForWord = new Scanner(System.in);
Searching SearchingObject = new Searching();
System.out.println("Please enter the file that you would like to search for these words in");
String temp1 = searchForWord.nextLine();
SearchingObject.setFileName(temp1);
SearchingObject.search();
}
}
This is the second class:
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.InputStreamReader;
class Reading {
private String file;
public void setFileName(String fileName){
file = fileName;
}
public String getFileName(){
return file;
}
public void read(){
try{
//Choosing the file to open
FileInputStream fstream = new FileInputStream(getFileName());
//Get the object of datainputstream
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String strLine = null;
//Read the file line by line
while((strLine = br.readLine()) != null){
// \\s+ means any number of whitespaces between tokens
String [] tokens = strLine.split("\\s+");
String [] words = tokens;
for(String word : words){
System.out.print(word);
System.out.print(" ");
Searching SearchingObject = new Searching();
SearchingObject.setWord(word);
}
System.out.print("\n");
}
in.close();
}
catch(Exception e){
System.err.println("Error: " + e.getMessage());
}
}
}
This is the third class:
import java.io.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
class Searching {
private String file1;
public void setFileName(String fileName){
file1 = fileName;
}
public String getFileName(){
return file1;
}
private String word1;
public void setWord(String wordName){
word1 = wordName;
}
public String getWord(){
return word1;
}
public void search() throws FileNotFoundException{
try{
//Choosing the file to open
FileInputStream fstream = new FileInputStream(getFileName());
//Get the object of datainputstream
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String strLine = null;
while((strLine = br.readLine()) != null){
Pattern p = Pattern.compile(getWord());
Matcher m = p.matcher(strLine);
int start = 0;
while (m.find(start)) {
System.out.printf("Word found: %s at index %d to %d.%n", m.group(), m.start(), m.end());
start = m.end();
}
}
}
catch(Exception e){
System.err.println("Error: " + e.getMessage());
}
}
}
Any help will be greatly appreciated.
Regards
Your code is hard to read. Your reading class does not only read; it also searches. You should call it something that reflects its intended use. However, it forgets to tell its searching object where to search, and does not pass the reference to this object to anyone else. In this snippet
for (String word : words) {
System.out.print(word);
System.out.print(" ");
searching searchingObject = new searching();
searchingObject.setWord(word);
}
you are essentially not doing anything. The reference to searchingObject is lost forever.
Your reading class should keep an ArrayList of words to be searched for in the searching, instead of instancing searching objects.
Your searching class should take, as a constructor parameter, one of these ArrayLists -- and convert it into a single regex, which is much more efficient than reading the file once per word to search for. You can search for "a", "b" and "c" using the single regular expression "a|b|c". Works with longer words, too. Escape them first to avoid problems.
Oh, and please, please follow naming guidelines. Call your reading a TokenReader, and your searching a WordListSearcher...
I am implementing a RPN calculator in Java and need help creating a class to parse the equations into separate tokens.
My input file will have an unknown number of equations similar to the ones shown below:
49+62*61-36
4/64
(53+26)
0*72
21-85+75-85
90*76-50+67
46*89-15
34/83-38
20/76/14+92-15
I have already implemented my own generic stack class to be used in the program, but I am now trying to figure out how to read data from the input file. Any help appreciated.
I've posted the source code for my stack class at PasteBin, in case it may help.
I have also uploaded the Calculator with no filereading to PasteBin to show what I have done already.
I have now managed to get the file read in and the tokens broken up thanks for the help. I am getting an error when it reaches the end of the file and was wondering how to solve that?
Here is the code:
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.StringTokenizer;
public class TestClass {
static public void main(String[] args) throws IOException {
File file = new File("testEquations.txt");
String[] lines = new String[10];
try {
FileReader reader = new FileReader(file);
BufferedReader buffReader = new BufferedReader(reader);
int x = 0;
String s;
while((s = buffReader.readLine()) != null){
lines[x] = s;
x++;
}
}
catch(IOException e){
System.exit(0);
}
String OPERATORS = "+-*/()";
for (String st : lines) {
StringTokenizer tokens = new StringTokenizer(st, OPERATORS, true);
while (tokens.hasMoreTokens()) {
String token = tokens.nextToken();
if (OPERATORS.contains(token))
handleOperator(token);
else
handleNumber(token);
}
}
}
private static void handleNumber(String token) {
System.out.println(""+token);
}
private static void handleOperator(String token) {
System.out.println(""+token);
}
}
Also How would I make sure the RPN works line by line? I am getting quite confused by the algorithms I am trying to follow.
Because all of the operators are single characters, you can instruct StringTokenizer to return them along with the numeric tokens.
String OPERATORS = "+-*/()";
String[] lines = ...
for (String line : lines) {
StringTokenizer tokens = new StringTokenizer(line, OPERATORS, true);
while (tokens.hasMoreTOkens()) {
String token = tokens.nextToken();
if (OPERATORS.contains(token))
handleOperator(token);
else
handleNumber(token);
}
}
As your question has now changed completely from it's original version - this is in response to your original one, which was how to use FileReader to get the values from your file.
This will put each line into a separate element of a String array. You should probably use an ArrayList instead, as it's far more flexible, but I have just done this as a quick demo - you can clean it up as you wish, although I notice the code you are using expects a String array as it's input. Perhaps you could read the values initially into an ArrayList, then copy that to an array once you have all the lines - that way you can put as many lines in as you wish and keep your code flexible for changes in the number of lines in your input file.
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
public class TestClass {
static public void main(String[] args) {
File file = new File("myfile.txt");
String[] lines = new String[10];
try {
FileReader reader = new FileReader(file);
BufferedReader buffReader = new BufferedReader(reader);
int x = 0;
String s;
while((s = buffReader.readLine()) != null){
lines[x] = s;
x++;
}
}
catch(IOException e){
//handle exception
}
// And just to prove we have the lines right where we want them..
for(String st: lines)
System.out.println(st);
}
}
You mentioned before that you were using the code on this link:
http://www.technical-recipes.com/2011/a-mathematical-expression-parser-in-java/#more-1658
This appears to already deal with operator precedence doesn't it? And with parsing each String from the array and sorting them into numbers or operators? From my quick look it at least it appears to do that.
So it looks like all you need is for your lines to be in a String array, which you then pass to the code you already have. From what I can see anyway.
Obviously this doesn't address the issue of numbers greater than 9, but hopefully it helps with the first half.
:-)
public void actionPerformed(ActionEvent e) {
double sum=0;
int count = 0 ;
try {
String nomFichier = "Fichier.txt";
FileReader fr = new FileReader(nomFichier);
BufferedReader br = new BufferedReader(fr);
String ligneLue;
do {
ligneLue = br.readLine();
if(ligneLue != null) {
StringTokenizer st = new StringTokenizer(ligneLue, ";");
String nom = st.nextToken();
String prenom = st.nextToken();
String age = st.nextToken();
String tele = st.nextToken();
String adress = st.nextToken();
String codePostal = st.nextToken();
String ville = st.nextToken();
String paye = st.nextToken();
double note = Double.parseDouble(st.nextToken());
count++;
}
}
while(ligneLue != null);
br.close();
double mediane = count / 2;
if(mediane % 2 == 0) {
JOptionPane.showMessageDialog(null, "Le mediane dans le fichier est " + mediane);
}
else {
mediane +=1;
JOptionPane.showMessageDialog(null, "Le mediane dans le fichier est " + mediane);
}
}//fin try
catch(FileNotFoundException ex) {
System.out.println(ex.getMessage());
}
catch(IOException ex) {
System.out.println(ex.getMessage());
}
}
For testing, I've got three names in a text file.
Joe ,Smith
Jim ,Jones
Bob ,Johnson
I fixed the eternal looping by adding a second s=reader.readLine(); at the end of my while loop, but when I run the code below, I get the following output:
JoeSmith
JoeSmith
JimJones
JimJones
BobJohnson
BobJohnson
How can I prevent the duplicate names? Is my second s=reader.readLine(); placed incorrectly? * Crap. Nevermind. I'm printing the source data and the array fields created from it. Oy.
import java.nio.file.*;
import java.io.*;
import java.nio.channels.FileChannel;
import java.nio.ByteBuffer;
import static java.nio.file.StandardOpenOption.*;
import java.util.Scanner;
import java.text.*;
import javax.swing.JOptionPane;
//
public class VPass
{
public static void main(String[] args)
{
final String FIRST_FORMAT = " ";
final String LAST_FORMAT = " ";
String delimiter = ",";
String s = FIRST_FORMAT + delimiter + LAST_FORMAT ;
String[] array = new String[2];
Scanner kb = new Scanner(System.in);
Path file = Paths.get("NameLIst.txt");
try
{
InputStream iStream=new BufferedInputStream(Files.newInputStream(file));
BufferedReader reader=new BufferedReader(new InputStreamReader(iStream));
s=reader.readLine();
while(s != null)
{
array = s.split(delimiter);
String firstName = array[0];
String lastName = array[1];
System.out.println(array[0]+array[1]+"\n"+firstName+lastName);
s=reader.readLine();
}
}
catch(Exception e)
{
System.out.println("Message: " + e);
}
}
}
You never update s after the first loop iteration.
You code needs to be more along the lines of:
while ((s = reader.readLine()) != null)
{
array = s.split(delimiter);
String firstName = array[0].trim();
String lastName = array[1].trim();
System.out.println(array[0]+array[1]+"\n"+userName+password);
}
Edit: added trim() suggestion as per Sanchit's comment.
Subsequent edit after the question changed:
I fixed the eternal looping by adding a second s=reader.readLine(); at the end of my while loop, but when I run the code below, I get the following output:
JoeSmith
JoeSmith
JimJones
JimJones
BobJohnson
BobJohnson
If we look at your code:
while(s != null)
{
array = s.split(delimiter);
String firstName = array[0];
String lastName = array[1];
System.out.println(array[0]+array[1]+"\n"+firstName+lastName); // <-- this prints 2 lines of output
s=reader.readLine();
}
... you see you output 2 lines of output for every loop iteration.
Put s=reader.readLine(); again at the end of your while loop. Eventually it will become null and your loop will exit.
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 7 years ago.
Improve this question
I'm trying to use the Simple hill climbing algorithm to solve the travelling salesman problem. I want to create a Java program to do this. I know it's not the best one to use but I mainly want it to see the results and then compare the results with the following that I will also create:
Stochastic Hill Climber
Random Restart Hill Climber
Simulated Annealing.
Anyway back to the simple hill climbing algorithm I already have this:
import java.util.*;
public class HCSA
{
static private Random rand;
static public void main(String args[])
{
for(int i=0;i<10;++i) System.out.println(UR(3,4));
}
static public double UR(double a,double b)
{
if (rand == null)
{
rand = new Random();
rand.setSeed(System.nanoTime());
}
return((b-a)*rand.nextDouble()+a);
}
}
Is this all I need? Is this code even right..? I have a range of different datasets in text documents that I want the program to read from and then produce results.
Would really appreciate any help on this.
----- EDIT ----
I was being an idiot and opened the Java file straight into Eclipse when i should have opened it in notepad first.. here is the code i have now got.
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.Reader;
import java.io.StreamTokenizer;
import java.util.ArrayList;
{
//Print a 2D double array to the console Window
static public void PrintArray(double x[][])
{
for(int i=0;i<x.length;++i)
{
for(int j=0;j<x[i].length;++j)
{
System.out.print(x[i][j]);
System.out.print(" ");
}
System.out.println();
}
}
//reads in a text file and parses all of the numbers in it
//is for reading in a square 2D numeric array from a text file
//This code is not very good and can be improved!
//But it should work!!!
//'sep' is the separator between columns
static public double[][] ReadArrayFile(String filename,String sep)
{
double res[][] = null;
try
{
BufferedReader input = null;
input = new BufferedReader(new FileReader(filename));
String line = null;
int ncol = 0;
int nrow = 0;
while ((line = input.readLine()) != null)
{
++nrow;
String[] columns = line.split(sep);
ncol = Math.max(ncol,columns.length);
}
res = new double[nrow][ncol];
input = new BufferedReader(new FileReader(filename));
int i=0,j=0;
while ((line = input.readLine()) != null)
{
String[] columns = line.split(sep);
for(j=0;j<columns.length;++j)
{
res[i][j] = Double.parseDouble(columns[j]);
}
++i;
}
}
catch(Exception E)
{
System.out.println("+++ReadArrayFile: "+E.getMessage());
}
return(res);
}
//This method reads in a text file and parses all of the numbers in it
//This code is not very good and can be improved!
//But it should work!!!
//It takes in as input a string filename and returns an array list of Integers
static public ArrayList<Integer> ReadIntegerFile(String filename)
{
ArrayList<Integer> res = new ArrayList<Integer>();
Reader r;
try
{
r = new BufferedReader(new FileReader(filename));
StreamTokenizer stok = new StreamTokenizer(r);
stok.parseNumbers();
stok.nextToken();
while (stok.ttype != StreamTokenizer.TT_EOF)
{
if (stok.ttype == StreamTokenizer.TT_NUMBER)
{
res.add((int)(stok.nval));
}
stok.nextToken();
}
}
catch(Exception E)
{
System.out.println("+++ReadIntegerFile: "+E.getMessage());
}
return(res);
}
}
You can compare your results against the code repository for the textbook
"Artificial Intelligence a Modern Approach", here is the aima code repository.
Their hill climbing implementation is HillClimbingSearch.java
I'm not sure what the code you pasted has to do with Traveling Salesman. You have a function UR which generates a random number in the interval [a,b).