第六次作业流数据的标准差NO.2

我们常常会遇到计算一系列数据的标准差的问题。最直接的方法是根据公式

average1

stddev1

进行计算。第一步先计算所有数据的平均值,然后再计算标准差。这个方法需要读取原始数据两次,对于某些情况是不可行的。例如,新的数据在不断的产生,历史数据太多不可能再次读取。这种类型的数据被称为流数据。我们日常生活中的有很多流数据的例子,如股票交易所的股票价格信息,环境温度的监测数据,电信部门的通话记录,网站的点击数据,传感器网络中的监测数据以及网络流量信息等。

traffic

网络流量示意图

对这样的数据进行标准差统计,不能采用需要两次读取原始数据的方法。下面的公式只需要读取原始数据一次,因此也被称为在线算法(on-line algorithm)via

average2

stddev2

更进一步,我们可用如下的算法得到标准差σ的值:

m_1=x_1, m_k=m_{k-1} + (x_k - m_{k-1})/k

s_1=0, s_k=s_{k-1} + ((k-1)/k)(x_k-m_{k-1})^2

\sigma = sqrt(s_N/(N-1))

*Donald E. Knuth (1998). The Art of Computer Programming, volume 2: Seminumerical Algorithms, 3rd edn., p. 232. Boston: Addison-Wesley.

================

本题要求你实现上文最后提到的计算流数据标准差的方法。

输入:

原始的数据,预先不知道个数,double类型。

输出:

输入结束时输出读到的所有数据的标准差,请使用格式化字符串"%8.5f\n"进行输出。

样例输入:

658.19351346.61608

104.76351975.13757

665.75218

样例输出:

333.70903

import java.util.List;
import java.util.ArrayList;
public class Main {
	public static void main(String[] args) {
		List<Double> dataDealList = new ArrayList<Double>();
		while(!StdIn.isEmpty()){
			dataDealList.add(StdIn.readDouble());
		}
		//从输入中对应公式参数
		double mk = dataDealList.get(0);
		double sk = 0.00;
		double k = 1.00;
		for(int i=1;i<dataDealList.size();i++){
			k++;
			sk = sk+((k-1)/k)*(dataDealList.get(i)-mk)*(dataDealList.get(i)-mk);
			mk = mk +(dataDealList.get(i)-mk)/k;			
		}
		double result = Math.sqrt(sk/(k-1));
		StdOut.printf("%8.5f\n", result);
	}
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值