Number of comparisons made in median of 3 function?

后端 未结 6 906
轻奢々
轻奢々 2020-12-19 04:16

As of right now, my functioin finds the median of 3 numbers and sorts them, but it always makes three comparisons. I\'m thinking I can use a nested if statement somewhere so

相关标签:
6条回答
  • 2020-12-19 04:34

    Python V2

    def bigger(a,b):
        if a > b:
           return a
        else:
        return b
    
    def biggest(a,b,c):
        return bigger(a,bigger(b,c))
    
    def median(a,b,c):
        big = biggest(a,b,c)
        if big == a:
           return bigger(b,c)
        if big == b:
           return bigger(a,c)
        else:
           return bigger(a,b)
    

    to print the Median

    print(median(1,18,10)) # => 10
    
    0 讨论(0)
  • 2020-12-19 04:38

    To sort 3 items, you need exactly 3 comparisons.

    To find the middle one by chance, you need 2.

    To find the middle one exactly, you need on average 2+2/3 ~= 2.67 (with uniformly distributed random data)

    if (a<b) {
       // partial order = a,b
       if (b<c) {  } // 2 comparisons: order is a,b,c
          else { // order is a,c,b or c,a,b
              if (a<c) { } // order is a,c,b -- 3 comparisons
              else { }     // order is c,a,b -- 3 comparisons
          }
    } else {
       // partial order = b,a  
       if (c<b) {  } // 2 comparisons: order is c,b,a
       else {  // order is b,c,a or b,a,c
          if (c>a) { } // order is b,a,c -- 3 comparisons
          else { }   // order is b,c,a -- 3 comparisons
       }
    }
    

    As an additional side note: some languages (Fortran, IIRC), as well as some ISAs (VAX, again IIRC) support comparisons, where the next PC address is selected from three choices: LT,EQ,GT. With small enough alphabet this chance reduces slightly the number of needed comparisons.

    Also this has probably no practical use, taken, that penalties from wrong branch predictions because of overly complex nested structures can be much larger than gain from a saved comparison.

    0 讨论(0)
  • 2020-12-19 04:43

    If we allow extra operations, we could use at most 2 comparisons to find the median. The trick is to use exclusive or to find the relationship among three numbers.

    void median3(int A[], int p, int r)
    {
        int m = (p+r)/2;
        /* let a, b, c be the numbers to be compared */
        int a = A[p], b = A[m], c = A[r];
        int e = a-b;
        int f = a-c;
    
        if ((e^f) < 0) {
            med_comparisons += 1;
            /* a is the median with 1 comparison */
            A[m] = a;
            /* b < a < c ? */
            if (b < c) /* b < a < c */ { A[p] = b, A[r] = c; }
            else       /* c < a < b */ { A[p] = c, A[r] = b; }
            comparisons += 2;
        } else {
            med_comparisons += 2;
            int g = b-c;
            if ((e^g) < 0) {
                /* c is the median with 2 comparisons */ 
                A[m] = c;
                /* a < c < b ? */
                if (a < b) /* a < c < b */ { A[p] = a, A[r] = b; }
                else       /* b < c < a */ { A[p] = b, A[r] = a; }
            } else {
                /* b is the median with 2 comparisons */
                A[m] = b;
                /* c < b < a ? */
                if (a > c) /* c < b < a */ { A[p] = c; A[r] = a; }
                else       /* a < b < c */ { /* do nothing */    }
            }
            comparisons += 3;
        }
    }
    

    The first exclusive or (e^f) is to find out the difference of the sign bit between (a-b) and (a-c).
    If they have different sign bit, then a is the median. Otherwise, a is either the minimum or the maximum. In that case, we need the second exclusive or (e^g).

    Again, we are going to find out the difference of the sign bit between (a-b) and (b-c). If they have different sign bit, one case is that a > b && b < c. In this case, we also get a > c because a is the maximum in this case. So we have a > c > b. The other case is a < b && b > c && a < c. So we have a < c < b; In both cases, c is the median.

    If (a-b) and (b-c) have the same sign bit, then b is the median using similar arguments as above. Experiments shows that a random input will need 1.667 comparisons to find out the median and one extra comparison to get the order.

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

    If you only need the median value, here's a branch-less solution based on min/max operators:

    median = max(min(a,b), min(max(a,b),c));

    Intel CPU's have SSE min/max vector instructions, so depending on your or your compiler's ability to vectorize, this can run extremely fast.

    0 讨论(0)
  • 2020-12-19 04:53
    int m = (p + r) / 2;
    if (list[p] < list[m])
        if (list[p] >= list[r])
            return list[p];
        else if (list[m] < list[r])
            return list[m];
    else
        if (list[p] < list[r])
            return list[p];
    return list[r];
    
    0 讨论(0)
  • 2020-12-19 04:59

    More like this

    #define MEDIAN(a,b,c) ( (a > b) ? max(b, min(a,c)) :
                                      min(b, max(a,c)) )
    
    0 讨论(0)
提交回复
热议问题