Array Links/Rechtsverschiebung



  • Gradiee schrieb:

    Ich frag mich nur warum ich in der "for (j =..." Schleife noch einmal i deklarieren muss, obwohl ich das ja am Anfang in der Main schon getan hab.

    Musst du gar nicht.



  • ok stimmt, der Compiler hat da wohl vorhin bisschen gesponnen 🙂



  • Wurde eigentlich schon in Betracht gezogen, das Array selbst gar nicht zu verschieben, sondern einfach nur einen Index zu verschieben?

    #define VECTOR_LENGTH 10
    
    typedef struct {
        int data[VECTOR_LENGTH];
        size_t offset;
    } vector_t;
    
    int vector_get_at (vector_t *obj, size_t pos) {
        return obj->data[(pos + obj->offset)%VECTOR_LENGTH];
    }
    
    void vector_set_at (vector_t *obj, int val, size_t pos) {
        obj->data[(pos + obj->offset)%VECTOR_LENGTH] = val;
        return;
    }
    
    void vector_rol (vector_t *obj) {
        obj->offset = (obj->offset + 1)%VECTOR_LENGTH;
        return;
    }
    
    void vector_ror (vector_t *obj) {
        obj->offset = (obj->offset + VECTOR_LENGTH - 1)%VECTOR_LENGTH;
        return;
    }
    

    Code nicht getestet, noch nichtmal kompilier.



  • Ich versteh nix von deinem Code 😛



  • @Tim: hmmm, interessanter Ansatz, hab nicht dran gedacht.



  • Gradiee schrieb:

    Ich versteh nix von deinem Code 😛

    Ja, etwas unglücklich. Ich hätte es besser erklären sollen. Die Idee ist, dass man nicht die Werte im Vektor verschiebt, sondern nur den "Blickwinkel" auf den Vektor, also wie man die Werte im Vektor interpretiert. Beispiel. Du hast ein Vektor[10]:

    1 5 3 7 2 6 7 2 8 0
    

    Gleichzeitig haben wir im Ausgangszustand einen offset von 0:

    1 5 3 7 2 6 7 2 8 0
    ^
    

    Anstatt jetzt die Werte zu kopieren, ändern wir einfach nur den offset:

    1 5 3 7 2 6 7 2 8 0
      ^
    

    Wenn wir jetzt über den Vektor iterieren (Funktion vector_get_at ) würden wir das bekommen:

    5 3 7 2 6 7 2 8 0 1
    

    Also gleichbedeutend mit einem verschieben nach links.

    Andersrum (offset wird "kleiner", darf aber nicht negativ werden, also muss 0-1 zu 9 werden):

    1 5 3 7 2 6 7 2 8 0
                      ^
    

    Würde das Ergebnis einem verschieben nach rechts gleichkommen:

    0 1 5 3 7 2 6 7 2 8
    

    Jetzt etwas klarer?

    Diese Variante muss nicht schneller sein als einfaches umkopieren. Für kleine Vektorgrößen wird das umkopieren wahrscheinlich meist schneller sein. Auch hängt es davon ab wie oft aus dem Vektor gelesen bzw. in den Vektor geschrieben wird. "Shiftet" man beispielsweise oft um, und liest/schreibt nur selten, dann hätte "meine" Variante Vorteile. Wenn man aber Viel liest/schreibt und nur selten "shiftet" wäre die Kopiervariante vorteilhaft. "Meine" Variante hat u.U. auch Nachteile wenn die Vektorgröße keine Zweierpotenz ist. Unterm Strich wirst du wahrscheinlich bei der Kopiervariante bleiben, aber andere Ansätze zu kennen ist wichtig, weil man sowas immer mal brauchen kann.



  • Ja danke sehr gut erklärt 🙂 👍



  • Ok naechstes Problem ..
    Das ganze wird jetzt in ein Menue gepackt, einfach der Uebung wegen..

    char* wahl="[1] Vektor anzeigen\n"\			// Menue Auswahl
    	"t2 - links rotieren\n"\
    	"\t3 - rechts rotieren\n"\
    	"\t4 - Mehrfache Links-/ Rechts-Rotation\n"\
    	"\t5 - Element l\224schen\n"\
    	"\t6 - Element einf\201gen\n"\
    	"\t0 - Beenden\n\n";
    

    uns wurde gezeigt man kann ein ganzes Menue einfach in ne Variable speichern, wobei das \ zeigen soll, das noch etwas kommt.

    Mir sagt er aber, das das ein unbekanntes Token ist.

    Muss ich jetzt noch eine Datei einbinden, oder warum geht das nicht?



  • Das Problem ist der Kommentar dahinter, mach den mal weg. Der Compiler versucht wegen des Backslashs, eine Escapesequenz zu bilden.

    const
    char* wahl= "[1] Vektor anzeigen\n"\
    			"\t2 - links rotieren\n"\
    			"\t3 - rechts rotieren\n"\
    			"\t4 - Mehrfache Links-/ Rechts-Rotation\n"\
    			"\t5 - Element l\224schen\n"\
    			"\t6 - Element einf\201gen\n"\
    			"\t0 - Beenden\n\n";
    

    Edit: Das Literal sollte gleich als const deklariert werden.



  • Das Problem ist der Backslash dahinter, mach den mal weg. Der Compiler versucht wegen des Backslashs, eine Escapesequenz zu bilden.

    char wahl[] =
        "[1] Vektor anzeigen\n"            /* Menue Auswahl */
        "[2] - links rotieren\n"
        "[3] - rechts rotieren\n"
        "[4] - Mehrfache Links-/ Rechts-Rotation\n"
        "[5] - Element l\224schen\n"
        "[6] - Element einf\201gen\n"
        "[0] - Beenden\n\n";
    

Anmelden zum Antworten