Finding standard deviation - java

I cant seem to figure out how exactly to find the standard deviation using what i have. the thing that is confusing me is really the whole standard deviation equation and how to exactly put it into code.
import java. util.Scanner;
public class StandardDeviation
{
public static void main (String[] args)
{
int array;
float sum = 0;
float mean;
Scanner scan = new Scanner(System.in);
System.out.println("Enter wanted array length:");
array = scan.nextInt();
float[] numbers = new float[array];
System.out.println("The size of the array: " + numbers.length);
for (int index = 0; index < numbers.length; index++)
{
System.out.print("Enter number " + (index+1) + ": ");
numbers[index] = scan.nextFloat();
}
for (float i : numbers)
{
sum += i;
}
mean = sum/numbers.length;
System.out.println("The mean is: " + mean);
}
}

You already have the mean, which is the first step in finding the standard deviation.
First, you loop through your array of numbers. You subtract the number from the mean, then square the answer. Add the squared answers together.
Next, divide your squared answer sum by the length of your array of numbers, minus 1.
Finally, take the square root of the result of the last step.
Sum (x - mean) * (x - mean)
Sum from step 1. / (length - 1)
Square root of the result from step 2.
Math.pow(number, 0.5D) gives you the square root of a double.

Related

Exception in thread "main" java.lang.IndexOutOfBoundsException: [duplicate]

This question already has answers here:
sublist index out of bound exception
(3 answers)
Closed 4 years ago.
The program uses methods to:
get the numbers used to calculate the average,
get the number of lowest numbers to drop before calculating the
get the weight, a double greater than 0 and less than or equal to 1,
calculate the weighted average of the numbers (except the lowest n numbers) entered by the user, and
print the results.
The first method should take no arguments and return an array list of doubles.
The second method should take no arguments and return a single integer, the number of the lowest numbers to drop before calculating the average.
The third method should take no arguments and return a double (the weight)
The fourth method should take three arguments: an array list of numbers (the return value of the first method above); an integer (the number of smallest items to drop before calculating the average); and a double (the weight). This method should return a double (the weighted average of all the numbers except the lowest n values).
The fifth method should take four arguments: an array list of numbers (the return value of the first method above); an integer (the number of smallest numbers to drop before calculating the average); a double (the weight); and a double (the weighted average returned from the fourth method above). This method should have no return value.
For example:
If the user gives these numbers for calculating the average:
40 60 80 100 20
and the user gives the number 2 to indicate how many of the lowest values should be dropped before calculating the average, and gives a weight of 0.5, then the program should give as output:
The weighted average of the numbers is 40.0, when using the data 40.0, 60.0, 80.0, 100.0, 20.0, where 0.5 is the weight used, and the average is computed after dropping the lowest 2 values.
import java.util.*;
import java.lang.*;
import java.util.ArrayList;
import java.util.Collections;
public class MyClass
{
public static ArrayList<Double> getALInfo()
{
Scanner in=new Scanner(System.in);
ArrayList<Double> inputs = new ArrayList<>();
System.out.println("Please enter 5 - 10 integers, Q to quit: ");
String [] tokens = in.nextLine().split("\\s");
for (int i = 0; i < tokens.length; i++)
inputs.add(Double.parseDouble(tokens[i]));
return inputs;
}
public static int getLowestnum()
{
int lowNum = 0;
System.out.println("How many of the lowest values should be dropped? ");
Scanner in = new Scanner(System.in);
lowNum = in.nextInt();
return lowNum;
}
public static double weight()
{
Scanner in = new Scanner(System.in);
System.out.println("Enter the weight: ");
double weight = in.nextDouble();
return weight;
}
public static double calculateAvg(ArrayList<Double> inputs,double weight, int lowNum)
{
double sum = 0;
double average = 0;
Collections.sort(inputs);
ArrayList<Double> inputs1 = new ArrayList<Double>(inputs.subList(lowNum, inputs.size()+1));
for (int i = 0; i < inputs1.size(); i++)
{
if (inputs1.get(i) > lowNum)
{
sum = sum + inputs.get(i);
}
}
sum=weight*sum;
average = (sum / inputs1.size());
return average;
}
public static void getAvg(ArrayList<Double> inputs,int n,double weight, double average)
{
System.out.println("The weighted average of the numbers is " + average + ", when using the data " + inputs + " where " +weight+ " is the weight used, and the average is computed after dropping the lowest " +n+" values");
}
public static void main(String args[])
{
int lowNum = 0;
double average;
double weight=0;
ArrayList<Double> inputs= getALInfo();
lowNum = getLowestnum();
weight=weight();
average = calculateAvg(inputs,weight, lowNum);
getAvg(inputs, lowNum,weight, average);
}
}
The program is running fine util you enter the weight after that it shows an array out of bounds exception error. Can you point out where im going wrong .
The error comes from new ArrayList<Double>(inputs.subList(lowNum, inputs.size()+1))
Because you try to reach, as end index, the last element +1 so it does not exists
Solve :
new ArrayList<Double>(inputs.subList(lowNum, inputs.size()))
!! Also, your for loop is wrong
don't need to check with this strange if
you don't pick up from the correct list : use better names
for (int i = 0; i < inputs1.size(); i++) {
if (inputs1.get(i) > lowNum) {
sum = sum + inputs.get(i);
}
}
Solve
ArrayList<Double> subList = new ArrayList<>(inputs.subList(lowNum, inputs.size()));
for (int i = 0; i < subList.size(); i++) {
sum = sum + inputs.get(i);
}

How to average random numbers in java?

thanks in advance for any help I'm in an intro to java class and our home work was to generate 10 random numbers between 1&50 which I got and then average the generated numbers. I can't figure out how to average them here's what I have. Is there a way to store each random number as a variable?
public class randomNumberGen
{
public static void main(String [] args)
{
Random r=new Random();
for (int i=1;i<=10;i++){
System.out.println(r.nextInt(50));
System.out.println();
int average = (i/4);
System.out.println("your average is"+average);
}
}
}
use streams with java 8
final int numberOfRandom = 10;
final int min = 0;
final int max = 50;
final Random random = new Random();
System.out.println("The ave is: "+random.ints(min, max).limit(numberOfRandom).average());
First of all you have to replace "r.nextInt(50)" for "r.nextInt(50) + 1" because r.nextInt(n) returns a number between 0 (inclusive) and n (exclusive). Then, you know that an average is just a sum of n values divided by n. What you can do is just declare a "total" variable initialized to 0 before the loop. On each iteration you add to this variable the random value generated by r.nextInt(50). After the loop you can just divide the total by 10 so you get the average.
PS: it's a good practice to don't use "magic numbers", so it would be perfect (and luckily your teacher will have it in count) if you declare a constant for the number of iterations and then use it both in the loop condition and in the average calculation. Like this, if you have to make it for 100 numbers you only have to change the constant value from 10 to 100 instead of replacing two 10's por two 100's. Also this gives you the chance to give semantic value to these numbers, because now they will be "AMOUNT_OF_NUMBERS = 10" instead of just "10".
Like every average, it's sum of elements / amount of elements. So let's apply it here:
import java.util.Random;
public class randomNumberGen
{
public static void main(String [] args)
{
Random r=new Random();
double sum = 0; // is double so to prevent int division later on
int amount = 10;
int upperBound = 50;
for (int i = 0; i < amount; i++){
int next = r.nextInt(upperBound) + 1; // creates a random int in [1,50]
System.out.println(next);
sum += next; // accumulate sum of all random numbers
}
System.out.println("Your average is: " + (sum/amount));
}
}
Store variables outside of the loop to store both the total amount of numbers generated as well as the sum of those numbers. After the loop completes, divide the sum by the total amount of numbers.
public static void main(String [] args)
{
Random r=new Random();
double sum = 0;
int totalNums;
for (totalNums=1;totalNums<=10;totalNums++){
int randomNum = r.nextInt(50);
sum += randomNum;
System.out.println(randomNum);
}
double average = sum/totalNums;
System.out.println("your average is: "+average);
}
Average = Sum of numbers / amount of numbers
int sum = 0;
for (int i=1;i<=10;i++){
sum += r.nextInt(50) +1; //nextInt 50 produces value 0 to 49 so you add 1 to get 1 to 50 OR as suggested in the comments sum/10d
}
System.out.println("Average is: " + sum/10) // If you want the result in double (with decimals) just write sum*1.0/10
You could also do the same with a while loop.
int i = 0;
int sum = 0;
while(i < 10){
sum += r.nextInt(50) +1;
i++;
}
System.out.println("Average is: " + sum*1.0/i);
Or even shorter with lambda expressions: (/java 8 streams)
OptionalDouble average = IntStream.range(1, 10).map(x-> x = r.nextInt(50) +1).average();
System.out.println("Average is "+ average.getAsDouble());
.map(x-> x = r.nextInt(50) +1) // maps (changes) each value from 1 to 10 to a random number between 1 and 50
.average(); // calculates the average.
Simply create a variable sum starting at zero that you increment at each iteration. After the loop, simply divide by the number of elements..
Average means you should add everything up and devide it by the number of elements (50).
import java.util.Random;
class Homework {
public static final Random RANDOM = Random(); // never regenerate randoms
public static void main(String args[]) {
final int N = 50;
int sum = 0;
for (int i = 0; i < N; ++i) {
sum += RANDOM.nextInt(50)+1;
}
System.out.println("Avg: "+ sum / (float) N);
}
}
This should do the trick. Try to learn from it not just C+P.
Ps: Friggin annoying to write code on a phone.

Mathematical riddle - how to solve numerically in Java?

So the riddle is:
John has written down k sequential odd numbers: n{1}, n{2}, ..., n{k-1}, n{k} (where n{2} = n{1} + 2 and so on). We know that:
The sum of the first four numbers is a fourth power of some prime number (so n{1} + n{2} + n{3} + n{4} = p{1} where p{1}^4 is a prime number.
The sum of the last five numbers is a fourth power of some prime number (so n{k} + n{k-1} + n{k-2} + n{k-3} + n{k-4}= p{2}^4 where p{1} is a prime number.
The question is - how many numbers have been written down (k=?).
Below is my attempt to solve it in Java:
import java.math.BigInteger;
import java.util.Set;
//precalculate prime numbers
public class PrimeSieve {
public static boolean[] calculateIntegers(int N) {
// initially assume all integers are prime
boolean[] isPrime = new boolean[N + 1];
for (int i = 2; i <= N; i++) {
isPrime[i] = true;
}
// mark non-primes <= N using Sieve of Eratosthenes
for (int i = 2; i*i <= N; i++) {
// if i is prime, then mark multiples of i as nonprime
// suffices to consider mutiples i, i+1, ..., N/i
if (isPrime[i]) {
for (int j = i; i*j <= N; j++) {
isPrime[i*j] = false;
}
}
}
return isPrime;
}
}
The solving class:
public class Solver {
static boolean[] isPrime = PrimeSieve.calculateIntegers(100000);
public static void main(String[] args) {
int minNumberCount = 5;
int maxNumberCount = 2000;
int startInt = 2;
int endInt = 1000000;
for (int numberCount = minNumberCount; numberCount < maxNumberCount+1; numberCount++) {
System.out.println("Analyzing for " + numberCount + " numbers");
int[] numbers = new int[numberCount];
//loop through number sets
for (int firstNum = startInt; firstNum < endInt; firstNum+=2) {
//populate numbers array
for(int j=0; j<numberCount; j++){
numbers[j] = firstNum + j*2;
}
long bottomSum=0;
long topSum=0;
//calculate bottom sum
for(int iter=0; iter<4; iter++){
bottomSum+=numbers[iter];
}
//calculate top sum
for(int iter=numberCount-1; iter>numberCount-6; iter--){
topSum+=numbers[iter];
}
//check if the sums match the sulution criteria
if(checkPrime(quadRoot(bottomSum)) && checkPrime(quadRoot(topSum))){
System.out.println("SOLUTION!");
for (int i = 0; i < numbers.length; i++) {
System.out.print(numbers[i] + " ");
}
System.exit(0);
}
}
}
}
private static boolean checkPrime(int i){
return isPrime[i];
}
private static boolean checkPrime(double i){
return ((i % 1) == 0) && checkPrime((int) i);
}
private static double quadRoot(long n){
return Math.sqrt(Math.sqrt(n));
}
}
Using this algorithm with the assumed parameters (max k=2000, max n{1}=100000) - I've found no solution. My question is: are the parameter assumptions wrong (no solution in this range), or do I have some algorithmic/numeric error and that is the reason I've found no solution?
EDIT: sorry - my mistake - it should be ODD instead of EVEN.
It is still easier to solve this directly than to write a program.
The first sum is even so it must be 16 (since 2 is the only even prime). The first four numbers are therefore 1,3,5,7.
The sum of five consecutive odd numbers is 5 times the middle number hence must be divisible by 5. Since it is a fourth power of a prime it must be 625 and the last five numbers are therefore 121,123,125,127,129
It is now an easy task to determine k=65
As said in the comments, your riddle has no solution.
Let's suppose there was a solution, then n1 + n2 + n3 + n4 == p1^4 . We know that n1,n2,n3,n4 are even from the definition of the riddle and therefore as a sum of even numbers, n1 + n2 + n3 + n4 is even as well. This leads us to the fact that p1^4 is even. We know that a multiplication of two odd numbers results only an odd number, hence p1^4 = p1 * p1 * p1 * p1 means that p1 must be an even number. However, p1 is prime. The only prime number which is also even is 2. It's easy to see that there are no four consecutive even numbers that sum up to 16 and therefore p1 is not prime. This contradicts the assumption that p1 is a prime, hence, no solution.
If there are only even numbers, the sum of those is an even number. If I understood correctly, your sum has to be the result of the fourth power of a prime number. Considering the sum is an even number, the only number to satisfy your condition is 16 (2*2*2*2), where 2 is a prime number, so your sum of 4 even number has to be 16. Now, if you're certain there's a sequence, then the sum is computed by adding the first and the last number in the sequence, then multiplying the result with the number of elements in the sequence, and dividing the result of the multiplication by 2. For example, 2+4+6+8=(2+8)*4/2=10*4/2=20. Similarly, for your example, n{1}+n{2}+...+n{k}=(n{1}+n{k})*k/2
On a side note, your smallest sum of 4 even numbers (20), the example I used, is already above your only 4th power of the prime number (16), so yes, there is no valid example in your sequence.
I hope this made some sense

Adding and finding the average in an array

I"m trying to make a program that retrieves an endless amount of numbers that user inputs, and then it tells you how many numbers that you inputted, the sum of all the numbers, and then the average of the numbers. Here is the code I have so far. I don't know why it does not work. I get no errors, but it just does not get a valid sum or average.
import javax.swing.*;
public class SumAverage {
public static float sum;
public static float averageCalculator;
public static float average;
public static void main(String[]args) {
float numbers[] = null;
String userInput = JOptionPane.showInputDialog(null, "Ready to begin?");
if(userInput.equalsIgnoreCase("no"))
{
System.exit(0);
}
for(int i = 0; i != -2; i++)
{
numbers = new float[i + 1];
userInput = JOptionPane.showInputDialog(null, "Input any number. Input * to exit");
if(userInput.length() == 0 || userInput.equals("*") || userInput.equals(null))
{
break;
}
else
{
numbers[i] = Float.parseFloat(userInput);
}
}
for (int i = 0; i < numbers.length; i++)
{
sum += numbers[i];
}
average = sum / numbers.length;
JOptionPane.showMessageDialog(null, "The sum of all your numbers is " + sum + ". The average is " + average + ". You entered a total of " + numbers.length + " numbers.");
}
}
The problem is in this line:
numbers = new float[i + 1];
You are creating a new array, but you aren't copying the values from the previous array assigned to numbers into it.
You can fix this in two ways:
copy the values using System.arraycopy() (you'll need to use a new variable to make the call then assign it to numbers)
Don't use arrays! Use a List<Float> instead, which automatically grows in size
In general, arrays are to be avoided, especially for "application logic". Try to always use collections - they have many powerful and convenient methods.
If you wanted to store the numbers for later use, try making your code look like this:
List<Float> numbers = new ArrayList<Float>();
...
numbers.add(Float.parseFloat(userInput));
...
for (float n : numbers) {
sum += n;
}
average = sum / numbers.size(); // Note: Don't even need a count variable
And finally, if you don't need to store the numbers, just keep a running sum and count and avoid any kind of number storage.
Unrelated to the Q, but note also you can compute a running count/average without storing all the input data - or assuming you want to keep the input - without traversing over it each iteration. Pseudocode:
count = 0
sum = 0
while value = getUserInput():
count++
sum += value
print "average:" + (sum / count)
with
numbers = new float[i + 1];
you are creating a whole new array on every iteration. That means you are always creating a new array that will increase its size by 1 on each iteration but only having one field filled with the current user input and having all the other fields been empty.
Delete this line and initialize the array before.
If the size of the array should grow dynamically within the loop
do not use an array at all and use a dynamic data structure like a List or an ArrayList instead.
Further i would suggest to use
while (true) {
//...
}
to realize an infinite loop.

Possible loss of precision error Java

Quick question, I found answers close to this but nothing that helps me. I want it to print out a percentage at the end of the code that has 4 numbers after the decimal point, and of course, using an int work work. But using floats gives me an error.
This code:
import java.util.Scanner;
public class HW2johnson_pp4 {
public static void main(String args[]) {
Scanner keyboard = new Scanner(System.in);
System.out.printf("How many numbers will you enter?\n");
float[] numbers = new float[keyboard.nextFloat()];
System.out.printf("Enter " + numbers.length + " integers, one per line:\n");
for (int i = 0; i <= numbers.length - 1; i++) {
numbers[i] = keyboard.nextInt();
}
float sum = 0;
for (int i = 0; i <= numbers.length - 1; i++) {
sum += numbers[i];
}
System.out.printf("The sum is " + sum + "\n");
System.out.printf("The numbers are:\n");
for (int i = 0; i <= numbers.length - 1; i++) {
float perc = (numbers[i] / sum);
float perct = (perc * 100);
System.out.printf(numbers[i] + " which is " + perct + "%% of the sum.\n");
}
}
}
Gives the error:
HW2johnson_pp4.java:8: possible loss of precision
found : float
required: int
float[] numbers = new float[keyboard.nextFloat()];
You can't create an array of floats whose length is a floating-point value. That is to say, you can't have an array with 2.7 elements.
So the float within the length parameter is getting rounded, causing a loss of precision.
You wanted keyboard.nextInt() there on line 8, and keyboard.nextFloat() below on line 13.
You cannot initialize an array with floating point values.
float[] a = new float[4]
And not
float[] a = new float[4.0]
So, The problem is here:
float[] numbers = new float[keyboard.nextFloat()];
Use keyboard.nextInt() instead.
You're using keyboard.nextFloat(), which is a float, as the length of the array numbers. The length of an array has to be an int.
Thats because in line 8 you are making a new array, and passing a float as the length. Since all arrays require an integer as an array length, it will convert the float to an integer, and gives an error. You want to pass in an integer value.

Categories

Resources