中位数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
好吧,我的一项任务给我带来了这个问题,我转向这个论坛寻求帮助,但这里没有帮助。我最终找到了解决方法。 从前4个元素开始合并排序并为每对排序(2个比较) 比较每对中的两个较低者,并从可能性中消除最低者(3个比较) 将第5个数字加到不成对的数字上,然后比较两个数字(4个比较) 比较两个新对中的两个最低对,并消除较低的一对(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 三是中位数
好吧,我的一项任务给我带来了这个问题,我转向这个论坛寻求帮助,但这里没有帮助。我最终找到了解决方法。
从前4个元素开始合并排序并为每对排序(2个比较)
比较每对中的两个较低者,并从可能性中消除最低者(3个比较)
将第5个数字加到不成对的数字上,然后比较两个数字(4个比较)
比较两个新对中的两个最低对,并消除较低的一对(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个比较:]
List.Sort()
这基本上只是从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); }