Fastest way of finding the middle value of a triple?

前端 未结 25 876
庸人自扰
庸人自扰 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:46

    Using idxA to idxC in ary,

    int ab = ary[idxA] < ary[idxB] ? idxA : idxB;
    int bc = ary[idxB] < ary[idxC] ? idxB : idxC;
    int ac = ary[idxA] < ary[idxC] ? idxA : idxC;
    
    int idxMid = ab == bc ? ac : ab == ac ? bc : ab;
    

    indexMiddle points to the middle value.

    Explanation: from the 3 minima 2 are the overall minimum and the other value must be the middle. Because we check equality we can compare the indices in the last line instead of having to compare the array values.

    0 讨论(0)
  • 2020-12-04 12:47

    median = (a+b+c) - Math.min(Math.min(a,b),c) - Math.max(Math.max(a,b),c)

    This is the basic one, i don't know how efficient this would work but these functions use if conditions after all. If you would like you can turn this statement into if-else statements, yet it will take time. Why so lazy?

    0 讨论(0)
  • 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.

    0 讨论(0)
  • 2020-12-04 12:50
    largest=(a>b)&&(a>c)?a:(b>c?b:c);
    smallest=(a<b)&&(a<c)?a:(b<c?b:c);
    median=a+b+c-largest-smallest;
    
    0 讨论(0)
  • 2020-12-04 12:50

    Here is the answer in Python, but same logic applies to the Java program.

    def middleOfThree(a,b,c):
        middle = a
        if (a < b and b < c) or (c < b and b < a):
            middle = b 
        elif (a < c and c < b) or (b < c and c < a):
            middle = c    
        print 'Middle of a=%d, b=%d, c=%d is %d' % (a,b,c,middle)
    
    middleOfThree(1,2,3)
    middleOfThree(1,3,2)
    middleOfThree(2,1,3)
    middleOfThree(2,3,1)
    middleOfThree(3,2,1)
    middleOfThree(3,1,2)
    
    0 讨论(0)
  • 2020-12-04 12:51

    Here's how you can express this using only conditionals:

    int a, b, c = ...
    int middle = (a <= b) 
        ? ((b <= c) ? b : ((a < c) ? c : a)) 
        : ((a <= c) ? a : ((b < c) ? c : b));
    

    EDITS:

    1. Errors in above found by @Pagas have been fixed.
    2. @Pagas also pointed out that you cannot do this with fewer than 5 conditionals if you only use conditional, but you can reduce this using temporary variables or value swapping.
    3. I would add that it is hard to predict whether a pure conditional or assignment solution would be faster. It is likely to depend on how good the JIT is, but I think the conditional version would be easier for the optimizer to analyse.
    0 讨论(0)
提交回复
热议问题