2
\$\begingroup\$

(See the previous iteration.)

Now all operations of the data structure work in exact constant time, yet it came with the price: the state of this set maybe non-sensical. A user may end up with the set with negative number of elements in it. Basically, the client programmer must keep track of how he/she work with this set.

StatisticsNumberSet.java

package net.coderodde.stat;
/**
 * This class provides the means for rapid statistics queries.
 * 
 * @author Rodion "rodde" Efremov
 * @version 1.618 (Mar 28, 2017)
 */
public class StatisticsNumberSet {
 /**
 * Holds the sum of all elements in this set.
 */
 private double sum;
 /**
 * Holds the sum of square of each element in this set.
 */
 private double squareSum;
 /**
 * Holds the number of elements currently in this set.
 */
 private int size;
 /**
 * Adds the given number to this set.
 * 
 * @param number the number to add.
 */
 public void add(double number) {
 checkNumberIsFinite(number);
 sum += number;
 squareSum += number * number;
 size++;
 }
 /**
 * Converts and adds the given number to this set.
 * 
 * @param number the number to add.
 */
 public void add(Number number) {
 add(number.doubleValue());
 }
 /**
 * Removes the given number from this set.
 * 
 * @param number the number to remove.
 */
 public void remove(double number) {
 checkNumberIsFinite(number);
 sum -= number;
 squareSum -= number * number;
 size--;
 }
 /**
 * Converts and removes the given number from this set.
 * 
 * @param number the number to remove.
 */
 public void remove(Number number) {
 remove(number.doubleValue());
 }
 /**
 * Resets the state of this set to an empty set.
 */
 public void clear() {
 sum = 0.0;
 squareSum = 0.0;
 size = 0;
 }
 /**
 * Returns the number of elements in this set.
 * 
 * @return the size of this set.
 */
 public int size() {
 return size;
 }
 /**
 * Computes the average of this set.
 * 
 * @return the average.
 */
 public double getAverage() {
 return sum / size;
 }
 /**
 * Computes the variance of this set.
 * 
 * @return the variance. 
 */
 public double getVariance() {
 double step1 = squareSum - sum * sum / size;
 return step1 / (size - 1);
 }
 /**
 * Computes the standard deviation of this set.
 * 
 * @return the standard deviation.
 */
 public strictfp double getStandardDeviation() {
 return Math.sqrt(getVariance());
 }
 /**
 * Returns the textual representation of the state of this set.
 * 
 * @return the textual representation.
 */
 @Override
 public String toString() {
 return "[Size = " + size + ", average = " + getAverage() +
 ", s.d. = " + getStandardDeviation() + ", variance = " + 
 getVariance() + "]";
 }
 public static void main(String[] args) {
 StatisticsNumberSet set = new StatisticsNumberSet();
 set.add(1);
 set.add(1.0f);
 set.add((byte) 3);
 System.out.println(set);
 set.remove(1.0f);
 System.out.println(set);
 set.clear();
 System.out.println(set);
 }
 private void checkNumberIsFinite(double number) {
 if (Double.isNaN(number)) {
 throw new IllegalArgumentException("number is NaN");
 }
 if (Double.isInfinite(number)) {
 throw new IllegalArgumentException("number is +Inf or -Inf");
 }
 }
}

As always, any critique is much appreciated.

asked Mar 28, 2017 at 13:28
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

This is not a Set. A Set contains no duplicate elements. You should rename the class, perhaps to a Bag or a MultiSet.

I'm also worried about this bit:

/**
 * Computes the variance of this set.
 * 
 * @return the variance. 
 */
public double getVariance() {
 double step1 = squareSum - sum * sum / size;
 return step1 / (size - 1);
}
/**
 * Computes the standard deviation of this set.
 * 
 * @return the standard deviation.
 */
public strictfp double getStandardDeviation() {
 return Math.sqrt(getVariance());
}

Either strictfp cascades, and you calculate the variance twice, but in different ways for toString(), or it doesn't, and in that case, no math is being done in this method and the keyword can go.

answered Mar 28, 2017 at 15:17
\$\endgroup\$
2
  • \$\begingroup\$ Oops, strictfp was not intended to make it to the post: JVM does not seem to throw exception whenever dividing by (double) zero, so I thought to try strictfp. \$\endgroup\$ Commented Mar 28, 2017 at 15:32
  • \$\begingroup\$ @coderodde the not throwing exception part is part of the IEEE standard, I believe. \$\endgroup\$ Commented Mar 28, 2017 at 15:42

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.