《算法竞赛入门经典》(第2版) 第三章思考题
题目1(必要的存储量)
数组可以用来保存很多数据,但在一些情况下,并不需要把数据保存下来。下面哪些题目可以不借助数组,哪些必须借助数组?请编程实现。假设输入只能读一遍。 1. 输入一些数,统计个数。 2. 输入一些数,求最大值、最小值和平均数。 3. 输入一些数,哪两个数最接近。 4. 输入一些数,求第二大的值。 5. 输入一些数,求它们的方差。 6. 输入一些数,统计不超过平均数的个数。
这里1~4、6题可以参见这篇博文:传 送 门
这里就5题的算法思想进行分析,并做简单的优化处理。。。。
引用传 送 门的代码(数组):
void variance() //第五题 { int nums[100]; int ct = 0, n, i; double ave = 0.0, sum = 0.0, psum = 0.0; while(1 == scanf("%d", &n)) { nums[ct++] = n; sum += n; } ave = sum / ct; for(i = 0; i < ct; ++i) psum += (nums[i] - ave) * (nums[i] - ave); printf("variance: %.3f ", psum / ct); }
分析:
由于要求的是输入一组数据的平方差,第一印象感觉就会想到用数组,但是我们把平方差公式写出进行分解来就会发现,并非非要用数组不可。
方差公式:
分解步骤:
S2 = .........这里编辑数学公式太麻烦了。。。。。
分解图:
代码实现(非数组):
double inVariance() { double x; double s1 = 0; double s2 = 0; double s3 = 0; double avg = 0; int n = 0; while(cin >> x) { n++; s2 += x; s1 += x*x; } avg = s2/n; s2 = 2*avg*s2; s3 = n*avg*avg; return (s1 - s2 + s3)/n; }