Logic Error in Java Program - java

Writing a program that reads in numbers from a text file and tests them to see if they are prime or not. Text file consists of the following numbers: 98, 76, 84, 69, 92, 83, 88, 90, 72, 66. The first number, 98 is not prime, but then the second number (76) should come out as Prime. My printed out results show all the numbers being Not Prime which is not true.
import java.io.*;
import java.util.Scanner;
public class AssignFive_FileRead {
public static void main(String[] args) throws IOException {
int number;
int calc = 0;
int i = 2;
File myFile = new File("Numbers.txt");
Scanner inputFile = new Scanner(myFile);
// Check to see if file exists
if (!myFile.exists()) {
System.out.println("Error: file cannot be found");
System.exit(0);
} else {
System.out.println("File has been found, starting operation...");
}
// Reading numbers from text file
while (inputFile.hasNext()) {
number = inputFile.nextInt();
// Begin calculation to see if number is prime
while (i <= number / 2) {
if (number % i == 0) {
calc = 1;
}
i++;
} // End second while loop
if (calc == 1) {
System.out.println("Number: " + number + " is Not Prime!");
} else {
System.out.println("Number: " + number + " is Prime!");
}
} // End first while loop
} // End main
} // End public class

There is a bug in your code (I just spotted it).
But the big error is in your testing methodology.
You say that 76 is a prime number. It isn't. 76 is 38 x 2, and that means it is not prime. (Indeed, any positive number that is even and larger than 2 is not prime ...)
In fact, 83 is the only prime number in that list.

Init calc whenever you read a number
// Reading numbers from text file
while (inputFile.hasNext()) {
number = inputFile.nextInt();
// Begin calculation to see if number is prime
calc = 0;
while (i <= number / 2) {
// [...]

You should reset both i and calc every time you come out from second while loop. I have fixed it by using the following code
import java.io.*;
import java.util.Scanner;
public class AssignFive_FileRead {
public static void main(String[] args) throws IOException {
int number;
int calc = 0;
int i = 2;
File myFile = new File("input.txt");
Scanner inputFile = new Scanner(myFile);
// Check to see if file exists
if (!myFile.exists()) {
System.out.println("Error: file cannot be found");
System.exit(0);
} else {
System.out.println("File has been found, starting operation...");
}
// Reading numbers from text file
while (inputFile.hasNext()) {
number = inputFile.nextInt();
// Begin calculation to see if number is prime
while (i <= number / 2) {
if (number % i == 0) {
calc = 1;
}
i++;
} // End second while loop
if (calc == 1) {
System.out.println("Number: " + number + " is Not Prime!");
} else {
System.out.println("Number: " + number + " is Prime!");
}
calc = 0;
i=2;
} // End first while loop
} // End main
} // End public class

Related

Printing ArrayList from a separate main class Java

I have an Assignment that has many questions and the only ones I seem to be having trouble with are the ones with ArrayLists. I need to use a separate main method to enter and print out information.
This is my class
import java.util.ArrayList;
public class HailstoneSequence {
private int n;
public HailstoneSequence(int n) {
this.n = n;
}
public double getn() {
return n;
}
public static ArrayList<Integer> getHailstoneSequence(int n){
ArrayList<Integer> list = new ArrayList<Integer>();
//int i = 0;
while (n != 1);
for (int s : list) {
try {
if(n == 1) break;
if(n % 2 == 0) {
System.out.println(n + " is even, so I take half: " + (n / 2));
}
else
System.out.println(n + " is odd, so I make 3n+1: " + ((n * 3)+1));
// i++;
}
catch (Exception error) {
while (n <= 1) {
System.out.println("You did not enter a valid positive, greater than 1 integer. Please try again: ");
System.out.println();
}
}
}
return list;
}
}
and this is the main class (which does not work)
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;
public class TestHailstoneSequence {
#SuppressWarnings("resource")
public static void main(String[]args){
Scanner input = new Scanner(System.in);
System.out.println("The Hailstone Sequence takes a number and if it odd it multiples it by 3 and adds 1,"
+ "\nit divides it by 2 and carries on until it reaches 1. \nPlease enter a positive number"
+ " (greater than 1) to generate the Hailstone Sequence: ");
int n = input.nextInt();
HailstoneSequence aHailstoneSequence = new HailstoneSequence(n);
System.out.println(Arrays.toString(aHailstoneSequence.list));
}
}
Please help me understand how to print out the results
You declared getHailstoneSequence method as static one you should call it and store to a variable if you need in another operation and printing like this:
ArrayList<Integer> list = HailstoneSequence.getHailstoneSequence(n);
System.out.println(list);
For your current case the main method will look something like this:
import java.util.Scanner;
public class TestHailstoneSequence {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("The Hailstone Sequence takes a number and if it odd it multiples it by 3 and adds 1,"
+ "\nit divides it by 2 and carries on until it reaches 1. \nPlease enter a positive number"
+ " (greater than 1) to generate the Hailstone Sequence: ");
int n = input.nextInt();
input.close(); // do not forget to close the resource
// if you use static method in your HailstoneSequence class you can remove
// field with name "n" from that class and you don't need to create an object in this case
// Also I'd rename the class from HailstoneSequence to something like HailstoneSequenceCalculator
System.out.println(HailstoneSequence.getHailstoneSequence(n));
}
}

Having trouble with using a while loop for simulating a 1 in 5 chance

I am having trouble with a program that looks to compute the chance of someone winning a contest that they have a 1 in 5 chance of winning. It is a simulation that repeats this 1000 times. The current loop iterates once correctly but just outputs zero to the file for all other loops and I can't figure out why.
import java.util.Scanner;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.File;
public class BottleCapPrize
{
public static void main (String [ ] args) throws IOException
{
//establishing scanner and variables
Scanner in = new Scanner(System.in);
int minimumTrials = 1000;
int enteredTrials = 0;
int won = 0;
int triesToWin = 0;
double totalTries = 0;
int winningValue = 0;
//establishes the number of trials and sais if it is less than 1000
while(enteredTrials < minimumTrials)
{
System.out.println("Please enter a number of trials greater than 1000: ");
enteredTrials = in.nextInt();
if(enteredTrials >= minimumTrials)
{
System.out.println("You enetred " + enteredTrials + " trials.");
}
else
{
System.out.println("You entered an incorrect number of trials.");
}
}
//establishes file to write to
PrintWriter outFile = new PrintWriter(new File("prizeResults.txt"));
//writes to these files the amount of tries it takes to get the prize 1000 times
for (int loop = 1; loop <= enteredTrials; loop++)
{
while(won != 1)
{
winningValue = (int)((Math.random() * 5.0) + 1.0);
if(winningValue == 1)
{
won ++;
triesToWin ++;
}
else
{
triesToWin ++;
}
}
winningValue = 0;
outFile.println(triesToWin);
triesToWin = 0;
}//end of for loop
outFile.close ( ); //close the file when finished
//finds the average number of tries it took
File fileName = new File("prizeResults.txt");
Scanner inFile = new Scanner(fileName);
while (inFile.hasNextInt())
{
totalTries = totalTries + inFile.nextInt();
}
double averageTries = totalTries/enteredTrials;
//tells the user the average
System.out.println("You would have to by an average of " + averageTries + " bottles to win.");
}//end of main method
}//end of class
You are not resetting won back to zero. Thus after the first time, when you increment won to 1, the while loop ends, and then in each subsequent for loop, it skips the while loop and prints value of triesToWin which you set back to zero.
Try adding
won = 0;
after writing to the file.

Java File Problems

So we want an application to allow the user to enter the names and grades of students the user should be prompted for the name of the file to create and for the number of students to be entered (1 grade per student). Then the program takes all of the grades and averages them. The problem is that it is not reading the file and always gives us a average of -0.0.
`
public static void main(String[] args) throws IOException {
System.out.println("What is the name of the file you would like to create?");
filename = p.next();
File fd = new File(filename + ".txt");
fd.createNewFile();
students(fd);
}
public static void students(File fd) throws IOException {
int numbstudents;
FileWriter ap = new FileWriter(fd, true);
BufferedWriter ad = new BufferedWriter(ap);
System.out.println("How many students would you like to add?");
numbstudents = p.nextInt();
int i = 0;
while (i != numbstudents) {
for (i = 0; i < numbstudents; i++) {
System.out.println("What is the name of student number " + i + " ?");
String name = p.next();
ad.write(name);
ad.newLine();
System.out.println("What grade did student number " + i + " acheive?");
String a = f.next();
ad.write(a);
ad.newLine();
}
}
read(fd);
ad.close();
}
public static void read(File fd) throws FileNotFoundException {
int counter = 0;
FileReader h;
BufferedReader g;
String test;
double average, total = 0;
int number = 0;
int i = 0;
try {
h = new FileReader(fd);
g = new BufferedReader(h);
while ((test = g.readLine()) != null) {
number += 1;
System.out.println(test);
counter = counter + 1;
i = counter % 2;
if (i == 0) {
total += Double.parseDouble(test);
}
}
average = total / (number - 1);
System.out.println("The students average is: " + average);
g.close();
fd.delete();
} catch (FileNotFoundException e) {
System.out.println("File could not be found.");
} catch (IOException e) {
System.out.println("Your file could not be read.");
}
}
}
`
You're attempting to read from the file before you've closed the writer.
The close() call includes flushing buffered data to disk. You're reading before data is flushed to disk.
As a side note, consider what you're accomplishing with this pair of statements:
while (i != numbstudents) {
for (i = 0; i < numbstudents; i++) {
The while is unnecessary. The for statement iterates over the comfortably numb students.
Also note the difference in conditions between the two. In general, when iterating over numbers, it's safer to use '<', '<=', '>' or '>=' than '==' or '!='. Otherwise, if you pass by the endpoint before an equality condition, it will continue happily past the end.
Finally, consider naming your methods with descriptive verb phrases. This will help you with breaking the big problem down into smaller pieces. For example, you could have one method called inputStudents() that reads input and creates and closes the file, called before another method printAverageOfStudents() that reads the file and computes the average.

How can I get my for each loop to print once for each number in the array

assignment:
Write a program that reads in integers between 1 and 100 from the user and counts the
occurrences of each number. The user input ends when they enter a 0.
You must use an enhanced for-loop to solve this problem.
If a number occurs more than 1 time use the plural word “times” instead of “time”. Do not display numbers that were not entered.
I know and understand why my code's current output below appears with duplicates. The print logic is inside the for-each loop code block. If I close the code block I am no longer able to use the variables I initialized inside the loop. I have tried everything I can think of. Any suggestions would be appreciated
current output:
- 1 occurs 1 time,
- 1 occurs 2 times
- 2 occurs 1 time
- 2 occurs 2 times
- 3 occurs 1 time
- 3 occurs 2 times
needed output:
- 1 occurs 2 times
- 2 occurs 2 times
- 3 occurs 2 times
package com.company;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int[] numbers = new int[10];
System.out.print("Enter Integers:");
for (int i = 0; i < numbers.length; i++) {
numbers[i] = in.nextInt();
if (numbers[i] == 0) {
break;
}
}
enhancedLoop(numbers);
}
private static void enhancedLoop(int[] numbers) {
int[] counts = new int[101];
for (int value : numbers) {
counts[value]++;
if (value > 0)
if (counts[value]> 1)
System.out.println(value + " occurs " + counts[value]+ " times");
else
System.out.println(value + " occurs " + counts[value] + " time");
}
}
Variables are only available in the block in which they are declared. Move the output after the for loop and iterate over counts to display the values:
for (int i = 0, c = counts.length; i < c; ++i) {
if (counts[i] > 0) {
if (counts[i] > 1) {
System.out.println(value + " occurs " + counts[i]+ " times");
} else {
System.out.println(value + " occurs " + counts[i]+ " time");
}
}
}
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int[] numbers = new int[10];
System.out.print("Enter Integers:");
for (int i = 0; i < numbers.length; i++) {
numbers[i] = in.nextInt();
if (numbers[i] == 0) {
break;
}
}
enhancedLoop(numbers);
}
private static void enhancedLoop(int[] numbers) {
int[] counts = new int[101];
for (int value : numbers) {
counts[value]++;
if (value > 0)
if (counts[value]> 1)
System.out.println(value + " occurs " + counts[value]+ " times");
else
System.out.println(value + " occurs " + counts[value] + " time");
}
}
You can do this effectively using the below steps:
(1) Identify the unique numbers first
(2) Find the number of times each unique number occurs
So, you need to change your enhancedLoop(int[] numbers) method as shown below to achieve the result:
private static void enhancedLoop(int[] numbers) {
//convert the array to a list to make computations easier by using streams
List<Integer> numbersList = Arrays.stream(numbers).boxed().collect(Collectors.toList());
//Get the unique numbers in the list
List<Integer> uniqueNumbers = numbersList.stream().distinct().collect(Collectors.toList());
//Now find out number of times each each unique number occured
for(int number : uniqueNumbers) {
long times = numbersList.stream().filter(num -> num == number).count();
System.out.println(number+" occurs "+times);
}
}
lets try to do this without lamdas, using simply a hashmap instead of arrays
import java.util.Scanner;
import java.util.HashMap;
import java.util.Map;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
HashMap<Integer, Integer> numbers = new HashMap<Integer, Integer>();
int tmp=0;
System.out.print("Enter Integers:");
//read a maximum of 10 int
for (int i = 0; i < 10; i++) {
tmp = in.nextInt();
//if we read a 0 we quit
if (tmp == 0) {
break;
}
//if we already saw the number we up the counter
if(numbers.containsKey(tmp)){
numbers.put(tmp, numbers.get(tmp)+1);
}else{
//otherwise we just add the new int
numbers.put(tmp, 1);
}
}
//call the print loop
enhancedLoop(numbers);
}
private static void enhancedLoop(HashMap<Integer, Integer> numbers) {
//you print what you counted
for(Map.Entry<Integer, Integer> entry : numbers.entrySet()) {
System.out.print(entry.getKey() + " occurs " + entry.getValue() + " time");
if (entry.getValue()>1)
System.out.print("s");
System.out.println("");
}
}

OutOfBoundsException When Calling Return For A Method JAVA

i'll get straight to the chase. If a user wants to read another file they must type r in the menu, then they are thrown with a return readFile(); method which takes them to the top of the program and asks them the same question it did at the beggining when they first ran this program. Only issue is when you type R or Default it throws an OutOFBoundsException. BTW It is Reading a CSV file
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1000
at studentrecs.StudentRecs.in(StudentRecs.java:71)
at studentrecs.StudentRecs.readFile(StudentRecs.java:55)
at studentrecs.StudentRecs.menu(StudentRecs.java:97)
at studentrecs.StudentRecs.main(StudentRecs.java:33)
Java Result: 1
/
public static Boolean readFile(String filename) throws IOException { //Constructor for filename
try {
Scanner userInput = new Scanner(System.in);
System.out.println("Type R To Read a File or Type Default for the default file");
user = userInput.nextLine();
if (user.equalsIgnoreCase("r")) {
user = userInput.nextLine();
}
filename = user;
if (user.equalsIgnoreCase("default")) {
filename = "newreg2.csv";
}
Scanner input = new Scanner(new FileReader(filename));
while (input.hasNext()) {
in(input.nextLine());
numstu++;
}
input.close();
return true;
} catch (IOException e) {
System.err.println(e.getMessage());
}
return false;
}
public static void in(String reader) {
String splitter[];
splitter = reader.split(",");
stu[numstu] = new StuRec();
stu[numstu].studentID = splitter[0];
stu[numstu].lastName = splitter[1];
stu[numstu].firstName = splitter[2];
stu[numstu].phoneNumber = splitter[3];
stu[numstu].courseCode = splitter[4];
stu[numstu].periodNumber = Integer.parseInt(splitter[5]); // parseInt turns a string of digits into an integer
stu[numstu].mark = Integer.parseInt(splitter[6]);
}
public static boolean menu() throws IOException {
String choice;
Scanner userInput = new Scanner(System.in);
System.out.println("=============================================");
System.out.println("Type R To Read Another File");
System.out.println("Type L To Print all File Records");
System.out.println("Type AA To Print The Average Of All The Marks");
System.out.println("Type X To Exit The Program");
choice = userInput.nextLine();
double average = 0.0; // declare average
if (choice.equalsIgnoreCase("L")) {
for (int i = 0; i < numstu; i++) {
System.out.println(stu[i].lastName + ", " + stu[i].firstName + ", " + stu[i].studentID + ", " + stu[i].phoneNumber + ", " + stu[i].courseCode + ", " + stu[i].periodNumber + ", " + stu[i].mark);
}
}else if (choice.equalsIgnoreCase("R")){
return readFile(filename);
} else if (choice.equalsIgnoreCase("AA")) {
for (int i = 0; i < numstu; i++) {
average += stu[i].mark; // keep adding to average
}
}else if (choice.equalsIgnoreCase("X")) {
for (int i = 0; i < numstu; i++) {
System.exit(i);
}
}else if (choice.equalsIgnoreCase("AC")) {
} else {System.err.println("Unknown Key Try Again...");
}
// divide by zero protection
if ( choice.equalsIgnoreCase("AA") && numstu > 0 ) {
average = average/numstu; // compute the average. Always use the size in terms of a variable whenever possible.
System.out.println(average); // as noted below, if this is an integer value, < #of students computations will eval to 0.
}
else if (!choice.equalsIgnoreCase("AA") && numstu < 0) {
System.out.println("Oops! No Marks To Calculate! :(");
}
return menu();
}
}
It looks like EITHER you have initialised numstu to start at 1, OR you have more than 1000 lines in your file.
The effect of either of these errors would be that you eventually attempt to write data to entry 1000 of stu. But since you've initialised stu with 1000 entries, numbered from 0 to 999, this gives your error.
You should make sure that numstu is initially 0, not 1.
And next time you post a question, post ALL of your code, not just the parts where you think the error might be. It's very difficult for most people to find bugs in code that they can't see.

Categories

Resources