最近,我做了一个测试任务,其中有必要计算中位数和其他内容。我写了下一个函数

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;
        }
}


在反馈中,我得到的中位数计算错误。现在,我无法弄清楚在什么情况下此功能将无法正常工作。您能解释一下这里出什么问题吗?
PS这样使用quartile(2)

只是排序
我发现了问题所在。我使用过array.sort(),但不知道以非自然顺序排序。

最佳答案

好吧,您的方程式是错误的,您的情况也是如此。

第一和第三夸脱的观察计算结果相差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。天哪,这是一种奇怪的,递归的,imo的非数学方法。更糟糕的是,没有一个,关于如何计算这些四分位数的定义有三种,它们返回的结果也不同。

//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感觉更像是:“我们无法同意使用哪种方法,是1还是2。让我们取两者的平均值,最后关闭该主题”

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];
  }
}

07-26 05:11