最近我做了一项测试任务,其中有必要计算中位数和其他内容。我写了下一个功能
function quartile(n) {
var observation = n * (len + 1) / 4 - 1;
if (n * (len + 1) % 4 === 0) {
return sortedSet[observation];
} else {
return Math.round((sortedSet[Math.floor(observation)] + (observation - Math.floor(observation)) *
(sortedSet[Math.ceil(observation)] - sortedSet[Math.floor(observation)])) * 10e3) / 10e3;
}
}
在反馈中,我得到了以错误方式计算的中位数。现在我无法弄清楚这个函数在哪些情况下会表现不正确。你能解释一下这里有什么问题吗?
P.S像这样使用quartile(2)
只需排序
我发现了问题所在。我使用了array.sort()并且不知道以非自然顺序排序。
答案 0 :(得分:1)
嗯,你的等式错了,你的情况也是如此。
对于第1和第3个四分位数,您的观察计算偏差为0.5,而对于0和4,您的观察计算结果为1。
而且您的状况最好是if(observation%1 === 0)
或if(observation === Math.floor(observation))
这里有一个固定版本,并且如评论中所述,格式化/舍入浮动不是此功能的作用。
function quartile(n) {
//compute the position in the Array you want to fetch
//n==0 return the first, n == 4 returns the last item in the Array
var pos = n/4 * (len-1),
//separate the index ...
i = Math.floor(pos),
//and the fractional part
t = pos - i;
return t? //if there is a fractional part
//interpolate between the computed and the next index
(1-t) * sortedSet[i] + t * sortedSet[i+1]:
//otherwise return the value at the computed index
sortedSet[i];
}
修改强>
我看了wikipedia on that topic。上帝,这是一种奇怪的,递归的,非现实的数学方法。更糟糕的是,没有一个,关于如何计算这些四分位数有三种不同的定义,它们会返回不同的结果。
//a utility, processes the part left <= indices < right
function _median(arr, left, right){
var i = (left+right)>>1;
return (right-left) & 1? arr[i]: .5 * (arr[i-1] + arr[i])
}
方法1和2比数学方法更实用,但通过它们的递归性质在某种程度上非常直接
var method1 = {
Q1(arr){
return _median(arr, 0, arr.length>>1)
},
Q2(arr){
return _median(arr, 0, arr.length);
},
Q3(arr){
var len = arr.length;
return _median(arr, (len>>1)+(len&1), len);
}
}
var method2 = {
Q1(arr){
var len = arr.length;
return _median(arr, 0, (len>>1) + (len&1))
},
Q2(arr){
return _median(arr, 0, arr.length);
},
Q3(arr){
var len = arr.length;
return _median(arr, len>>1, len);
}
}
方法3更像是:&#34;我们不同意使用方法,1或2.让我们取两者的平均值,最后关闭这个主题&#34;
var method3 = {
Q1(arr){
var len = arr.length,
r = (len >> 1) + (len&1),
i = r>>1;
return (r & 1)? arr[i]: .75 * arr[i-1] + .25*arr[i];
},
Q2(arr){
return _median(arr, 0, arr.length);
},
Q3(arr){
var len = arr.length,
l = len>>1,
i = (l+len)>>1;
return (len-l)&1? arr[i]: .25 * arr[i-1] + .75*arr[i];
}
}