Breaking out" of a while loop still executing whats inside? - java

The purpose of this program is to take in positive integers and once the sentinel value (-1) is hit the program will return the 2 lowest numbers. My program works, but in some scenarios it doesn't. for example if I enter 10,15,20,-1 the program will result in 10 rather than 10 and 15. Here is my program:
public class Small{
public static void main(String [ ] args){
int number;
number=IO.readInt();
int lowest=number;
int lowest2=number;
while (number!=-1){
number=IO.readInt();
if(number>0){
if(number<lowest && number!=-1){
lowest=number;}
else{if((number<lowest2||!(number>=lowest2))&& number!=-1){
lowest2=number;}
}
}
}
IO.outputIntAnswer(lowest);
IO.outputIntAnswer(lowest2);
}
}

The main problem with your code is that you set lowest and lowest2 to the first value you enter. If all the other numbers you enter are higher than the first number, it will never be able to find anything lower.
With your example, the first number is 10 which you assign to lowest and lowest2. When you enter 15, it's not lower than 10, so neither variable can be reset. Same with 20.
You've also got a lot of redundant checks in your if-statements.
public class Small {
public static void main(String [ ] args) {
int number;
int lowest = Integer.MAX_VALUE;
int lowest2 = Integer.MAX_VALUE;
while (number!=-1) {
number=IO.readInt();
if (number > 0) {
if(number < lowest) {
lowest=number;
}
else if (number < lowest2) {
lowest2=number;
}
}
}
}
IO.outputIntAnswer(lowest);
IO.outputIntAnswer(lowest2);
}

The problem is with your logic flow of the program. Here's what the code is doing:
Read in one number, store in both lowest and lowest2.
Go through loop to read in more numbers
2a. If the number is positive, check against lowest.
2a1. If the read in value is lower than lowest, change lowest's value to the read in value.
2a2. Otherwise, if the read in value is lower than lowest2, change lowest2's value to the read in value. Only do this if lowest was not changed.
2b. If the read in value is -1, end the loop.
2c. If the read in value is negative but not -1, continue but don't add the number to lowest or lowest2.
Print out the values for lowest and lowest2.
If you see the error, it's in 2a2. This is linked to the fact that your setup before the while loop is formatted as you did: you made both lowest and lowest2 that first value.
This code would normally run correctly, except for one instance: what if that first value were to be the smallest positive value you entered, with all other values greater than it? lowest2 would be set to that value, and you're checking to see if any other values are smaller than it (which they're not, because they're all going to be greater than it).
Tips for when you're coding:
1) Attempt to develop a logical thinking mentality. Think through how you want to create algorithms for your program. Make sure you don't run into any situations where your program does not run the way you want it to, like in this case (this is called a logic error).
2) Run through your programs by hand when you're finished coding, or after you've run it and got an error. Step through every line of your code, and try to see where and why your code isn't working the way you want it to. Or have someone else see, like a fellow programmer. Sometimes, even the best eyes do not catch their own mistakes.
EDIT:
There are various ways to solve this particular problem. One way is to do what Seeker and Rick did:
1) Set both values to the largest possible Integer value, and thus all values entered will be lower than the first values.
2) Ask for the first two inputs at the beginning before the loop, and check them against each other to set the first two lowest values.
However, I believe there are certain things to watch out for when you're doing something like this. These should all be outlined before you code, of course.
1) What if the user is entering only one or zero valid values? Seeker's method wouldn't work, unless he checks that the first/second value is negative/-1. Rick's method wouldn't work either because at least one of the lowest/lowest2 values would still be that max Integer value.
2) What if there were no positive values entered before the -1? This is similar to number 1, and your ints would be null.
You can certainly use Seeker's and Rick's algorithms, but you should check for these conditions if you use them.

import java.util.Scanner;
public class Small {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("Enter Number");
int lowest = scanner.nextInt();
System.out.println("Enter Number");
int lowest2 = scanner.nextInt();
if (lowest > lowest2) {
int t = lowest;
lowest = lowest2;
lowest2 = t;
}
while (true) {
System.out.println("Enter Number");
int number = scanner.nextInt();
if (number == -1)
break;
if (number < lowest2 && number < lowest) {
lowest = number;
} else if (number < lowest2) {
lowest2 = number;
}
}
System.out.println("lowest:" + lowest);
System.out.println("lowest2:" + lowest2);
scanner.close();
}
}

Related

Integer overflow for large a Fibonnaci sequence despite using Long primitive type and Big Integer

I'm making a program to print nth Fibonacci Number.
Method FIBBO(int n) uses a combination of long and BigInteger types to store the result of Fibonacci operations. The method is suppose to switch over to using BigInteger when it is deemed that prev+next>Long.MAX_VALUE using big_flag. However this program only works if i use Integer.MAX_VALUE in the 2nd loop.
When i use Long.MAX_VALUE, the 2nd loop of big_flag is never triggered now matter how large the value of n and i only get garbage values. I can't understand why my overflow logic is never activated when i use Long.MAX_VALUE.
import java.util.*;
import java.math.*;
public class fibbo_iteration{
public static void main(String argss[])
{
BigInteger result;
Scanner input=new Scanner(System.in);
int n=0;
System.out.println("Enter number of terms for fibbonacci sequence");
n=input.nextInt();
if(n<0){
System.out.println("Fibbonaci sequence cannot be generated for the entered negative value");
System.exit(1);
}
result=fibbo_iteration.FIBBO(n); //call
System.out.println(result.toString());
}
static BigInteger FIBBO(int n)
{
// variables
long sum=0L,prev=0L,next=1L;
BigInteger big_prev=new BigInteger("0"),big_next=new BigInteger("0"),big_sum=new BigInteger("0");
boolean big_flag=false;
for(int i=0;i<n;i++){
if(big_flag){
// System.out.println(big_sum.toString()); to use when printing a series upto n
big_prev=big_next;
big_next=big_sum;
big_sum=big_prev.add(big_next);
}
else if(prev+next>Long.MAX_VALUE){ // ***The program works abolutely correct if i replace LONG.MAX_VALUE with Integer.MAX_Value***
big_prev=new BigInteger(String.valueOf(prev));
big_next=new BigInteger(String.valueOf(next));
big_sum=big_prev.add(big_next);
big_flag=true; // this is supposed to signal the switch to BigInteger
System.out.println("Value exceeds Long");
}
else{
if(i==1){ // this if block accomodates the eccentricity of starting the fibbonaci sequence
sum=1L;
continue;
}
sum=prev+next;
prev=next;
next=sum;
System.out.println(sum);
}
}
return big_flag==true?big_sum:new BigInteger(String.valueOf(sum));
}
}
The max value of Long is really the maximum of the type. Any calculation above this is giving you... well results you apparently do not expect. A check of the kind prev+next>Long.MAX_VALUE is a nonsense. It will never be truthy.
A bit of change that should make your program work is: prev > Long.MAX_VALUE - next
If you want to understand in greater detail, you can use the comparison as I wrote it and debug, placing a breakpoint inside the if block. Try to see the value of prev+next. See how it goes negative. This is because you have reached values outside what long can store.
Use Math.addExact(long,long). Surround using try-catch and switch to BigInteger when the Exception is thrown.
try
{
sum=Math.addExact(prev, next);
prev=next;
next=sum;
System.out.println(sum);
}
catch(ArithmeticException overflow)//Out of range
{
big_prev=new BigInteger(String.valueOf(prev));
big_next=new BigInteger(String.valueOf(next));
big_sum=big_prev.add(big_next);
big_flag=true; // this is supposed to signal the switch to BigInteger
System.out.println("Value exceeds Long");
}
This snippet should be placed in the else block corresponding to if(big_flag).
Also see Integer Overflow.

How to add a variable to another variable that's already set

My homework is to create a program that takes a list of numbers and prints out the highest number divisible by four.
List would look like this:
12
16
87
58
25
73
86
36
79
40
12
89
32
Input should be:
40 because it is the highest number there divisible by four.
Here is my code:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int saved = 0;
int saved2 = 0;
for (int i = scanner.nextInt(); i % 4 == 0; i = scanner.nextInt()) {
for (boolean bull = true; bull == true; bull ^= true) {
if (i > saved) {
saved -= saved2;
saved += i;
saved2 += i;
}
}
System.out.println(saved);
}
}
}
The input of my code is
12
16
I don't really understand why this is doing it, but it seems to me that I'm adding the variables wrong. The homework page on adding variables does not specify how to add variables to each other.
Does anyone have a tip to improve the code in anyway, or find a way to make a fix my code? Thank you.
welcome to Java.
First you are saying you got input, but that is output. Input is what you enter, and output is what you get printed.
Then there is a mistake in your for loops. You have too much going on in one place. By the logic which is implemented, your program will exit first level for loop whenever your entered value is not divisable by 4.
Read on for loops if you want to learn more https://www.learnjavaonline.org/en/Loops.
I recommend to start from while loops instead. The logic whould be this:
1. create variable to hold the correct answer saved
2. create another one to hold the value read from console i
3. start the while loop with condition i = scanner.nextInt()
3.1 check if the value just entered i is divisable by 4
3.2 if it is, then compare if it's larger than the one was saved before (initially saved value will be 0)
3.3 if it is larger, then assign the read value i to the saved
4. At the end of the loop, you will have the highest number divisable by four in your saved variable. Print it.
I will provide some help, according to
How do I ask and answer homework questions?
for (int i = scanner.nextInt(); i % 4 == 0;i = scanner.nextInt())
This only reads as long as ALL inputs are divisible by 4, that is why it ends at 16, because 87 is not divisible by 4.
for (boolean bull = true; bull == true ;bull ^= true)
This needs explanation by you, but I am pretty sure that it unconditionally executes the body of the inner loop exactly once. (Not 100% sure, because the representation of true and false could be weird in your machine. Should 0 be the representation of true, i.e. really weird, then it is an endless loop, which does not match the output you describe...)
System.out.println(saved);
This executes exactly once per input, except the last one, which is not a multiple of 4.
The value of saved is identical to input, as long as it is increasing.
These hints explain the unexpected output.
If you inspect the details of what the problem is, you should be able to improve your coding attempt.
This is how I super-quickly fixed in your code.
Note that there are no statements about the possible minimum value and about how do you stop the input. Therefore the solution is pretty-straightforward, it just reads the input until integers are present there.
This article may be useful about handling the input from the Scanner.
I hope the comments in the code will help. Add comments if there are any questions. Good luck!
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int currentMax = Integer.MIN_VALUE; // you may set negative or 0 if you know that all the input is positive
// int saved2 = 0; // no need for this variable
while (scanner.hasNextInt()) { // you can make a better input handling, especially if you know when it should end the input. Now it will end on any non-integer input line
int i = scanner.nextInt();
// for (int i = scanner.nextInt(); i % 4 == 0; i = scanner.nextInt()) {
// for (boolean bull = true; bull == true; bull ^= true) {
if (((i % 4) == 0) && (i > currentMax)) {
currentMax = i;
// saved -= saved2;
// saved += i;
// saved2 += i;
// }
}
}
System.out.println(currentMax); // moved out of "for" or "while" cycles. Print the value after the input has ended.
}
}

using a while loop for user to input multiple int and find the max and min

so my homework question is prompt user a series of integers and find the max and min of those integer. Use a loop and -99 to break loop.Below is my code but my question is that is there a shorter way for this? feel free to comment and i appreciate your time reading this.
Scanner input=new Scanner(System.in);
int num1,num2,max,min;
System.out.print("enter a number: ");
num1=input.nextInt();
System.out.print("enter another number: ");
num2=input.nextInt();
max=Math.max(num1,num2);
min=Math.min(num1,num2);
while (num2!=-99){
System.out.print("enter a number or -99 to stop: ");
num2=input.nextInt();
if(num2!=-99){
max=Math.max(max,num2);
min=Math.min(min,num2);
}
}
System.out.println("largest is: "+max);
System.out.println("Smallest is: "+min);
You check for the condition of num2 != -99 twice, remember the first rule of programming, do not repeat yourself
You could save some lines by checking for min and max before asking for the next input. This way you do not need to check if num2 != -99 inside the while loop
Ok So after working on this. I finally did it. It does have a small bug, but I really don't wanna fix it so if anyway wants to edit this then be my guest.
Scanner input = new Scanner(System.in);
int studentNum = 0;
ArrayList<Integer> calc = new ArrayList<Integer>();
while (studentNum <= 100) {
System.out.print("Enter a number: ");
calc.add(input.nextInt());
studentNum += 1;
if (input.nextInt() == -99) {
break;
}
}
int min = Collections.min(calc);
int max = Collections.max(calc);
for (int i = 0; i < calc.size(); i++) {
int number = calc.get(i);
if (number < min)
min = number;
if (number > max)
max = number;
}
System.out.println("Max is " + max);
System.out.println("Min is " + min);
This does exactly what you want. However, there was a problem checking for the exit signal.
if (input.nextInt() == -99) {
break;
}
this checks if the userInput is equal to -99 then stops the program and calculates and prints out the min and max. However the tiny bug is that it will first ask for your number to add to the array list and then it will ask again for the userInput to check if its equal to -99. But overall it does exactly what you want.
Hope this helped.
EDIT I will work on it later and find a way to fix that bug if no one else knows.
Your code has one minor bug and can be slightly optimised. Things you might want to consider:
What happens (and what should happen) when the user types -99 as the second number?
Do you necessarily need to have at least 2 numbers? Wouldn't one be enough for the program to exit gracefully? The first number would then be both min and max.
Can you re-order your code lines so that the duplicated (num2!=-99) is not necessary anymore?
Pro questions:
What happens if the user types in some letters? How can you handle that case?
What happens if the user types in a super high number (bigger than the maximal integer)?
What happens if the user presses enter without typing any number?
Nitpicking:
Using + to concatenate strings and numbers is a bad idea because it's hard to remember where it works and where it doesn't.
Better look into String.valueOf(int i) and String.format(String format, Object... args)
Look up Google's Java Coding Style for formatting your code in best readable way. In many editors you can automatically apply the style. It describes things like where to use spaces or what to indent.

Need help Spotting A logic error in my program (prime numbers) / understanding output

New to programming.
Before you comment: I understand that their are more efficient ways to do this, and already have. I just feel that understanding the process here will make me a better programmer.
Following pseudo code I saw in class. I wrote a program that takes a integer and prints every prime number up to and including the integer(userinput).
This is what I came up with:
//Import Scanner.
import java.util.Scanner;
//Create class.
public class QuestionTwoA2
{
public static void main(String[] args)
{
System.out.println("Enter an integer:"); //Ask for user input.
int userInteger; //Create scanner object and collect user input.
Scanner keyboard = new Scanner(System.in);
userInteger = keyboard.nextInt();
boolean primeFlag = true; //Condition required for prime number loop.
int outer; //I localised these variables outside the loop so that I
int inner; //could test output by printing it.
//Checks natural numbers in between 2 and userInteger.
for (outer = 2; outer < userInteger; outer++)
{
for (inner = 2; inner < outer; inner++)
{
if (outer % inner == 0)
{
primeFlag = false;
//System.out.println(outer + " " + inner);
break;
}
}
if (primeFlag) //I think this statement causes a logic problem.
System.out.println(outer);
}
}
}
I have/had print statements in various parts of my code just to visualise what values I am comparing to get a remainder. My current output is (for any integer input):
Enter an integer:
9
2
3
Logically my code looks fine but obviously doesn't work, help explaining what is actually going on would be much appreciated.
You should put "boolean primeFlag = true;" inside the first for and before the second for.
Since second for is for detecting whether the "outer" variable is a prime number or not, so before going into that you should set your flag true which is your assumption at first, and in second loop when you are checking all smaller values to see whether it is actually prime or not and change the flag if not.

How to find the minimum number of sequence input in Java

I am devoloping an application to find the minimum of all the numbers entered .It accepts the numbers from the dialog box and when the user enters 0 it displays the minimum of all the numbers.But i dont need the 0 but the minimum of the numbers that preceeded it.
My code is as Follows:
try {
int a, c = 0, d = 0;
do {
a = Integer.parseInt(jOptionPane1.showInputDialog(null, "please enter the number"));
c = Math.min(a, d);
if (a != 0) //since a=0 will be excecuted one time
{
d = c;
}
} while (a != 0);
lb2.setText("Minimum of the numbers is " + d);
} catch (Exception e) {
jOptionPane1.showMessageDialog(this, "Some thing went wrong");
}
I know that it gives me 0 because the minimim of the numbers entered is zero and if i enter a number less than 0 (ie a negative number)it gives me the correct answer .I think the problem is also due to the initialisation that c=0.
Now i need a method to find the minimum without using any arrays and it should be simple and easy.(most helpful if you use Math.min itself)
Any help Appreciated.
Just change your initialization to set d set to Integer.MAX_VALUE.
I have an advice for your code, that you should make every variable names make sense. Maybe your code is small, but it will affect your habit, and when you work in large project, your habit will affect you so much :)
You should change initialize part of d = 0 to d = Integer.MAX_VALUE. Here is a new code :
try {
int inputNumber = 0, min= Integer.MAX_VALUE;
// int c : you don't need this variable
do {
inputNumber = Integer.parseInt(jOptionPane1.showInputDialog(null, "please enter the number"));
if (inputNumber != 0) //since a=0 will be excecuted one time
{
min= inputNumber;
}
} while (inputNumber != 0);
lb2.setText("Minimum of the numbers is " + min);
} catch (Exception e) {
jOptionPane1.showMessageDialog(this, "Some thing went wrong");
}
This new code is make more sense ?
And, Why you Must change initialize to min= Integer.MAX_VALUE? For example, you initialize like this : min = 10;. And at first time when someone type 15, you program will see : Oh, 15>10, so this is not the min value. But in fact, 15 is the first value of input and it should be the min value. Your program will be wrong until someone type a number less than 10.
Compare to your code, because you initialize d=0. when you type d=1, ops, 1>0, this is not min value (like above example). And everything will true only when you type some numbers < 0.
Al the problem above happen, because although user types any number, the min is the initialize number. (the number that user doesn't type). And that why you set your min value to something REALLY REALLY big. So, the FIRST TIME you type some numbers, It's ALREADY the SMALLEST.
Because machine not like us, doesn't have "infinity", so we must set it the biggest value possible. And because d is an int, so the biggest value of int is Integer.MAX_VALUE. In fact, you can type number for d. I don't remember exactly, but the biggest value for integer in range 32000 (2^31).

Categories

Resources