matlab代码(这个是我在网上找到的亲测可以运行/平台:matlab2019a):
x=input('输入数据');
alpha=input('输入alpha值(0.01或0.05)');
flag_1=1;
flag_2=0;
%% 计算
while flag_1==1
x=sort(x);
n=length(x);
avg=mean(x);
st=std(x,1);
reg=abs((x-avg)./st);
reg_max=max(reg);
%% 确定g值
T=[1.153 1.463 1.672 1.822 1.938 2.032 2.11 2.176 2.234 2.285 2.331 2.371 2.409 2.443 2.475 2.501 2.532 2.557 2.58 2.603 2.624 2.644 2.663 2.681 2.698 2.714 2.73 2.745;...
1.155 1.492 1.749 1.944 2.097 2.22 2.323 2.41 2.485 2.55 2.607 2.659 2.705 2.747 2.785 2.821 2.954 2.884 2.912 2.939 2.963 2.987 3.009 3.029 3.049 3.068 3.085 3.103];
switch alpha
case 0.05
g=T(1,n);
case 0.01
g=T(2,n);
otherwise
disp('输入了错误的alpha值');
end % 比较确定异常值?
if reg_max>g
flag_2=1;
abn=x(reg>g);
disp('被剔除的数据为')
disp(abn);
x=x(reg<=g);
else flag_1=0;
end
end
if flag_2==0
disp('没有异常数据');
end
C++代码(这是我将matlab代码翻译成C++,同样亲测可用/平台VS2017):
vector Grubb(vectorm, double alpha)//Grubb算法滤除异常值
{
//m[]:输入向量
//alpha: 显著因子
int flag = 1;
//判决table
double T[2][28] = { { 1.153, 1.463, 1.672, 1.822, 1.938, 2.032, 2.11, 2.176, 2.234, 2.285, 2.331, 2.371 ,2.409 ,2.443, 2.475, 2.501, 2.532 ,2.557 ,2.58 ,2.603 ,2.624 ,2.644 ,2.663 ,2.681 ,2.698 ,2.714 ,2.73, 2.745 },
{ 1.155, 1.492, 1.749, 1.944, 2.097, 2.22, 2.323 ,2.41, 2.485, 2.55 ,2.607, 2.659 ,2.705, 2.747, 2.785, 2.821, 2.954 ,2.884 ,2.912, 2.939, 2.963 ,2.987, 3.009 ,3.029, 3.049 ,3.068, 3.085 ,3.103} };
while (flag)
{
double mean = 0.0;
double accum = 0.0;
double stdev = 0.0;
vector reg;
double gate;
sort(m.begin(), m.end());
mean = accumulate(m.begin(), m.end(), 0.0) / m.size();//均值
for_each(m.begin(), m.end(), [&](const double d) {
accum += (d - mean)*(d - mean);
});
stdev = sqrt(accum / (m.size() - 1)); //标准差
for (int i = 0; i < m.size(); i++)
{
reg.push_back(abs(m[i] - mean) / stdev);
}
double reg_max = *max_element(reg.begin(), reg.end());
if (alpha == 0.05)
gate = T[0][m.size() - 1];
else if (alpha == 0.05)
gate = T[1][m.size() - 1];
else
cout << "输入了错误的alpha值" << endl;
if (reg_max > gate)
{
int s = 0;
for (vector::iterator it = m.begin(); it != m.end();)
{
if (reg[distance(m.begin(), it) + s] > gate)
{
it = m.erase(it);
s++;
continue; //删除后it已经指向下一个元素了,所以不能++了,直接continue
}
++it;
}
}
else
flag = 0;
}
return m;
}