java - Optimal median function -


i experimenting code in attempt answer generic method find median of 3 values , trying ensure compareto method called minimum number of times , maximise efficiency of code , came this:

// flattens results of compareto -1, 0, 1 static int sign(int x) {     return x < 0 ? -1 : x == 0 ? 0 : 1; }  // use enum help. enum abc {      a() {                  @override                 <t> t which(t a, t b, t c) {                     return a;                 }              },     b() {                  @override                 <t> t which(t a, t b, t c) {                     return b;                 }              },     c() {                  @override                 <t> t which(t a, t b, t c) {                     return c;                 }              },     insane() {                  @override                 <t> t which(t a, t b, t c) {                     // < b , b < c c <                     return null;                 }              };      abstract <t> t which(t a, t b, t c); }  // straight lookup. private static final abc[][][] median = {     { // < b         { // b < c             // < c             abc.b,             // == c             abc.insane,             // > c             abc.insane         },         { // b == c             // < c             abc.b,             // == c             abc.insane,             // > c             abc.insane         },         { // b > c             // < c             abc.c,             // == c             abc.a,             // > c             abc.a         }     },     { // == b         { // b < c             // < c             abc.b,             // == c             abc.insane,             // > c             abc.insane         },         { // b == c             // < c             abc.insane,             // == c             abc.b,             // > c             abc.insane         },         { // b > c             // < c             abc.a,             // == c             abc.b,             // > c             abc.a         }     },     { // > b         { // b < c             // < c             abc.a,             // == c             abc.a,             // > c             abc.c         },         { // b == c             // < c             abc.insane,             // == c             abc.insane,             // > c             abc.b         },         { // b > c             // < c             abc.insane,             // == c             abc.insane,             // > c             abc.b         }     } };  private static <t extends comparable> t median(t a, t b, t c) {     system.out.print(" ab=" + sign(a.compareto(b)) + " bc=" + sign(b.compareto(c)) + " ac=" + sign(a.compareto(c)));     // least number of comparisons.     return median[sign(a.compareto(b)) + 1][sign(b.compareto(c)) + 1][sign(a.compareto(c)) + 1]             .which(a, b, c); }  // test case. private static <t extends comparable> t median2(t a, t b, t c) {     list<t> medianhelper = arrays.aslist(a, b, c);      collections.sort(medianhelper);      return medianhelper.get(1); }  public void test() {     (int = -5; <= 5; += 5) {         (int b = -3; b <= 3; b += 3) {             (int c = -1; c <= 1; c++) {                 system.out.print("(" + + "," + b + "," + c + ")");                 integer m = median(a, b, c);                 integer m2 = median2(a, b, c);                 system.out.print(" -> " + m + " & " + m2);                 if (m != m2) {                     system.out.print(" <-- wrong");                 }                 system.out.println();             }          }     } } 

to working used sort them , pick middle one technique , manually tweaked matrix until returned same result.

although seems work not cover of possibilities when compareto unstable (e.g. a < b && b < c && c < a) don't think important.

is there mechanism use correctly generate matrix? ideally 1 used generate min , max matrices too.

if want call compareto 3 times (i don't think can make work 2 calls), why not simple nested if/else:

public static <t extends comparable> t median(t a, t b, t c) {   if (a.compareto(b) <= 0) {     if (a.compareto(c) <= 0) {       return b.compareto(c) <= 0 ? b : c; //a <= b && <= c, return min(b, c)     } else {       return a;  //c < <= b, return     }   } else { // b <     if (a.compareto(c) <= 0) {       return a; // b < <= c, return     } else {       return b.compareto(c) <= 0 ? c : b; //b < && > c, return max(b, c)     }   } } 

Comments

Popular posts from this blog

php - failed to open stream: HTTP request failed! HTTP/1.0 400 Bad Request -

java - How to filter a backspace keyboard input -

java - Show Soft Keyboard when EditText Appears -