一尘不染

如何计算C#中的“五位数”?

algorithm

中位数5有时在算法设计中用作练习,并且已知 仅使用6个比较即可计算

在C# 实现 “使用6个比较中的5个中位数”
的最佳方法是什么?我所有的尝试似乎都导致笨拙的代码:(我需要漂亮且易读的代码,同时仍然仅使用6个比较。

public double medianOfFive(double a, double b, double c, double d, double e){
    //
    // return median
    //
    return c;
}

注意: 我想我也应该在此处提供“算法”:

我发现自己无法像 Azereal
在他的论坛帖子中那样清楚地解释算法。因此,我将在这里引用他的帖子。来自http://www.ocf.berkeley.edu/~wwu/cgi-
bin/yabb/YaBB.cgi?board=riddles_cs;action=display;num=1061827085

好吧,我的一项任务给我带来了这个问题,我转向这个论坛寻求帮助,但这里没有帮助。我最终找到了解决方法。

  1. 从前4个元素开始合并排序并为每对排序(2个比较)

  2. 比较每对中的两个较低者,并从可能性中消除最低者(3个比较)

  3. 将第5个数字加到不成对的数字上,然后比较两个数字(4个比较)

  4. 比较两个新对中的两个最低对,并消除较低的一对(5个比较)

  5. 单独比较一个和最后一对中的较低者,较低者是中位数

可能的中位数在括号内

(54321)

5:4 3:2 2比较

(4 <5 2 <3 1)

4:2 3比较

2(4 <5 3 1)

1:3 4比较

2(4 <5 1 <3)

4:1 5比较

1,2(4 <5 3)

4:3 6比较

1,2(3)4,5

三是中位数

这是我写的C ++代码,发现中位数为5。不要介意它的笨拙:

double StageGenerator::MedianOfFive(double n1, double n2, double n3, double n4, double n5){
    double *a = &n1, *b = &n2, *c = &n3, *d = &n4, *e = &n5;
    double *tmp;

    // makes a < b and b < d
    if(*b < *a){
        tmp = a; a = b; b = tmp;
    }

    if(*d < *c){
        tmp = c; c = d; d = tmp;
    }

    // eleminate the lowest
    if(*c < *a){
        tmp = b; b = d; d = tmp; 
        c = a;
    }

    // gets e in
    a = e;

    // makes a < b and b < d
    if(*b < *a){
        tmp = a; a = b; b = tmp;
    }

    // eliminate another lowest
    // remaing: a,b,d
    if(*a < *c){
        tmp = b; b = d; d = tmp; 
        a = c;
    }

    if(*d < *a)
        return *d;
    else
        return *a;

}

它应该更紧凑,不是吗?


正如@pablito在回答中指出的那样,内置List.Sort()函数无法满足此要求,因为它最多使用13个比较:]


阅读 263

收藏
2020-07-28

共1个答案

一尘不染

这基本上只是从C ++示例中排除掉交换和排序代码:

private static void Swap(ref double a, ref double b) {
    double t = a;
    a = b;
    b = t;
}

private static void Sort(ref double a, ref double b) {
    if (a > b) {
        double t = a;
        a = b;
        b = t;
    }
}

private static double MedianOfFive(double a, double b, double c, double d, double e){
    // makes a < b and c < d
    Sort(ref a, ref b);
    Sort(ref c, ref d);

    // eleminate the lowest
    if (c < a) {
        Swap(ref b, ref d);
        c = a;
    }

    // gets e in
    a = e;

    // makes a < b
    Sort(ref a, ref b);

    // eliminate another lowest
    // remaing: a,b,d
    if (a < c) {
        Swap(ref b, ref d);
        a = c;
    }

    return Math.Min(d, a);
}
2020-07-28