2
import java.util.ArrayList;

public class Variance {
// Copy here sum from exercise 63 
public static int sum(ArrayList<Integer> list) {
    int sum = 0;        
    for(int i=0; i<list.size(); i++ ){
        sum = sum + list.get(i) ;
    }
    return sum;
}

// Copy here average from exercise 64 
public static double average(ArrayList<Integer> list) {  
    double average = sum(list)/list.size();
    return average;
}

public static double variance(ArrayList<Integer> list) {
    // write code here
   double sumMinusAverage = sum(list) - average(list);
   return sumMinusAverage * sumMinusAverage / (list.size()-1);
}

public static void main(String[] args) {
    ArrayList<Integer> list = new ArrayList<Integer>();
    list.add(3);
    list.add(2);
    list.add(7);
    list.add(2);

    System.out.println("The variance is: " + variance(list));

}

}

The program is calculating variance. But when when the list contains the same numbers etc 1-s. The program says the variance is 3, but the answer should be 0.

Can someone give me some direction.

Mike Schwartz
  • 2,182
  • 1
  • 17
  • 26
UkoM
  • 305
  • 2
  • 6
  • 17

2 Answers2

5

The integer division Luiggi Mendoza has already mentioned is a problem you need to fix, but additionally, your algorithm for computing the variance is not correct. It's not the square of the difference between the sum and the average in the numerator.

You must sum up the differences of the individual elements from the average. Dividing by (list.size() - 1) is correct for the sample variance.

public static double variance(ArrayList<Integer> list) {
   double sumDiffsSquared = 0.0;
   double avg = average(list);
   for (int value : list)
   {
       double diff = value - avg;
       diff *= diff;
       sumDiffsSquared += diff;
   }
   return sumDiffsSquared  / (list.size()-1);
}

Be careful when there is only one item in the list. The variance should be 0, but you'll need to check the size to avoid a divide-by-zero exception.

Also, if you ever want the population variance, divide by list.size() instead.

rgettman
  • 176,041
  • 30
  • 275
  • 357
0

The problem is here:

double average = sum(list)/list.size();

sum(ArrayList<Integer>) returns an int, and sum(list)/list.size() is an integer division, so you'll get an int as result. The decimal part of the division will be truncated.

In order to fix this, you should cast one of the operands of the division to double:

double average = ((double)sum(list))/list.size();

Similar in variance method.


This is unrelated to the main problem, but you should code oriented to interfaces, not to direct class implementations. This means, declare your variables and parameters as List<Integer> instead of ArrayList<Integer>. Here's an example:

public static int sum(List<Integer> list) {
    int sum = 0;        
    for(int i=0; i<list.size(); i++ ){
        sum = sum + list.get(i) ;
    }
    return sum;
}

//...

List<Integer> list = new ArrayList<Integer>();
Community
  • 1
  • 1
Luiggi Mendoza
  • 85,076
  • 16
  • 154
  • 332
  • double sumMinusAverage = ((double)sum(list)) - average(list); this still gives the wrong answer, if u meant that? – UkoM Oct 23 '14 at 16:35