中央値5は、アルゴリズム設計の演習として使用されることがあり、 6つの比較のみを使用して計算できることが知られています。
この「6つの比較を使用した5つの中央値」をC#で実装するための最良の方法は何ですか?私のすべての試みは厄介なコードをもたらすようです:(まだ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つの比較)
ペアのない数に取っておいた5番目の数を追加し、2つを比較します(4つの比較)
2つの新しいペアのうち最も低い2つのペアを比較し、下のペアを削除します(5つの比較)
1つだけを比較し、最後のペアの小さい方を比較します。小さい方の数値が中央値です。
可能な中央値は括弧内にあります
(54321)
5:4 3:22比較
(4 <5 2 <3 1)
4:23比較
2(4 <5 3 1)
1:34比較
2(4 <5 1 <3)
4:15比較
1,2(4 <5 3)
4:36比較
1,2(3)4,5
3つは中央値です
これは、中央値5を見つけるために私が書いたC++コードです。その厄介さを気にしないでください:
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の比較を使用するため、この要件を満たすことはできません:]