I have an assignment to find the minimum, maximum, and average of numbers that a user inputs. Basically, they type in positive integers, seperated by a space and Java scrolls through them and adds them up. I'm able to find the sum, the average, and the largest integers, however, I am unable to find the smallest. I thought the best way to figure this out would be to set the variable representing the smallest int equal to the variable representing the largest int outside of the loop. Then, within the loop, do something like this:
if(getInt < min)
{
min = getInt;
}
Where getInt is the user-inputted value and min is the minimum integer value. Every time I run this, though, min returns as 0.
Here is my full code:
import java.util.Scanner;
public class exc5
{
public static void main (String[] args)
{
System.out.println("Write a list of nonnegative integers, each seperated by a space. To signal the end of the list, write a negative integer. The negative integer will not be counted");
Scanner keyboard = new Scanner (System.in);
keyboard.useDelimiter(" |\n");
int count = 0;
int sum = 0;
int max = 0;
int min = max;
double average = 0;
boolean notNull = true;
while(notNull == true)
{
int getInt = keyboard.nextInt();
if(getInt < 0)
{
notNull = false;
}
else
{
if(getInt > max)
{
max = getInt;
}
if(getInt < min)
{
min = getInt;
}
sum += getInt;
count++;
average = (sum)/(count);
}
}
System.out.println("Sum = " + sum);
System.out.println("Average = " + average);
System.out.println("Max = " + max);
System.out.println("Minimum = " + min);
}
}
Any help is appreciated!
You should initially set min to Integer.MAX_VALUE, and max to Integer.MIN_VALUE.
You need to start with a large min, not 0 (only negative numbers are less then 0). Try this:
int min = Integer.MAX_VALUE;
This is a fairly standard pattern. Also, to be "correct", your code should also include:
int max = Integer.MIN_VALUE;
Then the full range of integer input, positive and negative, is handled.
Edit:
Another, more "classic" approach would be to use an object reference, rather than a primitive (which always has a value), so the initial state can be easily distinguished as null. In this case, using Integer, rather than int for the values would allow testing for null. If I were a university professor marking such work, I would rather see the object approach - using min/max values for primitives will work, but it's a bit of a "trick".
The code wold look like this:
Integer min;
while (...) {
if (min == null || getInt < min) {
min = getInt;
}
}
And similar for max.
This:
int max = 0;
int min = max;
initializes min to zero. (After all, max hasn't become the largest integer yet.) So this:
if(getInt < min)
will never be true. Try changing this:
int min = max;
to this:
int min = Integer.MAX_VALUE; // largest possible Java `int`
That's because you're assigning min = 0, so obviously unless you input a number lower than 0, the minimum is 0. You should initialize min to Integer.MAX_VALUE
int min = Integer.MAX_VALUE;
(
or also:
int min = 0xFFFFFFFF;
Just for hacking around :P. Use the first one! :)
)
You are setting min to zero, so (since the inputs are positive) none of the inputs are less than min.
The normal way to do this is to set the initial value of max to Integer.MIN_VALUE, and the initial value of min to Integer.MAX_VALUE.
This ensures that any input value will affect at least one of min and max - usually both!
You initialize min with 0. Try to initialize with Integer.MAX_VALUE, i.e. it would be best to do:
int max = Integer.MIN_VALUE;
int min = Integer.MAX_VALUE;
Otherwise, your check:
if(getInt < 0)
will break out of the loop and you will never go over 0.
you have min set as 0 to start with so getInt will never be less. You should set min at the beginning of the loop and that will solve your issue.
Fully working and "cleaned" version of your program:
import java.util.Scanner;
public class exc5
{
public static void main ( String [] args )
{
Scanner keyboard = new Scanner( System.in );
int count = 0;
int sum = 0;
int max = Integer.MIN_VALUE;
int min = Integer.MAX_VALUE;
double average = 0;
boolean notNull = true;
while ( notNull == true )
{
int getInt = keyboard.nextInt();
if ( getInt < 0 )
notNull = false;
else
{
if ( getInt > max )
max = getInt;
if ( getInt <= min )
min = getInt;
sum += getInt;
count++;
}
}
average = ( sum ) / ( count );
System.out.println( "Sum = " + sum );
System.out.println( "Average = " + average );
System.out.println( "Max = " + max );
System.out.println( "Minimum = " + min );
}
}
Related
I'm very new to Java, most of the time I don't know what I'm doing. I'm trying to make a code where you can choose how many numbers to generate, the maximum and the minimum number of a random number generated.
It keeps on generating the numbers within the max and min range infinitely.
import java.util.Scanner;
import java.util.Random;
public class random_unfinished {
public static void main(String[] args) {
int numofgen, max, min, generated, avg, i;
Scanner scan = new Scanner(System.in);
Random random = new Random();
System.out.println("How many numbers would you like to generate?");
numofgen = scan.nextInt();
System.out.println("What is the maximum number?");
max = scan.nextInt() + 1;
System.out.println("What is the minimum number?");
min = scan.nextInt();
for (int value = min; value <= max;) {
value = random.nextInt(max - min) + min;
System.out.println("numbers are " + value);
}
}
}
Okay so the for loop is problematic.
Get used to this:
for (int i = 0; i < n; i++) {
if your for loop doesn't look like that, unless you're quite advanced you're probably doing it wrong.
In your case for instance:
for (int value = min; value <= max;) {
You initialise a variable called value to be the minimum.
Your test to continue is whether value is less than max (which it will be unless min is greater than max)
The thing you do each time after executing the body of the loop is ... nothing.
Hence you loop infinitely.
Compare with the gold standard:
for (int i = 0; i < n; i++) {
It initialises a variable i to 0
Its test whether to continue is if i is less than a certain number n
After each execution of the body of the loop it increments i.
Ergo - unless we do something naughty to i, (or do an early exit with a break or return) we will repeat the body of the loop n times.
Cf:
for (int value = min; value <= max; [_____you forgot this bit____] ) {
The problem is that your for-loop is going from min to max. Also, it is missing an update clause—which means that value never changes. Hence, you’re stuck with an infinite loop.
Instead, you should go from 0 to numofgen and make sure to update your i by 1 each time. This will generate as many numbers as the user desires.
import java.util.Scanner;
import java.util.Random;
public class random_unfinished {
public static void main(String[] args) {
int numofgen, max, min, generated, avg, i;
Scanner scan = new Scanner(System.in);
Random random = new Random();
System.out.println("How many numbers would you like to generate?");
numofgen = scan.nextInt();
System.out.println("What is the maximum number?");
max = scan.nextInt() + 1;
System.out.println("What is the minimum number?");
min = scan.nextInt();
for (int i = 0; i < numofgen; i++) {
value = random.nextInt(max - min) + min;
System.out.println("numbers are " + value);
}
}
}
I'm brand new to Java and creating a simple program that takes information output from another program and uses it via command line for a loop. No matter how many times I look at it, I can't figure out why the 'if (minValue > value' doesn't change minValue.
Output given some information that should probably produce a minValue:
Count:3
Minimum: 0 #
Maximum: 75 # DummyDate3 DummyTime3
Average: 45.00
Is this a result of the while loop?
int minValue = 0;
int maxValue = 0;
String minValueTime = "";
String minValueDate = "";
String maxValueDate = "";
String maxValueTime = "";
int count = 0;
double average = 0;
/*
* For as long as input is going through A date, a time, and a value
* will come through as a loop If the minimum value is less than the
* value coming through The minimum value will become the value. If the
* maximum value is less than the value, the maximum value will become
* the value.
*/
while (input.hasNext() == true) {
String date = (input.next());
String time = (input.next());
int value = (input.nextInt());
if (minValue > value) {
minValue = value;
minValueDate = date;
minValueTime = time;
}
if (maxValue < value) {
maxValue = value;
maxValueDate = date;
maxValueTime = time;
}
count++;
average = average + value;
}
input.close();
System.out
.printf("Count:%d%nMinimum: %d # %s %s%nMaximum: %d # %s %s%nAverage: %.2f%n",
count, minValue, minValueDate, minValueTime, maxValue,
maxValueDate, maxValueTime, average / count);
}
EDIT: I have tried Integer.MAX_VALUE and MIN_VALUE, but both of them result in the values of MAX_VALUE and MIN_VALUE, respectively.
The first value assigned to min is 0. If every integer read is bigger than 0, it will never change. What you actually need to do is assing max and min to the minValue and maxValue :
int minValue = Integer.MAX_VALUE;
int maxValue = Integer.MIN_VALUE;
This way, the first value read will most likely be lower than the minimum at the moment and the first value will also be higher than the current max value.
The min value can't go higher than this with those values, the max can't go lower than this too.
The above answer using Integer.MAX_VALUE and Integer.MIN_VALUE works fine, but another technique used frequently if you know the array or input you are looping through has at least one entry is to initialize minValue and maxValue to the first entry.
e.g.
int firstEntry = input.nextInt();
int minValue = firstEntry;
int maxValue = firstEntry;
while (input.hasNext()) {
int currentVal = input.nextInt();
minValue = Math.min(minValue, currentVal);
maxValue = Math.max(maxValue, currentVal);
}
I am new to Java, so I apologize if I am simply overlooking something simple. I wrote this code to make a few simple calculations, but when I run it, Java does not seem to be adding my first integer that is input when calculating the average. Everything else seems to be fine, so I would appreciate any help. Thanks.
import java.util.Scanner;
public class IntegerCalc {
public static void main(String[] args){
System.out.println("Enter a list of non-negative integers.");
System.out.println("Enter a negative number to indicate the end of your input.");
Scanner keyboard = new Scanner(System.in);
int min = keyboard.nextInt();
int max = min;
double average = 0;
double numberOfInt= 1;
int next = keyboard.nextInt();
double total = 0;
while (next > 0){
if (next > max)
max = next;
else if (next < min)
min = next;
total = total + next;
numberOfInt++;
next = keyboard.nextInt();
}
average = total/numberOfInt;
System.out.println("The largest integer is " + max);
System.out.println("The smallest integer is " + min);
System.out.println("The average is " + average);
}
}
It looks like your code does sum all the input numbers, but your numberOfInt is off by one.
You should initialize it to
double numberOfInt= 0;
instead of
double numberOfInt= 1;
You only want to increment numberOfInt when you add the current value of next to the total, so the first time you add next to total, numberOfInt should become 1.
What I can see is that inside while loop you have this condition:
if (next > max)
max = next;
else if (next < min)
min = next;
Your first value never goes to total.Your first value will count towards average is only when value of next is equal to first value.To solve this problem you can initialize total with max or min(since they are equal initially):
double total = (double) max;
your int numberOfInt should not be initialized at value 1. Since you increment it by 1 with each iteration of your loop, it's value is off by one. Instead, initialize it at value 0.
The full assignment was to create a number of methods, e.g. getMode and getAverage, to compute stats for an array with randomly-generated numbers and user-inputted ceiling max, floor min, and sample size. All of my other methods seem to work, but every time I try returning the populated set's min value, I get 0--even if the inputted min was something higher.
Here's my code:
import java.util.Random;
public class Stats extends Main
{
int sampleSize;
double count;
double ave;
double sum;
int mode;
int evenCount;
int oddCount;
int countMatching;
int counter;
int target;
int match;
//Method: return the sample set's max value
public int getMax(int sampleSize, int[] data)
{
int max = Integer.MAX_VALUE;
max = data[0];
for(int i = 0; i < sampleSize; i++)
{
if (data[i] > max)
max = data[i];
}
return max;
}
//Method: return the min value
public int getMin(int sampleSize, int[] data)
{
int min = Integer.MIN_VALUE;
min = data[0];
for(int i = 0; i < sampleSize; i++)
{
if (data[i] < min)
min = data[i];
}
return min;
...
And the main program:
import java.util.Random;
import java.util.Scanner;
public class Main
{
public static void main(String[] args)
{
int stats;
Scanner keyboard = new Scanner(System.in);
System.out.println("Welcome to the Stats Program!");
System.out.println();
System.out.println("Enter sample size: ");
int sampleSize = keyboard.nextInt();
System.out.println();
System.out.println("What is the sample set's minimum? ");
int min = keyboard.nextInt();
System.out.println();
System.out.println("What is the sample set's maximum? ");
int max = keyboard.nextInt();
System.out.println();
Stats g = new Stats();
System.out.println("Main Menu");
System.out.println();
System.out.println("1) Get max value");
System.out.println("2) Get min value");
System.out.println("3) Get the mean");
System.out.println("4) Get the mode");
System.out.println("5) Get the count of even numbers");
System.out.println("6) Get the count of odd numbers");
System.out.println("7) Display the sample set");
System.out.println("8) Return the count of numbers in the sample set that match the input parameter");
System.out.println("9) Exit");
System.out.println();
stats = keyboard.nextInt();
//Constructor: use an RNG to generate sampleSize integers between minValue and maxValue. Store the numbers in an array named 'data'.
int[] data = new int[sampleSize];
for (int i = 0; i < sampleSize; i++)
{
Random rand = new Random();
data[i] = rand.nextInt((max - min + 1) + min);
}
while (stats != 9)
{
if (stats == 1)
{
g.getMax(sampleSize, data);
System.out.println("Max is: " + g.getMax(sampleSize, data));
System.out.println();
}
else if (stats == 2)
{
g.getMin(sampleSize, data);
System.out.println("Min is: " + g.getMin(sampleSize, data));
System.out.println();
}
...
Any idea why my program isn't returning appropriate min values (equal to or above what the user inputs)? The max seems to come out fine--sometimes it's below the user's inputted max, and most often it's equal. I've looked at other questions re. min/max and arrays with random numbers, but haven't been able to apply their solutions to my own problem.
Thanks in advance!
Look at this part of your code:
for (int i = 0; i < sampleSize; i++)
{
Random rand = new Random();
data[i] = rand.nextInt((max - min + 1) + min);
}
First wrong thing is that you create a new random number generator in each iteration. You should create it before the loop and just use it in the loop.
But that's the less important issue. The more important one is the way you run rand.nextInt(). Suppose your min is 3 and your max is 7. Then (max - min + 1) + min gives you 8. And this means you are calling rand.nextInt(8), which will give you a number such that 0 ≤ number < 8.
The method Random.nextInt(int n) gives you back a number such that 0 ≤ number < n. So if you want a number such that 3 ≤ number < 8, you'll need it to give you something between 0 and 5, and add that to 3. This means:
rand.nextInt(max - min + 1) + min;
It looks almost like what you wrote, but the extra pair of parentheses made all the difference. You can't just stick parentheses anywhere. The first parenthesis after the name of a method defines that method's parameters, and in your case, it caused the + min to become part of the parameter to nextInt.
One more thing: your class should not extend Main. They are not related in any way, your Stats is not a kind of Main, right?
Your min method seems to work well, maybe there is no number in your array that is less than 0.
This answer is not exactly to make your actual method work but is just a suggestion for a much easier way to do this.
You could use Collections and Commons Lang to find the min/max of an array and to convert a primitive array to a List.
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.apache.commons.lang.ArrayUtils;
public class tst {
public static void main(String[] args) {
int[] arr = {1, 23, 43, 2, 4, 5, 5, 1, 2, 3};
List lst = Arrays.asList(ArrayUtils.toObject(arr));
System.out.println(Collections.min(lst));
System.out.println(Collections.max(lst));
}
}
This will output min:1 and max:43.
This is a good solution to consider if you are not forced to use primitive arrays and do everything by yourself.
Hope it helps :)
Please change you random nextInt function on how you get the random value.
it should be
data[i] = rand.nextInt(max - min + 1) + min;
not data[i] = rand.nextInt((max - min + 1) + min);
I have a range [min-max]. min and max are of type double. I want to divide this interval into n equal intervals.(n is an integer). How can I achieve this in Java?
For example :
say I have a range [10-50]. and n=4 .
output should be a list of ranges like [10-20] [20-30][30-40] [40-50]
So what you need here is a formula for the limits of the smaller ranges. First lets start off by computing the length of each small range:
// let range be [start, end]
// let the number of smaller ranges be n
double total_length = end - start;
double subrange_length = total_length/n;
After that do a simple cycle for the smaller ranges moving the left end of the current range with the value computed above on each step:
double current_start = start;
for (int i = 0; i < n; ++i) {
System.out.printl("Smaller range: [" + current_start + ", " + (current_start + subrange_length) + "]");
current_start += subrange_length;
}
If have the Range given in the form of an array with two elements (min and max)
double[] range = new double[] {min, max};
int n = 4;
you could try it this way. What you get from divideRange is a two-dimensional array with subranges of the given range, with each of them having the wanted length.
public double[][] divideRange(double[] range, n) {
double[][] ranges = new double[n][2];
double length = (range[1] - range[0])/n;
ranges[0][0] = range[0];
ranges[0][1] = range[0]+length;
for(int i = 1; i < n; i++) {
ranges[i][0] = ranges[i-1][1];
ranges[i][1] = ranges[i-1][1]+length;
}
return ranges;
}
What you can do is use what #Achintya used, double dist = (double)(max-min)/n; Then starting from the min, add dist to it and that is the max of your first interval.
So it'd be something like:
[min, min + dist], [min + dist, min + 2*dist]... until min + n*dist >= max.
int counter = 0;
while(true) {
CreateInterval(min + counter*dist, min + (counter+1)*dist);
if (min+(counter+1)*dist >= max) {
//if we have reached the max, we are done
break;
}
}