2

我正在编写一个函数来克隆 Excel 中数据分析加载项的直方图功能。基本上,提供了样本数据的输入,然后还提供了 bin 范围。bin 范围必须单调增加,在我的情况下,需要具体为 [0 20 40 60 80 100]。如果样本大于下限(左边缘)且小于或等于上限(右边缘),Excell 会计算样本是否落入 bin 范围。

我在下面编写了 bin 排序算法,它为 data0 提供了不正确的输出(非常接近),但为 data1 和 data2 提供了正确的输出。在这种情况下,正确意味着该算法的输出与 Excell 生成的表中的输出完全匹配,其中样本数与 bin 相邻。任何帮助表示赞赏!

#include <iostream>

int main(int argc, char **agv)
{
    const int SAMPLE_COUNT      = 21;
    const int BIN_COUNT         = 6;
    int binranges[BIN_COUNT]    = {0, 20, 40, 60, 80, 100};
    int bins[BIN_COUNT]         = {0, 0, 0, 0, 0, 0};

    int data0[SAMPLE_COUNT] =  {4,82,49,17,89,73,93,86,74,36,74,55,81,61,88,94,72,65,35,25,79};
    // for data0 excell's bins read:
    // 0    0
    // 20   2
    // 40   3
    // 60   2
    // 80   7
    // 100  7
    //
    // instead output of bins is: 203277

    int data1[SAMPLE_COUNT] = {88,83,0,0,95,86,0,94,92,77,94,73,93,90,50,95,93,83,0,95,91};
    //for data1 excell and this algorithm both yield:
    // 0    4
    // 20   0
    // 40   0
    // 60   1
    // 80   2
    // 100  14  (correct)

    int data2[SAMPLE_COUNT] = {58,48,75,68,85,78,74,83,83,75,67,58,75,58,84,68,57,88,55,79,72};
    //for data2 excell and this algorithm both yield:
    // 0    0
    // 20   0
    // 40   0
    // 60   6
    // 80   10
    // 100  5   (correct)

    for (unsigned int binNum = 1; binNum < BIN_COUNT; ++binNum)
    {
        const int leftEdge = binranges[binNum - 1];
        const int rightEdge = binranges[binNum];

        for (unsigned int sampleNum = 0; sampleNum < SAMPLE_COUNT; ++sampleNum)
        {
            const int sample = data0[sampleNum];

            if (binNum == 1)
            {
                if (sample >= leftEdge && sample <= rightEdge)
                    bins[binNum - 1]++;
            }
            else if (sample > leftEdge && sample <= rightEdge)
            {
                bins[binNum]++;
            }
        }
    }

    for (int i = 0; i < BIN_COUNT; ++i)
        std::cout << bins[i] << " " << std::flush;

    std::cout << std::endl << std::endl;

    return 0;
}
4

1 回答 1

3

假设边缘总是按递增顺序排列,您只需要:

     unsigned int bin;
    for (unsigned int sampleNum = 0; sampleNum < SAMPLE_COUNT; ++sampleNum)
    {
           const int sample = data0[sampleNum];
           bin = BIN_COUNT;
           for (unsigned int binNum = 0; binNum < BIN_COUNT; ++binNum)  {
                 const int rightEdge = binranges[binNum];
                 if (sample <= rightEdge) {
                    bin = binNum;
                    break;
                }
           }
           bins[bin]++;
      }

虽然,要使此代码正常工作,您需要为等于或低于第一条边 ( 0) 的值再添加一个 bin。

合理的是,如果你有 n 个分隔符,那么你就有 n+1 个间隔。

于 2013-03-04T23:39:22.283 回答