I've been working on getting this program to work. I'm having a little trouble getting the program to read the files I have created, census2000 and census2010. These contain the 50 states and their population in 2000 and 2010. I believe that the rest of my program is correct. I was told to use methods to find the smallest population, largest population and the average. Here is two lines from the 2000 file:
Alabama 4447100
Alaska 626932
Here is my program:
public static void main(String[] args) throws IOException {
String state = "";
int population = 0;
int p = 0, s = 0, pop = 0, stat = 0, populate = 0, sum = 0;
File f = new File("census2000.txt");
Scanner infile = new Scanner(f);
infile.useDelimiter("[\t|,|\n|\r]+");
while (infile.hasNext()) {
checksmall(p, s);
checklargest(pop, stat);
checkAverage(populate, sum);
population = infile.nextInt();
state = infile.next("/t");
System.out.println(state + "has" + population + "people");
}
System.out.println(state + "has smallest population of" + population);
prw.close();
}
public static boolean checksmall(int p, int s) {
boolean returnValue;
if (p < s) {
returnValue = true;
} else {
returnValue = false;
}
return (returnValue);
}
public static boolean checklargest(int pop, int stat) {
boolean returnVal;
if (pop > stat) {
returnVal = true;
} else {
returnVal = false;
}
return (returnVal);
}
public static int checkAverage(int populate, int sum) {
int retVal;
retVal = populate + sum;
return (retVal);
}
}
What am I doing wrong?
I believe the problem is here:
state = infile.next("/t");
I think what you're trying to do is skip a tab in the file and read the state? You could do that by reading in the line and then splitting the line using \t as the delimiter.
String line;
while (infile.hasNextLine()){
line = infile.nextLine();
String data[] = line.split("\\s+");
state = data[0];
population = Integer.parseInt(data[1]);
}
edit: also as the other answer points out, you're attempting to perform functions on the file's data before it's read.
You need to be calling checksmall, checklargest and checkAverage after/while the file is loaded.
Related
I have been tasked to solve a question concerning the creation of a triple-ended queue with efficient random access, as outlined in this: https://open.kattis.com/problems/teque. I created a program based around using 2 very large arrays, one containing the front half of all stored integers so far and the other the back half, with both being of the same size or the front half containing at most 1 more element than the back half after every insertion operation. This should allow all insertion and retrieval operations to be of O(1) time complexity, but the code just keeps exceeding the given time limit. Can anyone tell me what is wrong with my code? Here it is:
import java.util.*;
import java.io.*;
public class Teque3 {
static int[] front = new int[1_000_000];
static int[] back = new int[1_000_000];
static int frontHead = 499_999;
static int backHead = 499_999;
static int frontSize = 0;
static int backSize = 0;
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine());
for (int i = 0; i < n; i++) {
String[] line = br.readLine().split(" ");
if (line[0].equals("get")) {
int index = Integer.parseInt(line[1]);
if (index >= frontSize) System.out.println(back[backHead + index - frontSize]);
else System.out.println(front[frontHead + index]);
continue;
}
if (frontSize == backSize) {
if (line[0].equals("push_front")) {
frontHead--;
front[frontHead] = Integer.parseInt(line[1]);
frontSize++;
} else if (line[0].equals("push_back")) {
back[backHead + backSize] = Integer.parseInt(line[1]);
front[frontHead + frontSize] = back[backHead];
frontSize++;
backHead++;
} else if (line[0].equals("push_middle")) {
front[frontHead + frontSize] = Integer.parseInt(line[1]);
frontSize++;
}
} else {
if (line[0].equals("push_front")) {
frontHead--;
front[frontHead] = Integer.parseInt(line[1]);
backHead--;
back[backHead] = front[frontHead + frontSize];
backSize++;
} else if (line[0].equals("push_back")) {
back[backHead + backSize] = Integer.parseInt(line[1]);
backSize++;
} else if (line[0].equals("push_middle")) {
backHead--;
back[backHead] = Integer.parseInt(line[1]);
backSize++;
}
}
}
}
}
You could try to minimze IO-Operations: Collect your programm output. Instead of writing System.out.println better create a new StringBuilder to collect everything. In the end write all at once.
static StringBuilder result = new StringBuilder();
...
private static void result(int value) {
result.append(value).append("\n");
}
...
if (index >= frontSize) result(back[backHead + index - frontSize]);
else result(front[frontHead + index]);
...
System.out.println(result);
Decouple read from parse and process: Create one thread for reading the operations. But the operations in a Queue. Start another thread for the process.
My assignment is:
Create a file that has 2 columns of numbers: Distance and Speed.
Write a class TravelInfo which has three pieces of information: Speed, Time, Distance.
The class should also have a method calcTime() which calculates the time it will take to reach a destination based on the distance and speed (recall: Time = Distance/Speed)
Write a main program that:
Creates an ArrayList of TravelInfo objects of size 10.
Prompts the user for the name of the file and reads the data into TravelInfo objects
Calls the calcTime() method on each TravelInfo object.
Creates an output file with the data written in the format: Distance, Time, Speed
Every time I run my program I get an error
Exception in thread "main" java.util.NoSuchElementException
Other than this error I think I have done everything right except maybe calling my method, and I still haven't formatted the output file yet (not quite sure how). I can't continue while I get this error.
Here is my main() method:
public static void main(String[] args) throws IOException {
Scanner keyboard = new Scanner(System.in);
ArrayList<TravelInfo> list = new ArrayList<>();
System.out.println("What is the name of the file?");
String filename = keyboard.nextLine();
File f = new File(filename);
Scanner inputFile = new Scanner(f);
while(inputFile.hasNext()) {
int s = inputFile.nextInt();
int d = inputFile.nextInt();
int t = inputFile.nextInt();
TravelInfo p = new TravelInfo(s, d, t);
list.add(p);
TravelInfo cls = new TravelInfo(s,d,t);
cls.calcTime(t);
cls.calcTime(s);
cls.calcTime(d);
// System.out.println("Time is " + cls.calcTime(t));
/*for(int i=0; i<list.size(); i++) {
list.get(i).print();
*/ }
for(TravelInfo k : list)
System.out.println(k);
PrintWriter outputFile = new PrintWriter("Data.txt");
outputFile.println(list);
//outputFile.println();
outputFile.close();
}
}
And my TravelInfo class
public class TravelInfo {
private int speed;
private int distance;
private int time;
public TravelInfo(int s, int d, int t) {
speed = s;
distance = d;
time = t;
}
public int calcTime(int time) {
time = distance/speed;
return time;
}
}
You shall do some more validation, and never use the nextXXX() methods blindly - something like
while(true)
{
if (!inputFile.hasNextInt()) {
System.err.println("Reading file failed - invalid format (s)");
break;
}
int s = inputFile.nextInt();
System.out.println("Reading s = " + s);
if (!inputFile.hasNextInt()) {
System.err.println("Reading file failed - invalid format (d)");
break;
}
int d = inputFile.nextInt();
System.out.println("Reading d = " + d);
if (!inputFile.hasNextInt()) {
System.err.println("Reading file failed - invalid format (t)");
break;
}
int t = inputFile.nextInt();
System.out.println("Reading t = " + t);
// Do some stuff
}
This way, you will avoid the NoSuchElementException, and the application will terminate gracefully. You will get the debugging output on the console. It will also print out what exactly has been read from the file.
As Dorian said, you're missing some validation:
while(inputFile.hasNext()) // Tells you there is "at least" 1 more element.
{
int s = inputFile.nextInt(); // Good
int d = inputFile.nextInt(); // Not good if 's' has taken the last element
int t = inputFile.nextInt(); // Same as above
// rest of the code here...
}
I personnally don't like the 'while(true)' stuff, so here is my version.
while(inputFile.hasNextInt()) // I would use 'hasNextInt()' rather than 'hasNext()'
// This will make sure the next data can be cast to an Integer
{
Integer d = null;
Integer t = null;
Integer s = inputFile.nextInt();
if( inputFile.hasNextInt() {
d = inputFile.nextInt();
if( inputFile.hasNextInt() {
t = inputFile.nextInt();
}
}
// 's' will never be null.
if( d != null && t != null ) {
TravelInfo p = new TravelInfo(s, d, t);
list.add(p);
TravelInfo cls = new TravelInfo(s,d,t);
cls.calcTime(t);
cls.calcTime(s);
cls.calcTime(d);
// System.out.println("Time is " + cls.calcTime(t));
/*for(int i=0; i<list.size(); i++)
{
list.get(i).print();
*/ }
for(TravelInfo k : list)
System.out.println(k);
PrintWriter outputFile = new PrintWriter("Data.txt");
outputFile.println(list);
//outputFile.println();
outputFile.close();
}
else if( inputFile.hasNext()) {
// At this point, you there the remaining data cannot be safely cast to an Integer.
}
else {
// Not enough data to process.
}
}
public class TravelInfo {
private int speed;
private int distance;
private int time;
public TravelInfo(int s, int d, int t) {
speed = s;
distance = d;
time = t;
}
public int calcTime(int time) {
time = distance/speed;
return time;
}
// Override toString() instead of using the default Object.toString()
#Override
public String toString() {
// Return whatever 'String' you want
return String.format( "%d, %d, %d", speed, distance, time );
}
}
I am trying to create a program in Java that calculates the average cost of winning the lottery and saves that average to reference when it runs again (my goal is to be able to create a more accurate outcome every time i run it). The average successfully saves to my txt file, but when I run the program it uses 0 as the previous average every time. Any help is greatly appreciated! Thanks!
(Number of times it runs can be changed by changing the 'runs' variable)
public class WinningTheLottery
{
public static final int SIZE = 5;
public static void main(String[] args)
{
int[] winningNums = new int[SIZE];
int[] guessNums = new int[SIZE];
int spent, runs = 1;
double oldAvg = 0;
double newAvg;
int totalSpent = 0;
NumberFormat currency = NumberFormat.getCurrencyInstance();
try
{
Scanner fileScanner = new Scanner(new File("average.txt"));
PrintWriter fileWriter = new PrintWriter(new File("average.txt"));
while (fileScanner.hasNextDouble())
{
oldAvg = fileScanner.nextDouble();
}
for (int i = 0; i < runs; i++)
{
spent = 0;
randomlyAssignedNumbers(winningNums);
// Arrays.toString(nameOfArray) => built in method to print an array
System.out.println("\n[" + (i+1) + "] Todays winning numbers:\n" + Arrays.toString(winningNums).replace("[", "").replace("]", ""));
do
{
randomlyAssignedNumbers(guessNums);
spent++;
} while (howManyCorrect(winningNums, guessNums) < 5);
System.out.println("After spending " + currency.format(spent) + ", you won the Fantasy 5 lottery $75,000 prize!");
totalSpent += spent;
}
newAvg = ((totalSpent/runs) +oldAvg)/2;
fileWriter.println(newAvg);
System.out.println("\nAverage Cost to win the Lottery: " + currency.format(newAvg)
+ "\n(Previous Average: " + currency.format(oldAvg) + ")");
fileScanner.close();
fileWriter.close();
}
catch(IOException e)
{
System.out.println(e.getMessage());
}
}
public static void randomlyAssignedNumbers(int[] anyArray)
{
Random rng = new Random();
for (int i = 0; i < anyArray.length; i++)
{
anyArray[i] = rng.nextInt(36) + 1;
}
}
public static int howManyCorrect(int[] a1, int[] a2)
{
if (a1.length != a2.length)
return -1;
int count = 0;
for (int i = 0; i < a1.length; i++)
{
if (a1[i] == a2[i])
count++;
}
return count;
}
}
Your code is opening the file in overwrite mode, default of many programming languages, before scanner can read the content, thus deleting the content before fileScanner.hasNextDouble() read. Move your PrintWriter instantiation after Scanner read, and it will work.
Note: To open the file in append mode, which I don't think you need here. But in Java you use new FileWriter("average.txt", true) and then wrap a PrintWriter around it.
Try not constructing the PrintWriter until after you read the previous value. As noted in the Javadoc the file will be truncated by creating the PrintWriter.
I spent several hours working on this and even had my professor look at this and it seems to be printing out just the last element in the for loop. It seems to allows me to add the data structure information and initialize the array queue but it only print out the last element. Here is the sufficient code to assist with the question.
static int MAX;
static final int amount = 6;
static boolean [] openflag;
static queue [] Clinic;
static String [] Doctor;
final static String HEADING = "The clinic moniter of Dylan Rychlik";
public static void Listpaitents( ) {
Paitent[] array;
int queuechoice;
JOptionPane.showMessageDialog(null, "Which doctor would you like to
print?");
String InputString = JOptionPane.showInputDialog(null,Doctor, HEADING,
JOptionPane.QUESTION_MESSAGE);
queuechoice = Integer.parseInt(InputString);
if (openflag[queuechoice -1 ] == false){
JOptionPane.showMessageDialog(null, "Sorry, that doctor is not aviable");
}
else {
//Paitent[] array = null;
int limit;
limit = Clinic[queuechoice -1 ].getSize();
array = Clinic[queuechoice -1 ].toArray();
System.out.println(array[0]);
System.out.println(array[1].Print());
System.out.println(array[2].Print());
//int size = Clinic[queuechoice -1].getSize();
//System.out.println(limit);
int x; String out = " Members of the list are: \n";
// boolean exit = false;
for(x = 0; x < limit; x++) {
out += array[x].Print() + "\n";
//System.out.println(out);
// System.out.println(Clinic[queuechoice].toString() + "\n");
}
System.out.println(limit);
JOptionPane.showMessageDialog(null,out);
}
}
Here this is the array() method in the queue clas
public Paitent[] toArray() {
int x;
Paitent[] Array = new Paitent[Length];
queuenode Current = rear;
for (x = 1; ((Current != null) && (x <= Length));x++) {
Array[x-1] = new Paitent();
Array[x-1].update(Current.info);
Current = Current.next;
// System.out.println( Array[x-1].Print());
}
//System.out.println( Array[x-1].Print());
return Array;
}
Any finally here this is the print method
public String Print() {
String outputString;
outputString = "Paitent: " + "-" + name + "\n" + " Telephone number
telephone + " ID " + ID;
return outputString;
}
Any help you can give is really appreciated. I really have spent hours analyzing the code to come up a solution. Its a bulky program.
It seems that 20 regiments were in a continuous process of formation. The first had 1000 men, the second had 950, the third 900, and so on down to the twentieth regiment, which garrisoned only 50. During each week, 100 men were added to each regiment, and at week's end, the largest regiment was sent off to the front.This lasted for a total of 20 weeks.
For this program I have already managed to print out the original number of men for each regiment. But I am having difficult adding 100 men to each regiment.The adding men must be a method in the army class. I am getting the regiment objects using a .txt file. All this files contains is the names of regiments numbered 1-20.
I currently have no errors my only problem is that I do not know how to add men to my regiment. I have to use the addMen method in the army class which I currently have blank.
public class Regiment {
private String name; //name of regiment
private int regNumber; //regiment number
private int men; // regiment men
public Regiment(int regNumber, String name, int men) {
this.name = name;
this.regNumber = regNumber;
this.men = men;
}
public String getName() {
return name;
}
public int getregNumber() {
return regNumber;
}
public int getMen() {
return men;
}
public int addMen2(int RegNumber) {
int men = 1050 - (regNumber * 50);
return men;
}
}
ArmyDataList:
class ArmyDataList {
public ArrayList<Regiment> list;
public ArmyDataList() {
list = new ArrayList<Regiment>();
}
public void AddToList(Regiment current) {
list.add(current);
}
public void RemoveFromList(Regiment current) {
list.remove(current);
}
public Regiment getLargest() {
if (list.isEmpty()) {
return null;
}
Regiment Reg1 = list.get(0);
for (int i = 1; i < list.size(); i++) {
Regiment current = list.get(i); // get next regiment
// is current regiment > largest
if (current.getMen() > Reg1.getMen()) {
Reg1 = current;
}
}
return Reg1;
}
public void addMen() {
}
public String toString() {
String out
= String.format("%28s%12s%n", "Regiments", " Men")
+ String.format("%12s%n", "Number")
+ String.format("%12s%16s%14s%n", "=======", "===============",
"=========");
for (int i = 0; i < list.size(); i++) {
Regiment regim = list.get(i);
int regNumber = regim.getregNumber();
String name = regim.getName();
int men = regim.addMen2(regNumber);
out = out + String.format("%12s", regNumber)
+ String.format("%16s", name)
+ String.format("%10s", men)
+ "\n";
}
return out + "\n";
}
}
RegimentTest:
public class RegimentTest {
public static void main(String[] args) throws IOException
{
ArmyDataList army = new ArmyDataList();
Scanner fileScan = new Scanner(new File("regiments.txt"));
System.out.println("Report Summary:\n");
while (fileScan.hasNext()) {
String line = fileScan.nextLine();
System.out.println(line);
Scanner in = new Scanner(line) ;
int regNumber = in.nextInt();
String name = in.next();
int men = 0 ; //men is set to 0 only because I havent add the men yet
Regiment adder = new Regiment(regNumber, name, men );
army.AddToList(adder) ;
}
System.out.println(army.toString());
}
Add a setMen(int numberOfMen) method to your Regiment class. Then in your addMen() method, you can do something like this:
public void addMen(){
for(Regiment r : list){ //iterate through the list of regiments
r.setMen(r.getMen() + 100); //add 100 men to each regiment
}
}
The setMen method would look like this:
public void setMen(int numberOfMen){
men = numberOfMen;
}
There is another issue with your toString method, where the regiment's addMen2 method is called - right now you're just printing the number, not initializing the number of men. In the constructor for your Regiment class, replace the line
this.men = men;
with
this.men = addMen2(regNumber);
Then in your toString method, replace
int men = regim.addMen2(regNumber);
with
int men = regim.getMen();
Here is what your main should look like:
public static void main(String[] args) throws IOException{
ArmyDataList army = new ArmyDataList();
Scanner fileScan = new Scanner(new File("regiments.txt"));
System.out.println("Report Summary:\n");
while (fileScan.hasNext()) {
String line = fileScan.nextLine();
System.out.println(line);
Scanner in = new Scanner(line);
int regNumber = in.nextInt();
String name = in.next();
int men = 0 ; //men is set to 0 only because I havent add the men yet
Regiment adder = new Regiment(regNumber, name, men );
army.AddToList(adder);
}
System.out.println(army.toString()); //print out the initial # of men
for(int i = 0; i < 20; i++)
army.addMen();
System.out.println(army.toString()); //print the final # of men
}
in Regiment get rid of method addMen2, and replace it with
public void addMen(int men) {
this.men +=men;
}
then in your army you could have method
public void addMen(int men) {
for(Regiment regiment : list){
regiment.addMen(men);
}
}
that will be simplest solution to add 100 men to each regiment,
other thing is, your toString is bit nasty, regiment should know how meny soldiers it ghas, you shouldnt need additional method to calculate it (reason why i recommend you to trash addMen2 method)
to initiate your Regiment, use constructor. You want to have regiments in sizes 1000, 1950, 1900 etc, do it when you are creating them
while (fileScan.hasNext()) {
String line = fileScan.nextLine();
System.out.println(line);
Scanner in = new Scanner(line) ;
int regNumber = in.nextInt();
String name = in.next();
int men = 1050 - (regNumber * 50);
Regiment adder = new Regiment(regNumber, name, men );
army.AddToList(adder) ;
}