西电期末1002.异常点检测

一.题目

二.分析与思路

根据题目按部就班即可,不难发现西电的题目大多都是以一个简单的背景稍作嵌套命题的,主要考察基础知识点的嵌套,本题先计算平均值,再根据给出的公式计算方差,最后遍历所有数据进行判断。主要考察的点在于数据类型的选择和处理,由于开方和除法的操作,很多变量比如总数,均值,方差都使用了double类型,此外,由于样本个数为整形,还涉及类型转换。

三.代码实现

#include<bits/stdc++.h>//万能头文件
int main()
{
    int n;//个数为整形
    scanf("%d",&n);
    double num[n];//数据为双精度浮点型
    double E_x=0;//期望
    for(int i=0;i<n;i++){
        scanf("%lf",&num[i]);
        E_x+=num[i];
    }//读入数据并累加到期望中
    double n0=n*1.0;//隐式类型转换
    E_x/=n0;//求期望
    double D_x=0;//方差
    for(int i=0;i<n;i++){
        D_x+=(num[i]-E_x)*(num[i]-E_x);
    }//累加到方差中
    D_x/=(n0-1);//按照公式求出方差
    double SD_x=sqrt(D_x);//按照公式的标准差
    int ans=0;//用来储存答案
    for(int i=0;i<n;i++){
        if(num[i]<E_x-3*SD_x||num[i]>E_x+3*SD_x)ans++;
    }//判断是否符合条件
    printf("%.4lf %d",SD_x,ans);//打印答案,注意中间空格隔开,标准差保留4位小数
    return 0;
}

四.评价

其实我一开始用的不是这种方法,在概率论中方差和均值有关系的(高中数学也应该见到过):

 D[X]=E[X^{2}]-E[X]^{2}\\\\

推导如下:

D[X]=E[(X-E[X])^{2}]\\\\ =E[X^{2}-2XE[X]+E[X]^{2}]\\\\ =E[X^{2}]-2E[X]E[X]+E[X]^{2}\\\\ =E[X^{2}]-E[X]^{2}\\

所以代码就是:

#include<bits/stdc++.h>
int main()
{
    int n;
    scanf("%d",&n);
    double num[n];
    double E_x=0;
    double E_x_square=0;
    for(int i=0;i<n;i++){
        scanf("%lf",&num[i]);
        E_x+=num[i];//和
        E_x_square+=num[i]*num[i];//平方和
    }
    double n0=n*1.0;
    E_x/=n0;//E[X]
    E_x_square/=n0;//E[X^2]
    double SD_x=sqrt(E_x_square-E_x*E_x);//公式
    int ans=0;
    for(int i=0;i<n;i++){
        if(num[i]<E_x-3*SD_x||num[i]>E_x+3*SD_x)ans++;
    }
    printf("%.4lf %d",SD_x,ans);
    return 0;
}

但是示例的运行结果不对,我百思不得其解,最后发现题目中给的方差公式分母是n-1,把源代码计算方差的分母的n_{0}-1改成n_{0},得出了和新代码一样的运行结果,我不知道是题目有一些问题还是这题目本身处理时有自己的公式,与纯数学的标准差公式有区别,但是题总归是切掉了,于是我查了一下,发现标准差其实有两种:

题目中叫样本标准差,我们所熟知的叫对象总体标准差,学习一下总归是好的。