Fastest way of finding the middle value of a triple?

前端 未结 25 928
庸人自扰
庸人自扰 2020-12-04 12:20

Given is an array of three numeric values and I\'d like to know the middle value of the three.

The question is, what is the fastest way of finding the midd

25条回答
  •  野趣味
    野趣味 (楼主)
    2020-12-04 12:50

    Bumping up an old thread, but still it's the shortest solution, and nobody mentioned it.

    Solution:

    int median2(int a, int b, int c) {
        return (a > b) ^ (a > c) ? a : (a > b) ^ (b > c) ? c : b;
    }
    

    Tests:

    (tests cover all the possible combinations, all of them print 6)

    public static void main(String[] args) {
    
        System.out.println(median(3, 6, 9));
        System.out.println(median(3, 9, 6));
        System.out.println(median(6, 3, 9));
        System.out.println(median(6, 9, 3));
        System.out.println(median(9, 3, 6));
        System.out.println(median(9, 6, 3));
        System.out.println(median(6, 6, 3));
        System.out.println(median(6, 6, 9));
        System.out.println(median(6, 3, 6));
        System.out.println(median(6, 9, 6));
        System.out.println(median(3, 6, 6));
        System.out.println(median(9, 6, 6));
        System.out.println(median(6, 6, 6));
    
    }
    

    Explanation 1

    (a > b) ^ (a > c) false if either c > a > b or c < a < b - return a;

    otherwise (a > b) ^ (b > c) false if either a > b > c or a < b < c - return b;

    otherwise return c;

    Explanation 2

    Let's assume p = a > b; q = b > c; s = a > c;

    Let's build a Karnaugh map.

       | 00  01  11  10 (p, q)
    ---+----------------------
     0 |  b   c   *   a
     1 |  *   a   b   c
    (s)|
    

    * means that the combination is impossible (like a > b; b > c; a < c)

    Notice that the right part is a mirrored left part, and the map can be simplified by introducing t = p ^ q; u = s ^ p

       |  0   1 (t)
    ---+---------
     0 |  b   c  
     1 |  *   a  
    (u)|
    

    So the function may be written as

    private static int median(int a, int b, int c) {
        boolean t = (a > b) ^ (b > c);
        boolean u = (a > b) ^ (a > c);
        if (u)
            return a;
        else if (t)
            return c;
        else
            return b;
    }
    

    Inlining variables and replacing ifs with ?: gives the answer

    int median2(int a, int b, int c) {
        return (a > b) ^ (a > c) ? a : (a > b) ^ (b > c) ? c : b;
    }
    

    The solution works fine even if some on the inputs are equal, which may be not evident, but quite logical.

提交回复
热议问题