Return the amount of numbers below average - java

I am trying to write a program that returns the amount of numbers less than the average
For example, if I have the numbers 2, 3 and 4, the average would be (2.1+3.6+4.2)/3 = 3.3 and since 2.3 is below average it would return 1 as there is one number below the average.
I am getting an error that says
Type mismatch: cannot convert from double[] to int
My code:
public static void main(String[] args) {
double[] numbers = {2.1, 3.6, 4.2};
System.out.println(belowaverage(numbers));
}
public static int belowaverage(double[] ba) {
double sum = 0;
double average = 0;
for(int i = 0;i<ba.length;i++){
sum = sum + ba[i];
average = sum / ba.length;
if(ba[i]<average){
return ba;
}
}

You're trying to return the array ba which is the array holding your input data instead of the count.
You need to leave the computation of the average in your current for loop and then create a second for loop and an int count variable which you will increment each time you find a number in the ba array that is smaller than the average. Then outside of that loop you return count.
Also this line:
average = sum / ba.length;
Has to be outside of the first loop.
#Edit: others provided some code but it had either logical or compile time errors (not all of them I guess, the ones I checked) so here's a working version:
public static int belowaverage(double[] ba) {
double sum = 0;
double average = 0;
int count = 0;
for(int i = 0; i < ba.length; i++) {
sum = sum + ba[i];
}
average = sum / ba.length;
for(int i = 0; i < ba.length; i++){
if (ba[i] < average) {
count++;
}
}
return count;
}
You don't need to cast length to double as sum is of type double so the result will be promoted to the bigger type.

public static void main(String[] args) {
double[] numbers = {2.1, 3.6, 4.2};
System.out.println(belowaverage(numbers));
}
public static int belowaverage(double[] ba) {
double sum = 0;
int length = ba.length;
for (int i = 0; i < length; i++) {
sum += ba[i];
}
double average = sum / length;
int belowAvgCount = 0;
for (int i = 0; i < length; i++) {
if (ba[i] < average) {
belowAvgCount++;
}
}
return belowAvgCount;
}

This isn't going to work using only a single for loop, because you can't possibly compare anything to the average until you've calculated it.
Try separating your calculation of the average and the counting of terms below the average into two different loops:
public static int belowaverage(double[] ba) {
double sum = 0;
double average = 0;
for(double b : ba){
sum += b;
}
average = sum / ba.length;
int count = 0;
for(double b : ba){
if(b < average){
count++;
}
}
return count;
}

You need to work out the sum first, then compute the average and then count how many below this threshold.
try
public static int belowaverage(double[] ba) {
double sum = 0;
double average = 0;
int count = 0;
for(int i = 0;i<ba.length;i++){
sum = sum + ba[i];
}
average = sum / ba.length;
for(int i = 0;i<ba.length;i++){
if (ba[i] < average) count++;
}
return count;
}

Related

Array Index Out of Bounds Exception in 1 of 3 Methods [duplicate]

This question already has answers here:
What causes a java.lang.ArrayIndexOutOfBoundsException and how do I prevent it?
(26 answers)
Closed 6 years ago.
This should be a fairly simple homework assignment, but I've been pounding my face on it for a while now ... When executed, it should just populate an array and find the mean and standard deviation. I'm getting an out of bounds exception, but only in the arrayDeviation method. Any direction would be appreciated.
import java.util.Scanner;
import java.util.Random;
public class StandardDeviation
{
//declare global variables
final static int ELEMENTS = 100;
public static void main(String [] args)
{
//declare variables
final int RANGE = 500;
int[] numList = new int[ELEMENTS];
Random rand = new Random();
//populate array
for(int count = 0; count < ELEMENTS; count++)
{
numList[count] = rand.nextInt(RANGE) + 1;
}
//call printArray
printArray(numList);
//call arrayAverage
double mean = arrayAverage(numList);
System.out.println("\nMean: " + mean);
//call arrayDeviation
double standardDeviation = arrayDeviation(numList, mean);
System.out.print("Standard deviation: " + standardDeviation);
} //end main
//output 10 elements per line
public static void printArray(int[] list)
{
final int ELEMENTS_PER_LINE = 10;
for(int count = 0; count < ELEMENTS; count++)
{
System.out.printf("%-4d", list[count]);
if ((count + 1) % ELEMENTS_PER_LINE == 0)
{
System.out.println();
}
}
}
//returns average as double
public static double arrayAverage(int[] list)
{
int sum = 0, count;
double average;
for(count = 0; count < ELEMENTS; count++)
{
sum = sum + list[count];
}
average =(double) sum / count;
return average;
}
//calculate and return standard deviation
public static double arrayDeviation(int[] list, double mean)
{
double sum = 0.0, standardDeviation;
int count;
for(count = 0; count < ELEMENTS; count++);
{
sum = sum + Math.pow((list[count] - mean), 2);
}
standardDeviation = Math.sqrt(sum / 2);
return standardDeviation;
}
} //end class
Staring at this code for like 10 minutes I couldn't see why it's giving that Exception.Pasting it in Netbeans and it instatly highlights an empty for-loop
public static double arrayDeviation(int[] list, double mean)
{
double sum = 0.0, standardDeviation;
int count;
for(count = 0; count < ELEMENTS; count++); //This semicolon is your
//problem
{
sum = sum + Math.pow((list[count] - mean), 2);
}

Erroneous behaviour of Java 8 Stream.sum()

Today while solving this question on HackerRank I used Array stream .sum() function to sum all the entries and proceeded with my algorithm. But for sum reason I found that my algorithm fails for some cases. I used diff to find out it passes 99% cases and for 1% the output is nearly equal but is less than the original answer. That's why I replaced the stream .sum() with a for loop and unexpectedly it passed all the test cases. I tried but couldn't ascertain this uncertain behaviour.
My implementation using stream.sum() :
public class MandragoraForest {
public static void main(String[] args) {
InputReader in = new InputReader(System.in);
for (int i = in.nextInt(); i > 0; i--) {
int number = in.nextInt();
int[] h = new int[number];
for (int j = 0; j < number; j++) h[j] = in.nextInt();
System.out.println(new MandragoraForestSolver().solve(h));
}
}
}
class MandragoraForestSolver {
public long solve(int[] h) {
if (h.length==1) return h[0];
Arrays.parallelSort(h);
long sum = Arrays.stream(h)
.sum();
long ans = -1;
for (long i=0, strength = 2; i<h.length; i++, strength++) {
sum -= h[(int)i];
ans = Math.max(ans, strength * sum);
}
return ans;
}
}
Implementation without Java stream :
public class MandragoraForest {
public static void main(String[] args) {
InputReader in = new InputReader(System.in);
for (int i = in.nextInt(); i > 0; i--) {
int number = in.nextInt();
int[] h = new int[number];
long sum = 0;
for (int j = 0; j < number; j++) {
h[j] = in.nextInt();
sum += h[j];
}
System.out.println(new MandragoraForestSolver().solve(h, sum));
}
}
}
class MandragoraForestSolver {
public long solve(int[] h, long sum) {
if (h.length==1) return h[0];
Arrays.parallelSort(h);
long ans = -1;
for (long i=0, strength = 2; i<h.length; i++, strength++) {
sum -= h[(int)i];
ans = Math.max(ans, strength * sum);
}
return ans;
}
}
Is there something that I'am missing out ? What could be the reason for this behaviour?
There is one significant difference between using a stream and a loop - the possibility of arithmetic overflow.
Arrays.stream(int[]) returns an IntStream, whose sum() method returns an int result. If the sum exceeds Integer.MAX_VALUE, a silent integer overflow will occur.
However your loop sums by adding int values to a long total, which would not suffer from arithmetic overflow.
The sum of integers in one of the tests must exceed Integer.MAX_VALUE, testing that a long is used to (correctly) calculate the total.
If you want to use a stream to sum, you need to convert the IntStream to a LongStream, which you can do like this:
long sum = Arrays.stream(big).asLongStream().sum();

Why is my code coming out with the wrong output? Is my insert class wrong?

I have to create classes to be implemented with the main class someone else has and for some reason I am not getting the right outputs, I'm not sure is my calculations are off which I don't think they are or my insert class is wrong.
Expected Output:
Median = 44.5
Mean = 49.300
SD = 30.581
Actual Output:
Median = 0.0
Mean = 0.967
SD = 4.712
public class StatPackage {
int count;
double [] scores;
final int MAX = 500;
StatPackage() {
count = 0;
scores = new double[MAX];
}
public void insert (double value) {
if (count < MAX){
scores[count] = value;
++ count;
}
}
public double Mean () {
double sum = 0;
//For loop for calculating average or mean
for(int i = 0; i < scores.length; i++){
sum += (scores[i]);
count++;
}
double average = sum/count;
return average;
}
public double Median() {
int min;
int tmp;
int size;
for (int i = 0; i < scores.length - 1; i ++)
{
min = i;
for (int pos = i + 1; pos < scores.length; pos ++)
if (scores [pos] < scores [min])
min = pos;
tmp = (int)scores [min];
scores [min] = scores [i];
scores [i] = tmp;
}
double median = 0;
if (scores.length % 2 == 0){
median = (scores[scores.length/2-1] + scores[scores.length/2])/2;
}
else {
median = (scores[((scores.length/2))]);
}
return median;
}
public double Variance () {
double variance = 0;
double sum = 0;
//For loop for getting the variance
for(int i = 0; i < scores.length; i++){
sum += scores[i];
variance += scores[i] * scores[i];
count++;
}
double varianceFinal = ((variance/count)-(sum*sum)/(count*count));
return (varianceFinal);
}
public double StdDev (double variance) {
double sum = 0;
for(int i = 0; i < scores.length; i++){
sum += scores[i];
variance += scores[i] * scores[i];
count++;
}
double varianceFinal = ((variance/count)-(sum*sum)/(count*count));
return Math.sqrt(varianceFinal);
}
}
The length of your scores array is 500, so every time you are using it in a calculation you are running that 500 times. You need to make your loop continuation conditions dependent on the number of values in the array, no the actual length of the array. I would be careful of your variable naming as well, you are using count in two places sometimes and it has global scope! This method stores the number of values in the array in the count variable:
public void insert (double value) {
if (count < MAX){
scores[count] = value;
++count;
}
}
So use the count variable as the loop-continuation condition when you are getting values from the array, like so:
public double mean() {
double sum = 0;
//For loop for calculating average or mean
for(int i = 0; i < count; i++){
sum += (scores[i]);
}
double average = sum / count;
return average;
}
That should help a little, I don't have time to check out your other methods but maybe this will give you a good starting place. I figured out what was happening by inserting print statements in your methods to make sure the values were as expected. It's a helpful thing to do when debugging. Your mean() method with the print statements looks like this:
public double mean() {
double sum = 0;
//For loop for calculating average or mean
for(int i = 0; i < count; i++){
sum += (scores[i]);
}
// print statements for debugging
System.out.println("count is " + count);
System.out.println("sum is " + sum);
double average = sum / count;
return average;
}
Because the solution is easily found by debugging, I will only give you a hint:
The mean of 3, 4 and 5 is 4: (3+4+5)/3, not (3+4+5)/(n*3) where
n is a positive integer.
If you look at your mean and std and divide it by the expected result, you will see it's a rounded number.
Once you find the solution to 1 problem, you will immediately know why the other results are faulty as well =)

Passing array to get mean median and mode in java

I am trying to use java to pass an array to get the mean, median,mode , max an min in java. I am currently having an issue passing the array to a function and return its value so i can output the results. I believe i have the loops correct to solve the mean median and mode but i cannot get them to send and receive as wanted. How can I pass the array and send back the values needed?
UPDATE: i have updated the code it will compile and i can input the number of years but i get several errors following after that. it is also not printing the outputs
Exception in thread "main" java.util.UnknownFormatConversionException: Conversion = 'i'
at java.util.Formatter$FormatSpecifier.conversion(Formatter.java:2646)
at java.util.Formatter$FormatSpecifier.(Formatter.java:2675)
at java.util.Formatter.parse(Formatter.java:2528)
at java.util.Formatter.format(Formatter.java:2469)
at java.io.PrintStream.format(PrintStream.java:970)
at java.io.PrintStream.printf(PrintStream.java:871)
at la5cs1110_woodspl_03.pkg17.pkg2016.La5cs1110_WoodsPl_03172016.main(La5cs1110_WoodsPl_03172016.java:56)
Java Result: 1
public static void main(String[] args) {
int i;
List<Double> hArray = new ArrayList<>();
int nYears = 0, y = 0;
double rMax = 0.00,rMin = 100.00;
//get input check if between 1-80
while(y == 0){
String userData = JOptionPane.showInputDialog
("Enter number of years");
nYears = Integer.parseInt(userData);
if (nYears > 1 && nYears <= 80 )
y = 1;
}
y = 0;
while(y <= nYears){
for(i = 0; i < 12; i++){
Random rand = new Random();
double rNum = rand.nextFloat() * (rMax - rMin) + rMin;
hArray.add(rNum);
}
double mean = getMean (hArray);
double median = getMedian (hArray);
double mode = getMode (hArray);
double max = getMaxValue(hArray);
double min = getMinValue (hArray);
System.out.printf("In year %i the Mean = %d , mode = %d, median = %d," +
" max = %d, min = %d", y , mean, median, mode, max, min);
y++;
}
}
private static double getMean(List<Double> hArray) {
double sum = 0;
for (int i = 0; i < hArray.size(); i++) {
sum += hArray.get(i);
}
return sum / hArray.size();
}
//Median
private static double getMedian(List<Double> hArray) {
int middle = hArray.size()/2;
if (hArray.size() %2 == 1) {
return hArray.get(middle);
} else {
return (hArray.get(middle-1) + hArray.get(middle)) / 2.0;
}
}
//Mode
public static double getMode(List<Double> hArray) {
double maxValue = 0, maxCount = 0;
for (int i = 0; i < hArray.size(); ++i) {
int count = 0;
for (int j = 0; j < hArray.size(); ++j) {
if (hArray.get(j) == hArray.get(i)) ++count;
}
if (count > maxCount) {
maxCount = count;
maxValue = hArray.get(i);
}
}
return maxValue;
}
public static double getMaxValue(List<Double> hArray){
double maxValue = hArray.get(0);
for(int i=1;i < hArray.size();i++){
if(hArray.get(i) > maxValue){
maxValue = hArray.get(i);
}
}
return maxValue;
}
public static double getMinValue(List<Double> hArray){
double minValue = hArray.get(0);
for(int i=1;i<hArray.size();i++){
if(hArray.get(i) < minValue){
minValue = hArray.get(i);
}
}
return minValue;
}
}
Your hArray is a List. You should convert it to an array first.
getMean(hArray.toArray)
Check out this.
This does not compile, you try to pass a Double to a method, which expects a double[]. So you have to change the parameter of your methods and use a List and just pass in the hArray (see Tibrogargan answer - i.e., you would have to modify each of your implementations) or do the following:
create a Double[]
Double[] hArray2 = hArray.toArray(new Double[hArray.size()]);
change your methods' signature, so that they expect an Double[]
private static double getMean(Double[] hArray) { ...}
pass hArray2 instead of hArray
double mean = getMean(hArray2);
// ...
That should be it.
Replace the section where you're trying to pass a single element from the array to your statistics functions with calls using the whole array and change the signature of the calls so they take a List<Double> param, not a double[]. Something like this:
double mean = getMean (hArray);
double median = getMedian (hArray);
double mode = getMode (hArray);
double max = getMaxValue(hArray);
double min = getMinValue (hArray);
//Mean
private static double getMean(List<Double> hArray) {
double sum = 0;
for (int i = 0; i < hArray.size(); i++) {
sum += hArray.get(i);
}
return sum / hArray.size();
}
See also: How do you calculate the variance, median, and standard deviation in C++ or Java?
Fix for median:
Copied directly from this above link with some minor modifications to use a List as a param
public Double median(List<Double> list)
{
Double[] array = list.toArray(new Double[list.size()]);
Arrays.sort(data);
if (data.length % 2 == 0)
{
return (data[(data.length / 2) - 1] + data[data.length / 2]) / 2.0;
}
else
{
return data[data.length / 2];
}
}
Fix for mode:
public Double mode(List<Double> list)
{
java.util.TreeMap<Double,Integer> map = new java.util.TreeMap<>();
Double maxVal = null;
int maxCount = 0;
for (Double d : list) {
int count = 0;
if (map.containsKey(d)) {
count = map.get(d) + 1;
} else {
count = 1;
}
map.put(d, count);
if (count > maxCount) {
maxVal = d;
maxCount = count;
}
}
return maxVal;
}

How to find the mean, median, mode, and range from an input file?

I need to find the mean, median, mode, and range from an input file.
[input file has the numbers{60,75,53,49,92,71}]
I don't know how to print the calculations from the range out or calculate the mode.
It's pretty bad, I'm very new to Java.
It would be great if anyone could help me with it.
import java.io.*;
import java.util.*;
public class grades {
public static double avg(double[] num) {
double total = 0;
int j = 0;
for (; j < num.length; j++) {
total += num[j];
}
return (total / j);
}
public double getRange(double[] numberList) {
double initMin = numberList[0];
double initMax = numberList[0];
for (int i = 1; i <= numberList.length; i++) {
if (numberList[i] < initMin) initMin = numberList[i];
if (numberList[i] > initMax) initMax = numberList[i];
double range = initMax - initMin;
}
return range;
}
public static void main(String[] args) throws IOException {
double[] num = new double[12];
File inFile = new File("data.txt");
Scanner in = new Scanner(inFile);
for (int i = 0; i < num.length && in.hasNext(); i++) {
num[i] = in.nextDouble();
// System.out.println(num[i]);
}
double avg = grades.avg(num);
System.out.println("Arithmetic Mean = " + avg);
System.out.printf("Median = %.2f%n", grades.getMedian(num));
System.out.println("Range = " + range);
}
public static double getMedian(double[] num) {
int pos = (int) num.length / 2;
return num[pos];
}
}
I don't know how to print the calculations from the range out or calculate the mode.
You have already written a function to calculate the Range. Here is how you can print the Range.
System.out.println("Range = " + getRange(num));
Here is a quick code snippet to calculate the Mode:
public static double calculateMode(final double[] numberList) {
double[] cnts = new double[numberList.length];
double mode = 0, max = 0;
for (int i = 0; i < numberList.length; i++) {
/* Update Count Counter */
cnts[numberList[i]]++;
/* Check */
if (max < cnts[numberList[i]]) {
/* Update Max */
max = cnts[numberList[i]];
/* Update Mode */
mode = numberList[i];
}
}
/* Return Result */
return mode;
}
try sorting the element into an array.it will give following results:
[49,53,60,71,75,92]
suppose you stored it in array A.
int arrLength=A.length();
for(i=0,sum=0;i<arrlength;i++)
sum=sum+A[i]
mean=sum/arrLength;
median=A[arrLength/2]
I think you didn't sort the elements before finding median.
Do same thing to calculate range.It will be easier , I feel

Categories

Resources