Java: min method for array with random ints and inputted count - java

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);

Related

How to display the min and max elements of an array?

I've been trying to solve this problem for quite some time now. I'm trying to display the min and max elements of an array, but the min always remains at 0. Here's the code that explains my issue:
public class ArrExs {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("enter the array capacity (min 1, max 20): ");
int n = input.nextInt();
while(n <= 0 || n > 20) {
System.out.print("enter a valid number and try again: ");
n = input.nextInt();
}
int[] nums = new int[n];
maxAndMin(nums);
}
public static void maxAndMin(int[] numbers) {
Scanner input = new Scanner(System.in);
System.out.println("enter your array elements: ");
int min = numbers[0];
int max = numbers[0];
for(int i = 0; i < numbers.length; i++) {
numbers[i] = input.nextInt();
max = (numbers[i] > max) ? numbers[i] : max;
min = (numbers[i] < min) ? numbers[i] : min;
}
System.out.print("min = " + min + ", max = " + max);
}
}
The output:
enter the array capacity (min 1, max 20): 3
enter your array elements:
2
3
4
min = 0, max = 4
The min always remains at 0, I've tried to edit the code multiple times but I get the same result.
I've encountered this problem before and watched a video where the instructor's logic is to set the "Min" and "Max" to the first number entered by the user. Then there comes the relational operator to decide which is minimum and maximum.
The problem is on the line where you do int min = numbers[0]; because numbers is an empty array (all of the values are 0). Since min starts at 0 and nothing in the array is less than 0 then min will remain 0 forever.
Try making min start as a high value such as int.MaxValue and see if that fixes your problem.

How to update multiple variables in a loop

I'm a beginner Java student faced with the following question: W"rite a program that inputs an integer that will be the number of times (n) that you will read a random number."
The program is then supposed to calculate the sum and product of those random numbers.
I understand how to generate a random number and I set up a For loop to generate the n random numbers per user input.
import java.util.Scanner;
import java.util.Random;
public class Example {
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
int n;
System.out.println("Enter a number:");
n = input.nextInt();
for (int i = 0; i < n; i++){
double randomNumber = Math.random();
System.out.println(randomNumber);
}
}
}
My first attempt had shoehorned
System.out.println(randomNumber * randomNumber);
System.out.println(randomNumber + randomNumber);
at the bottom of the code which did not work for reasons that are probably obvious to anyone else.
I'm stuck on the concept of storing n random numbers for long enough to do the required arithmetic on them.
You should be able to just maintain some state for the sum and product:
int n = input.nextInt();
double sum = 0d;
double product = 0d;
for (int i=0; i < n; i++) {
double randomNumber = Math.random();
sum += randomNumber;
product = i == 0 ? randomNumber : product*randomNumber;
}
System.out.println("sum = " + sum);
System.out.println("product = " + product);
The line:
product = i == 0 ? randomNumber : product*randomNumber;
is equivalent to:
if (i == 0) {
product = randomNumber;
}
else {
product = product*randomNumber;
}
The version I used is called a ternary expression, and is a concise way of writing if else logic. The idea here is that we want to initialize the product with the first random number. Otherwise, we just multiply the product with the latest random number.

Why does my Java program not produce a fixed number of random numbers?

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);
}
}
}

Mean, Median, Variance calculator

I have created a program that calculates the mean, median, and variance. the program accepts up to 500 inputs. All of my methods work perfectly when there are 500 inputs (max size of my array). When there are less inputs, only the 'mean' calculator works. Here's the entire program:
public class StatsPackage{
static int i = 0, arrayLength;
static double sum = 0, mean, median, sumOfSquares, variance, stdDev;
static double calcMean (int inputs[], int count) throws IOException{
for (i = 0; i < count; i++){
sum += inputs[i];
}
mean = (sum/count);
return mean;
}
static double calcMedian (int inputs[], int count){
Arrays.sort(inputs);
if (count % 2 == 0){
median = ((inputs[(count/2)] + inputs[(count/2)- 1])/2) ;
}
if (count % 2 != 0){
median = inputs[(count-1)/2];
}
return median;
}
static double calcVariance (int inputs[], int count){
sum = 0;
for (i = 0; i < count; i++){
sumOfSquares += (inputs[i]*inputs[i]);
}
for (i = 0; i < count; i++){
sum = sum + inputs[i];
}
variance = ((sumOfSquares/count) - (sum * sum)/(count * count));
return variance;
}
static double calcStdDev (double varianceInput){
stdDev = Math.sqrt(variance);
return stdDev;
}
public static void main(String[] args) throws IOException {
NumberFormat nf = new DecimalFormat("0.##");
nf.setMaximumFractionDigits(2);
nf.setMinimumFractionDigits(2);
BufferedReader stdin = new BufferedReader (new InputStreamReader (System.in));
String str = "test";
int inputs[] = new int [500];
int counter = 0;
int i = 0;
while ((str = stdin.readLine()) != null && i < 500) {
inputs[i] = Integer.parseInt(str);
i++;
counter++;
}
System.out.println("Mean: " + nf.format(StatsPackage.calcMean(inputs, counter)));
System.out.println("Median: " + nf.format(StatsPackage.calcMedian(inputs, counter)));
System.out.println("Variance: " + nf.format(StatsPackage.calcVariance(inputs, counter)));
System.out.println("Standard Deviation: " + nf.format(StatsPackage.calcStdDev(variance)));
}
}
Here is an example output when 10 random numbers are entered:
Mean: 47.90
Median: 0.00
Variance: 0.00
Standard Deviation: 0.00
Here is the same code when 500 numbers are entered (the max size of my array):
Mean: 47.27
Median: 47.00
Variance: 856.71
Standard Deviation: 29.27
These outputs are consistent. I input 10 numbers, and I only get the mean method to work. I input 500 numbers and I get all of them working. I'm running this program against another tester program, not by inputting the numbers myself in eclipse. The tester program is my instructor's and I trust his program is working correctly.
Can anyone please help? I'm about to tear my hair out.
The problem is that you are initializing an array of size 500, but then not using all 500 indices. That means you have an array like:
[2,5,3,7,8,2,......,0,0,0,0,0,0,0,0,0,0,0,0]
So your code is going to calculate the median and std devation with all those 0s. What you should be using is an ArrayList. An ArrayList will expand in size as you add elements, whereas a regular list cannot change size.
If you cannot use an ArrayList, then you have to do a bit more work.
while ((str = stdin.readLine()) != null && i < 500) {
inputs[i] = Integer.parseInt(str);
i++;
counter++;
}
Your counter variable already has the information you need. Now, before passing this array to your mean/median/stddev methods, you need to reduce the size of the array. The easiest way to do this is to use an existing method provided to all arrays, called CopyOf() : CopyOf() method for Arrays
int[] newArray = Arrays.copyOf(inputs, counter);
Now replace your old input array with your new newArray in your method calls:
System.out.println("Mean: " + nf.format(StatsPackage.calcMean(newArray, counter)));
System.out.println("Median: " + nf.format(StatsPackage.calcMedian(newArray, counter)));
System.out.println("Variance: " + nf.format(StatsPackage.calcVariance(newArray, counter)));
System.out.println("Standard Deviation: " + nf.format(StatsPackage.calcStdDev(variance)));
I assume you tested it with random positive integers, as it seems to be the case for these results.
When you input n (where n is small in comparison to 500) positive integers, your array is mostly full of 0's.
As Array.sort sorts the array in-place, calcMedian modifies the actual array passed, placing all these 0's to the front, and the median is, naturally, 0, as all n of them are in the back.
Then calcVariance calculates the variance of the first n 0's, as the array was sorted previously.
Finally, calcStdDev refers to the result of calcVariance.
To fix this, you should consider:
Sorting the array with this method taking a starting and ending indices.
Making a copy of the array before sorting.
Keeping the class stateless - all these methods could take anything required as arguments (while this is not strictly necessary, it will save you a lot of time in the future).
Your method of calculating variance is wrong. Have a look at the definition of the variance (for instance on wikipedia).
import java.util.Arrays;
public class StatisticalCalculations {
public static void main(String[] args) {
double[] array = { 49, 66, 73, 56, 3, 39, 33, 77, 54, 29 };
double mean = getMean(array);
double var = getVariance(array);
double med = getMedian(array);
System.out.println(Arrays.toString(array));
System.out.println("mean : " + mean);
System.out.println("variance : " + var);
System.out.println("median : " + med);
}
private static double getMean(double[] array) {
int l = array.length;
double sum = 0;
for (int i = 0; i < l; i++)
sum += array[i];
return sum / l;
}
private static double getVariance(double[] array) {
double mean = getMean(array);
int l = array.length;
double sum = 0;
for (int i = 0; i < l; i++)
sum += (array[i] - mean) * (array[i] - mean);
return sum / l;
}
private static double getMedian(double[] array) {
int l = array.length;
// copy array to leave original one untouched by sorting
double[] a = new double[l];
for (int i = 0; i < l; i++)
a[i] = array[i];
Arrays.sort(a);
if (l % 2 == 0)
return (a[l / 2 - 1] + a[l / 2]) / 2;
else
return a[(l - 1) / 2];
}
}
Also, you have an issue with your array, as it is fixed size versus a variable size of user inputs. Consider using ArrayList<Double> or something similar as a container for your values to avoid this problem.

Java - Finding even numbers and the percent of them within an array

This is the question that I need to figure out:
Write a method called percentEven that accepts an array of integers as a parameter and returns the percentage of even numbers in the array as a real number. For example, if the array stores the elements [6, 2, 9, 11, 3] then your method should return 40.0. If the array contains no even elements or no elements at all, return 0.0.
Here is what I have so far:
import java.util.*;
public class Change {
public static void main(String[] args) {
Scanner console = new Scanner(System.in);
System.out.println("Let's find the range.");
System.out.println("Enter five numbers to find the range.");
int num = console.nextInt();
int[] list = new int[num];
System.out.println("The numbers you entered are: " + list.length);
System.out.println();
percentEven(list);
}
public static void percentEven(int[] num){
int percent = 0;
int even = 0;
for(int i = 0; i < num.length; i++){
if(num[i] % 2 == 0){
even++;
}
}
percent = (even / num.length) *100;
System.out.println("The percent of even numbers is: " + percent);
}
}
When I run it, I get 100 as the percent.
Two issues here:
Cast one of them to a double or float.
percent = (even / (double) num.length) *100;
The other issue is that you never assign the numbers any value, so they are all 0. 0 % 2 is equal to 0, so the list is, by definition, 100% even.
You should also have a base case in the method when nums == {}, which would return 0.0 as the assignment states.
There are three major problems in your code:
You are reading only ONE integer, not five
You use this single integer to define the LENGTH of the array, not the content (so you don't put the integer into the array. So the array contains only zeroes, which means that all of them are even.
You are doing wrong integer arithmetic (as Obicere already stated in his answer). But this doesn't have any effect, as all elements of the array are even, so the result will be 100 in any case.
You are almost there. But you are initializing and storing the array wrong way. Do this
int num = console.nextInt();
int[] list = new int[num];
System.out.println("Enter " + num + " numbers");
for(int i = 0; i < num; i++) {
list[i] = console.nextInt();
}
System.out.println("The numbers you entered are: " + java.util.Arrays.toString(list));
System.out.println();
and also do as other suggested.
Write
percent = even * 100 / num.length;
Changing the order of the operations will make the integer division business work in your favour - you'll get a value rounded down to the next lowest percentage, rather than rounded down to zero.
Also fix the problem with all the numbers being zero by reading them from the keyboard, as in tintinmj's answer.
import java.util.*;
public class percentEvenClass
{
public static void main(String[] args){
int[] list = {6, 2, 9, 11, 3};
int percentEven_Result = percentEven(list);
System.out.println(percentEven_Result);
}
public static int percentEven(int[] list){
int count = 0;
int percent = 0;
for (int i=0; i<list.length; i++){
if (list[i] % 2 == 0){
count++;
}
percent = (count * 100)/ list.length;
}
return percent;
}
}

Categories