Determine the two smallest integers from a set of user input integers

Hi everyone,

I am a little stumped on this problem. I have it solved for the most part but I'm getting stuck on a small detail. First here is the exact wording of the problem:

"Write a Java program that prompts the user to enter integer values then prints the two smallest numbers (in any order) in the input. You may assume that the user will enter a valid number greater than 1 for the number of numbers to read."

We have not studied arrays yet so the prof expects us to use loops and conditional statements to determine the smallest values in real time. Now I have been able to write a program that will output the two smallest digits in all scenarios EXCEPT for if the first digit entered is the smallest digit. I was wondering if there is another if statement that can remedy this issue or if I should approach the problem in a completely different way. Here is the code:

Code Java:

import java.util.*;
public class Assignment5Q1 {
public static void main(String[] args) {
Scanner input = new Scanner (System.in);
System.out.print ("How many numbers would you like to enter? ");
int numin = input.nextInt();
System.out.print ("Number 1: ");
int num1 = input.nextInt();
int min1 = num1;
int min2 = num1;
for (int i=2; i<=numin; i++) {
System.out.print ("Number " + i + ": ");
int num2 = input.nextInt();
if (num2 >= min1 && num2 < min2) {
min2 = num2;
}
if (num2 < min1) {
min2 = min1;
min1 = num2;
}
}
System.out.println("The two smallest numbers are " + min1 + " and " + min2);
}
}

I don't necessarily want someone to outright give me the answer but even a hint as to what I might try would be greatly appreciated. Thanks very much in advance for your help!!

Re: Determine the two smallest integers from a set of user input integers

I have some tips.

I'm not sure why everyone is taught this when they first start, but you usually don't want to go to less than or equal to in your for loops and you don't want to start from something like 2. There are obviously exceptions to this rule, but that is what is generally accepted. The reason for this is indexing, which is something you will learn about with arrays. Basically, indexes start at 0. So, it is usually a good idea to start your loops at 0. And, the maximum index of an array is the size of the array minus one. So, it is also usually a good idea to stop when the index equals the size.

Although you are not doing arrays at the moment, it is a good thing to get used to doing.

Also, since you have been given the guarantee that the number inputted will always be greater than 1, you don't have to set your two minimum variables outside the loop. Usually, a programmer sets an int that has not been given a value to -1. That is also an indexing thing that you will probably learn to do. Since the numbers will always be positive, we can do this without a problem. Inside our loop, we can check the value of our two ints. If they are -1, we know they haven't been set yet and we need to set them. We also know that both can have the same value, so we can set both if one equals -1.

Next, there is no reason to do the complex if statements you have done. In fact, we only want to run checks for 1 of them. For my example below, I am assuming the first value is always going to be the lowest. So, whenever we find a value lower than the first number, we want to set the second number to be equal to it. If the number is not lower than the first number, only then do we want to check the second number. So, instead of this:

Code java:

System.out.print ("Number 1: ");
int num1 = input.nextInt();
int min1 = num1;
int min2 = num1;
for (int i=2; i<=numin; i++) {
System.out.print ("Number " + i + ": ");
int num2 = input.nextInt();
if (num2 >= min1 && num2 < min2) {
min2 = num2;
}
if (num2 < min1) {
min2 = min1;
min1 = num2;
}
}

I would say this:

Code java:

//Set Values to -1 to indicate no value.
int min1 = -1;
int min2 = -1;
//For loop. Start at 0 and end when i equals numin
for (int i=0; i<numin; i++)
{
//Prompt the user. Since we start at 0, we want to say (i+1) for the count
System.out.print ("Number " + (i+1) + ": ");
//Get number from user
int num = input.nextInt();
/* There is a lot going on here. First of all, notice the use of else if statements
* instead of just if statements. This is because when one of these statements return
* true, we do not want to even check the other two statements. Checking the others
* just slow down the loop. Also notice what we check last. We check if min1 and min2
* has not been set on our last else if statement. This is because that statement will
* only run the first time and it is not necessary for us to evaluate it every time.
* So, it will only evaluate that statement if the other two are not true. Next, notice
* how we have checked if num is less than min1 as our first statement. This is because
* we want to shift min1 into min2 if it is less than. Now notice how the next check,
* which checks if num is less than min2, is checked with an else if statement. This is
* because if the first if statement returns true, then num will be less than min2, and
* we don't want to set min2 to equal that when min1 has been set to that. Lastly, notice
* that we don't check if it is equal to. If it is equal to, we can ignore it, as it is
* already the low number and changing it will do nothing.
*/
if(num<min1)
{
//Set min2 to equal min1 first
min2 = min1;
//Set min1 to equal num
min1 = num;
}
else if(num<min2)
{
//Set min2 to equal num
min2 = num;
}
else if(min1==-1)
{
//Set min1 to equal num
min1 = num;
//Set min2 to equal num
min2 = num;
}
}

I commented my code heavily so you can understand why I did what I did. The changes are largely stylistic and I'm only intending to show an alternative (and possibly faster) way of doing this. Based on what I have done and explained above, see if you can fix your attempt.

Re: Determine the two smallest integers from a set of user input integers

Thanks so much aussiemcgr, that is very helpful and those are some good tips. Unfortunately I think you misinterpreted the question a little bit. When it says the user will enter a value greater than 1, this is in reference to the number of numbers that the user wants to input, not the numbers themselves. So I don't think setting the two min values to -1 will work since the numbers can be any value, positive or negative. I have rewritten my code a little bit to incorporate your tips and try to make it a little cleaner but I am still running into trouble. Here is the code:

Code Java:

// Import java utils so we can use user input
import java.util.*;
public class Assignment5Q1 {
public static void main(String[] args) {
Scanner input = new Scanner (System.in);
// Prompt user for the number of numbers they want to enter
System.out.print ("How many numbers would you like to enter? ");
int numin = input.nextInt();
System.out.print ("Number 1: ");
int num1 = input.nextInt();
// Assigns the two minimum values to the first value entered by the user
int min1 = num1;
int min2 = num1;
// Continues to prompt user for numbers and evaluate the minimum values on the fly
for (int i=1; i<numin; i++) {
System.out.print ("Number " + (i+1) + ": ");
int num2 = input.nextInt();
// Series of conditional statements that determines what the minimum values
// entered by the user are.
if (num2 <= min1) {
min2 = min1;
min1 = num2;
} else if (num2 < min2) {
min2 = num2;
} else if (min1 == min2) {
min2 = num2;
}
}
// Prints the two minimum integers that the user input
System.out.println("The two smallest numbers are " + min1 + " and " + min2);
}
}

Now the issue I am having is that if you input the smallest value, say 1, and then a larger value and then 1 again and then another larger value, it determines the two smallest numbers to be 1 and the last value, rather than 1 and 1. For example:

How many numbers would you like to enter? 4

Number 1: 1

Number 2: 5

Number 3: 1

Number 4: 3

The two smallest numbers are 1 and 3

Clearly this is wrong and the two smallest numbers should be 1 and 1. Is there something very simple I am missing here? I cant figure this one out!

Thanks again in advance!

Re: Determine the two smallest integers from a set of user input integers

It is this statement:

Code java:

else if (min1 == min2) {
min2 = num2;
}

Since we are setting the default values outside of the loop, we only need 2 cases. The first is if num2 is less than min1. The second is if num2 is less than min2. So, instead of this:

Code java:

if (num2 <= min1) {
min2 = min1;
min1 = num2;
} else if (num2 < min2) {
min2 = num2;
} else if (min1 == min2) {
min2 = num2;
}

We need this:

Code java:

if (num2 <= min1) {
min2 = min1;
min1 = num2;
} else if (num2 < min2) {
min2 = num2;
}

The reason that you are getting 3, is because when the fourth number is entered, min1 and min2 equal 1. So since num1 and num2 are equal to each other, min2 gets set to num2, which is not what we want.

Re: Determine the two smallest integers from a set of user input integers

Hi aussiemcgr thanks again for your quick reply. I do see what you are saying however if I remove that statement I am back to where I started where if the first number entered is the smallest number, min1 and min2 will be displayed as that number. For example...

Code Java:

for (int i=1; i<numin; i++) {
System.out.print ("Number " + (i+1) + ": ");
int num2 = input.nextInt();
// Series of conditional statements that determines what the minimum values
// entered by the user are.
if (num2 <= min1) {
min2 = min1;
min1 = num2;
} else if (num2 < min2) {
min2 = num2;
// } else if (min1 == min2) {
// min2 = num2;
}
}
// Prints the two minimum integers that the user input
System.out.println("The two smallest numbers are " + min1 + " and " + min2);
}
}

Gives me...

How many numbers would you like to enter? 4

Number 1: 1

Number 2: 2

Number 3: 2

Number 4: 2

The two smallest numbers are 1 and 1

When the two smallest numbers should be 1 and 2. :confused::confused::confused:

Any more suggestions? :)

Thanks again