it-swarm.com.de

Mindestanzahl von Vergleichen, um den Mittelwert von 3 Zahlen zu finden

Ich implementierte Quicksort und wollte den Drehpunkt auf den Mittelwert oder drei Zahlen setzen. Die drei Zahlen sind das erste Element, das mittlere Element und das letzte Element.

Könnte ich möglicherweise den Median in weniger nein finden. von Vergleichen? 

median(int a[], int p, int r)
{
    int m = (p+r)/2;
    if(a[p] < a[m])
    {
        if(a[p] >= a[r])
            return a[p];
        else if(a[m] < a[r])
            return a[m];
    }
    else
    {
        if(a[p] < a[r])
            return a[p];
        else if(a[m] >= a[r])
            return a[m];
    }
    return a[r];
}
14
Karan Kalra

Sie können es nicht in einem tun, und Sie verwenden nur zwei oder drei, also würde ich sagen, Sie haben bereits die minimale Anzahl von Vergleichen.

4
Joel

Wenn es sich nur um Vergleiche handelt, sollte dies verwendet werden.

int getMedian(int a, int b , int c) {
    int x = a-b;
    int y = b-c;
    int z = a-c;
    if(x*y > 0) return b;
    if(x*z > 0) return c;
    return a;
}
10
Raghav

Anstatt nur den Median zu berechnen, können Sie sie genauso gut einsetzen. Dann können Sie die ganze Zeit mit nur drei Vergleichen durchkommen und Ihren Pivot näher bringen.

T median(T a[], int low, int high)
{
    int middle = ( low + high ) / 2;
    if( a[ middle ].compareTo( a[ low ] ) < 0 )
        swap( a, low, middle );
    if( a[ high ].compareTo( a[ low ] ) < 0 )
        swap( a, low, high );
    if( a[ high ].compareTo( a[ middle ] ) < 0 )
        swap( a, middle, high );

    return a[middle];
}
4
Joel
int32_t FindMedian(const int n1, const int n2, const int n3) {
    auto _min = min(n1, min(n2, n3));
    auto _max = max(n1, max(n2, n3));
    return (n1 + n2 + n3) - _min - _max;
}
3
codeb34v3r

Wenn Sie keine Angst davor haben, sich mit Compiler-Intrinsics ein wenig schmutzig zu machen, können Sie dies mit genau 0 Ästen tun.

Die gleiche Frage wurde zuvor am besprochen:
Der schnellste Weg, um den Mittelwert eines Tripels zu finden?

Allerdings muss ich hinzufügen, dass im Zusammenhang mit der naiven Implementierung von Quicksort mit vielen Elementen die Verringerung der Anzahl der Zweige beim Ermitteln des Medians nicht so wichtig ist, da der Verzweigungs-Prädiktor in beiden Fällen ersticken wird, wenn Sie Elemente werfen um den Pivot. Anspruchsvollere Implementierungen (die sich beim Partitionierungsvorgang nicht verzweigen und WAW-Gefahren vermeiden) werden davon sehr profitieren.

2
Max

max und Min Wert aus der Gesamtsumme entfernen

int med3(int a, int b, int c)
{
    int tot_v = a + b + c ;
    int max_v = max(a, max(b, c));
    int min_v = min(a, min(b, c));
    return tot_v - max_v - min_v
}
1
Alok N Singh

Es gibt tatsächlich eine clevere Methode, das Median-Element von drei Elementen zu isolieren, indem die 6 möglichen Permutationen (von niedrig, median, hoch) sorgfältig analysiert werden. In Python:

def med(a, start, mid, last):
    # put the median of a[start], a[mid], a[last] in the a[start] position
    SM = a[start] < a[mid]
    SL = a[start] < a[last]
    if SM != SL:
        return
    ML = a[mid] < a[last]
    m = mid if SM == ML else last
    a[start], a[m] = a[m], a[start]

Die Hälfte der Zeit haben Sie zwei Vergleiche, ansonsten haben Sie 3 (durchschnittlich 2,5). Sie tauschen das Median-Element nur einmal, wenn dies erforderlich ist (2/3 der Zeit).

Volle Python-Quicksortierung unter Verwendung von:

https://github.com/mckoss/labs/blob/master/qs.py

1
mckoss

Ich weiß, dass dies ein alter Thread ist, aber ich musste genau dieses Problem auf einem Mikrocontroller lösen, der sehr wenig RAM hat und keine h/w-Multiplikationseinheit (:) hat. Am Ende fand ich die folgenden Arbeiten gut:

static char medianIndex[] = { 1, 1, 2, 0, 0, 2, 1, 1 };

signed short getMedian(const signed short num[])
{
    return num[medianIndex[(num[0] > num[1]) << 2 | (num[1] > num[2]) << 1 | (num[0] > num[2])]];
}
0
user5108360

Sie können alle Permutationen aufschreiben:

    1 0 2
    1 2 0
    0 1 2
    2 1 0
    0 2 1
    2 0 1

Dann wollen wir die Position des 1 finden. Wir könnten dies mit zwei Vergleichen tun, wenn unser erster Vergleich eine Gruppe von gleichen Positionen wie die ersten beiden Zeilen aufteilen könnte.

Das Problem scheint zu sein, dass die ersten beiden Zeilen bei jedem verfügbaren Vergleich unterschiedlich sind: a<b, a<c, b<c. Daher müssen wir die Permutation vollständig identifizieren, die im schlimmsten Fall drei Vergleiche erfordert.

0
Thomas Ahle