algorithmus zum finden von zyklischen verschiebungen in sortierten arrays?

4 Antworten

  1. sei T der letzte Eintrag der Liste...
  2. ich nehme mal an, dass die Einträge paarweise verschieden sind, weil man sonst zuviel rumprobieren müsste... grins
  3. man sucht nun also den Eintrag E der Liste, der >T ist, und dem ein Eintrag folgt, der kleiner oder gleich E ist...
  4. man sucht also erst etwas mit Intervallschachtelung, das größer ist... wenn man auf etwas kleineres trifft, weiß man, dass man in der rechten Hälfte weitersuchen muss...
  5. und dann wieder mit Intervallschachtelung etwas rechts davon, das kleiner ist...
  6. also ich käm da auf O(2·log n)=O(log n)... oda?
Woher ich das weiß:Studium / Ausbildung
buffalo23  29.04.2019, 00:35

Warum 2*log(n)?

0
RIDDICC  29.04.2019, 00:39
@buffalo23

weil man zweimal suchen muss... oda?

ist vllt auch ne Schnapsidee von mir... :) bin müde... und so...

0
buffalo23  29.04.2019, 00:41
@RIDDICC

Nee ist doch im Prinzip das gleiche wie das was ich auch machen würde, nur warum 2x suchen? Wo ist der zweite Suchvorgang?

0
RIDDICC  29.04.2019, 06:38
@buffalo23
  1. erstmal von ganz hinten nach links nach etwas, das größer ist...
  2. dann von dort nach rechts, bis man genau die Grenze findet...

oder kann man quasi beide Schritte in einem machen?

1
buffalo23  29.04.2019, 07:06
@RIDDICC

Klar das ist ein einziger Suchvorgang... Weil du startest ja nicht wieder am Anfang sondern benutzt das Ergebnis aus Schritt (1) für Schritt (2)

1
RIDDICC  29.04.2019, 13:57
@buffalo23

jetzt code ich es doch: kicher

#include <stdio.h>
#include <stdlib.h>

int tellme(int * L, int l) {
    const int E = L[l-1];
    if (L[0]<E) return 0;
    int a=0, b=l-2;
    while (a < b) {
        const int m = (a+b) / 2;
        const int M = L[m];
        if (M<E) b=m-1;
        else if (a<m) a=m;
        else if (M<L[a+1]) a++;
        else b--;
    }
    return a+1;
}

int main(int argc, char ** argv) {
    int lst[argc-1];
    for (int i=0; i<argc-1; i++) lst[i]=atoi(argv[i+1]);
    printf("yay! %d\n",tellme(lst,argc-1));
    return 0;
}

hast recht: es gehen beide Such-Ziele in derselben Schleife... :)

1

Logarithmische Komplexität kriegst du hin indem du zuerst das Element ganz links mit dem ganz rechts (als Pivotelement) vergleichst, dann mit dem Element in der Mitte (als Pivotelement), und dann wieder mit dem mittleren Element der linken/rechten Hälfte des kleineren Intervalls. Hoffe du verstehst wie ich das meine.

Da die Arrays sortiert sind, funktioniert das, du prüfst jeweils ob das Pivotelement kleiner/größer ist als das Element ganz links, um den Grad der Verschiebung zu ermitteln

Wenn Du weißt, dass das Array eh "sortiert" ist, dann verstehe ich nicht, warum Du auf logarithmischen Aufwand kommen willst. Das geht dann billiger, indem man einfach die Vorbedingung honoriert und sich nur am Minimum im Array orientiert.

Also:

  1. Array #1 absuchen und Mindestwert darin finden, Feldindex merken.
  2. Array #2 absuchen und Mindestwert darin finden, Feldindex merken.
  3. Differenz Feldindizes bilden und rückmelden.

Dann kommst Du auf O(2*n) mit n=Arraygröße. Ist doch viel effizienter.

buffalo23  29.04.2019, 14:47

Das stimmt nicht, logarithmische Laufzeitkomplexität ist besonders für große Datenmenge deutlich besser als lineare... Insofern ist diese Antwort hier nicht richtig

0

Und woran scheitert es nun?

Ziehe ein Element aus der Quelle (Median z.B.) und führe eine binäre Suche im Ziel durch. Bestimme (errechne) den Offset (Achtung 2 Kandidaten) und wiederhole mit einem geeigneten Element zur (Gegen)prüfung. Wenn gleiches Offsetting muß das Ergebnis ein Shift sein, andernfalls laut Vorbedingung ein sortiertes Array.

Prinzipiell kannst Du auch 4 Proben ziehen, das ist relativ egal, denn Du bleibst in c*log(n).

Nachtrag: Du kannst im Prinzip erstes Element, Median und letztes Element für den Test nehmen, ab dem zweiten Test sollte Richtung und Distanz feststehen.

buffalo23  29.04.2019, 00:33

Wofür brauchst du mehrere Tests? Die Richtung ist irrelevant, da sich ein Rechts- nicht von einem Links-Shift unterscheidet

0
KarlRanseierIII  29.04.2019, 00:51
@buffalo23

Daß die Shiftrichtugn egal ist, stimmt wohl. Allerdings kannst Du mit einem einfachen Test eine Sortierung nicht ausschließen.

4,3,2,1-> 1,2,3,4

Was mir generell fehlt: Gibt es eine Nebenbedingung bezüglich der paarweisen Verschiedenheit der Elemente?

0