Denkfehler bei einfacher Schleife

EinNickname9

Bekanntes Mitglied
Hallo,

ich möchte alle Zeichen einer Zeichenfolge um shift Schritte in eine Richtung verschieben. Es soll dabei kein zusätzliches Array benutzt werden...

Das ist mein bisheriger Ansatz:

Java:
    public static char[] shiftImproved(final char[] txt, final int shift) {
        for (int i = 1; shift * (i - 1) + shift <= txt.length; i *= 2) {
            for (int j = 0; j < shift; j++) {
                int i1 = (shift * (i - 1) + j) % txt.length;
                int i2 = (shift * (i - 1) + j + shift) % txt.length;
                char temp = txt[i1];
                txt[i1] = txt[i2];
                txt[i2] = temp;
            }
        }
        System.out.println("txt = " + Arrays.toString(txt));
        return txt;
    }

    public static void main(String[] args) {
        for (int i = 1; i < 10; i++) {
            System.out.println("i = " + i);
            shiftImproved("Guten Tag".toCharArray(), i);
        }
    }

Und das ist die Ausgabe:

i = 1
txt = [u, t, G, n, e, , T, g, a]
i = 2
txt = [a, e, n, , G, u, g, t, T]
i = 3
txt = [e, n, , T, a, g, G, u, t] ✅
i = 4
txt = [u, t, e, a, g, n, , T, G]
i = 5
txt = [n, T, a, g, , G, u, t, e] ✅
i = 6
txt = [e, n, , T, a, g, G, u, t] ✅
i = 7
txt = [t, e, n, , T, g, a, G, u]
i = 8
txt = [u, t, e, n, , T, a, g, G] ✅
i = 9
txt = [G, u, t, e, n, , T, a, g] ✅

Kann mir vielleicht jemand sagen, was ich falsch mache? Danke. 😊
 
Also irgendwie verstehe ich deinen Ansatz in keiner Weise. Dein Code ist auch extrem unleserlich...

Du könntest ja mal erläutern, was Dein Code überhaupt machen soll 🙂

Generell würde ich da einfach heran gehen und es wie immer unterteilen:

a) Du kannst eine Methode Schreiben, die um genau eine Stelle verschiebt. Das ist ja auch einfach, da man einfach ein Element nimmt und dann immer mit den nachfolgenden Zeichen tauscht.
b) das kannst Du dann in einer Schleife n mal aufrufen

Beides ist einfach und übersichtlich zu schreiben mit Code, der einfach zu lesen und zu verstehen ist.
 
Das ist nicht effizient, eine Schleife n-mal aufzurufen (n*n Laufzeit, also quadratische Laufzeit).
Quadratisch ist es nicht, es ist O(n*m) mit n = Länge des Arrays und m = Anzahl der Verschiebungen
Aber ja, 100% effizient ist es nicht - aber solange die Effizienz nicht gefragt ist, ist es selten sinnvoll die von vornerein einzubauen
Ist das denn mein Problem?
Ja. ich hab überhaupt keine Idee, was das die äußere Schleife machen soll und warum da irgendwas rauskommen soll, was eine Verschiebung ist. Das ist schlicht nicht verständlich. i nimmt die Werte 1, 2, 4, und bricht irgendwann ab. Warum das quadrieren von i irgendwas mit einer Verschiebung um n Stellen zu tun hat ist mir schleierhaft.
 
Das ist nicht effizient, eine Schleife n-mal aufzurufen (n*n Laufzeit, also quadratische Laufzeit).
Das ist doch auch die Komplexität von Deinem Code. Du hast auch zwei verschachtelte Schleifen.
Ist das denn mein Problem?
Scheint zumindest so. zumindest fällt es uns schwer, Dir zu helfen und Du selbst scheinst da auch nicht durchzublicken, sonst hättest Du ja kaum den Thread erstellt.
 
Im Endeffekt ist die Herausforderung bei der Aufgabe, das kein weiteres Array verwendet werden darf. Das heißt, ich muss bei der Verschiebung aufpassen, dass ich nicht Dinge doppelt verschiebe (Das aus Position 1 kommt auf 5 - aber das aus 5 kommt vielleicht auf 9 - oder je nach Länge auf Position 2). Sprich, wenn man einmal durch das Array durchgeht und alles um shift verschiebt kommt vermutlich nicht das richtige raus.

Jetzt gibt es zwei Ansätze die man machen kann:

a) Den @kneitzel vorgeschlagen hat, dass konkret für einen shift um 1 zu implementieren und das dann entsprechend oft durchzuführen
b) Das Problem in einen effizienten Algorithmus überführen, der jedes Element nur einmal anfasst. Das ist aber deutlich aufwendiger und setzt voraus, dass man diesen Algorithmus auch erstmal überhaupt beschreiben kann in Worten bevor man ihn implementiert.

Ich würde an der Stelle a) machen, solange b) nicht gefordert ist.
 
Das ist doch auch die Komplexität von Deinem Code.
Nein ist es nicht. Das würde man durch genaues Hinsehen sehen oder durch Zählen der tatsächlichen Schritte.

Scheint zumindest so. zumindest fällt es uns schwer, Dir zu helfen und Du selbst scheinst da auch nicht durchzublicken, sonst hättest Du ja kaum den Thread erstellt.
Ja vielleicht geht es auch einfacher, aber ich sehe nicht, wie.
 
Wenn die Aufgabenstellung wirklich nur ist, dass alle Zeichen um shift Schritte verschoben werden, brauchst du nur eine Schleife mit der temp Variable, die ein Zeichen vorhält, damit es nicht verloren geht.

Die äußere Schleife in deiner Funktion kann ich ehrlich gesagt auch nicht nachvollziehen. Was soll die bezwecken?
 
Und generell immer schön sauber bleiben was den Code angeht:
- klare Bezeichner! (Was ist i, j, i1, i2 in deinem Code?)
- Vernünftige Ausdrücke! ("shift * (i - 1) + shift" ist z.B. "shift * i")
- Und wenn Code nicht sofort erkennbar ist, was da passiert: Unterteilen! Du kannst die innere for Schleife ja ggf. auch in eine eigene Methode auslagern mit vernünftigem Bezeichner und schon hat man es leichter, den Code zu verstehen.
 
Wenn das Array 10 Felder hat muss die Schleife 10 mal laufen.

pos = 0
Vor dem ersten lauf Wert von Pos0 in Merker1 merken.
pos + shift

Schleife

Wert auf pos in Merker2
Wert von Merker1 auf pos setzen
Merker1= Merker2
pos + shift
Testen ob pos größer als Array
Wenn ja pos = pos - arraylänge-1
 
Zuletzt bearbeitet:
Wenn die Aufgabenstellung wirklich nur ist, dass alle Zeichen um shift Schritte verschoben werden, brauchst du nur eine Schleife mit der temp Variable, die ein Zeichen vorhält, damit es nicht verloren geht.
Kannst Du den Algorithmus einmal kurz Vorstellen? Das dürfte nicht ganz so einfach sein fürchte ich, denn Du musst ja erkennen, was Du schon verschoben hast und was nicht.

Also um es deutlich zu machen:
A B C D und um 3 verschieben:
A muss zum D, wie gehst Du mit dem D weiter vor? Das kommt direkt zum C und Du machst beim C weiter? Was ist der Abbruch? Das dann irgendwann etwas wieder beim A landet?

Dann nehmen wir A B C D und verschieben um 2:
A auf C, C kommt dann auf A -> Abbruch weil etwas bei A gelandet ist?

Also die möglichen Fälle machen es schon etwas komplexer fürchte ich. Zumindest die zwei Fälle: n%shift == 0 oder eben nicht.
 
Java:
weiterschieben( char array. int buchstabenposition im array , shift)
{
    dein buchstabe = array [ buchstabenposition ]
    position = possition buchstabenposition im array + shift
    if ( überlauf am ende )
    {
        position = position am anfang dann finden
    }
    if ( nicht am ende des arrays angelangt )
    {
    array = weiter schieben ( char array , buchstabenposition im array +1 , shift )
    array [ position ] = deinbuchstabe
    return array
    }
    else
    {
        array [ position ] = deinbuchstabe
        return array
    }
}
das wäre der pseudo code für eine rekursive methode

die kannst du umwandeln in eine for schleife falls dir das was hilft
 
Java:
weiterschieben( char array. int buchstabenposition im array , shift)
{
    dein buchstabe = array [ buchstabenposition ]
    position = possition buchstabenposition im array + shift
    if ( überlauf am ende )
    {
        position = position am anfang dann finden
    }
    if ( nicht am ende des arrays angelangt )
    {
    array = weiter schieben ( char array , buchstabenposition im array +1 , shift )
    array [ position ] = deinbuchstabe
    return array
    }
    else
    {
        array [ position ] = deinbuchstabe
        return array
    }
}
das wäre der pseudo code für eine rekursive methode

die kannst du umwandeln in eine for schleife falls dir das was hilft
Das funktioniert nicht so einfach. Mit einem Durchlauf ist es extrem tricky und nicht so einfach.

Einfach mal durchspielen mit den Fällen, die Kneitzel genannt hat.


Edit:
Wobei rekursiv kann es funktionieren, das stimmt.
Aber leider lässt sich das nicht in eine Schleife umwandeln ohne einen Stack = Zusätzliches Array zu nutzten.

Sprich eine rekursive Lösung ist im Sinne der Aufgabenstellung keine Hilfe.
 
Das funktioniert nicht so einfach. Mit einem Durchlauf ist es extrem tricky und nicht so einfach.

Einfach mal durchspielen mit den Fällen, die Kneitzel genannt hat.
woran sollte es scheitern, das array bleibt bis zum ende unverändert

und dann sortiert jede methode seinen buchstaben ein

das funktioniert da bin ich mir safe weil es an sich das einsortieren in 2 arrays gleichzusetzen ist
nur ich bleibe in einem array

ich sehe nicht worin das scheitern sollte
 
woran sollte es scheitern, das array bleibt bis zum ende unverändert

und dann sortiert jede methode seinen buchstaben ein

das funktioniert da bin ich mir safe weil es an sich das einsortieren in 2 arrays gleichzusetzen ist
nur ich bleibe in einem array

ich sehe nicht worin das scheitern sollte
Ich habs editiert, ich hab einen Denkfehler gehabt. Es funktioniert, ist aber keine Hilfe, weil es rekursiv ist und sich nicht in eine Schleife umwandeln lässt ohne ein zusätzliches array zu bauen.

Dafür bräuchtest du eine rekursive Lösung ohne die zusätzlichen lokalen Variabeln.
 
wenn man den durchlauf hat mit "abc" und shift 1 ist
ist es so
Methoden aufruf mit array
abc => a position 2=> weiterschieben
abc => b position 3=> weiterschieben
abc => c position 1=> am ende vom array dh jetzt einsetzen
c an position 1
b an position 2
a an position 3

und wehe jetzt kommt der array an stelle 0 haken xD
 
ich halte die aufgabe ein, kein zusätzliches array und verschieben, sehe kein problem damit es rekursiv zu machen


das ist das gleiche wie wenn du die türme von hanoi iterativ machen willst... toll ist anders
 
wenn man den durchlauf hat mit "abc" und shift 1 ist
ist es so
Methoden aufruf mit array
abc => a position 2=> weiterschieben
abc => b position 3=> weiterschieben
abc => c position 1=> am ende vom array dh jetzt einsetzen
c an position 1
b an position 2
a an position 3

und wehe jetzt kommt der array an stelle 0 haken xD
Du hast kein Array - aber bei der Umwandlung in eine Schleife brauchst du eins, weil du bei drei Rekursionen 3x die lokale Variable dein buchstabe hast.

Du musst du bei der rekursiven Lösung elemenieren. Ansonsten verletzt du die Aufgabenstellung, weil du den Call-Stack als Array implizit nutzt.
 
ich halte die aufgabe ein, kein zusätzliches array und verschieben, sehe kein problem damit es rekursiv zu machen


das ist das gleiche wie wenn du die türme von hanoi iterativ machen willst... toll ist anders
Ok, wenn man so argumentiert hast du durchaus recht - kommt jetzt auf die konkrete Aufgabenstellung an und was an Wissen bekannt & genutzt werden darf 🙂
 
Es funktioniert, ist aber keine Hilfe, weil es rekursiv ist
Doch schon. Es ist eine ganz interessante Sache. Es geht ja nur um das Array.

Also geht man rekursiv durch und merkt sich Platz und wert auf dem Hinweg und setzt es auf dem Rückweg.
Java:
    public static void shift(char[] chars, int shift) {
        shift(chars, shift, 0);
    }
    
    public static void shift(char[] chars, int shift, int pos) {
        if (pos >= chars.length) return;

        char value = chars[pos];
        shift(chars, shift, pos+1);
        chars[(pos+shift)%chars.length] = value;
    }

Den es geht hier ja rein akademisch um eine Vermeidung eines Arrays. Rekursion ist da durchaus eine gute Alternative, denn es wird kein Array verwendet.

Eine Idee, die mir auch durch den Kopf ging: Eine Queue der Länge shift verwenden - wobei das dann sehr ähnlich zu "Array" Datenstruktur ist.
 
Java:
void schieben (  array , shift )
    position = 0;
Character merker = array[0];
for ( i = 0 , array.length)
{
     position = ( position + shift ) % array.length
     Character zwischenspeicherFürMerker = array[position]
array[position] = merker;
merker = zwischenspeicherfürmerker
       
}

das ist das einfachste was ich mir vorstellen kann zu bauen als for schleife
man hüpft halt kreuz und quer durch das array

ist ungetestet
 
Java:
void schieben (  array , shift )
    position = 0;
Character merker = array[0];
for ( i = 0 , array.length)
{
     position = ( position + shift ) % array.length
     Character zwischenspeicherFürMerker = array[position]
array[position] = merker;
merker = zwischenspeicherfürmerker
      
}

das ist das einfachste was ich mir vorstellen kann zu bauen als for schleife
man hüpft halt kreuz und quer durch das array

ist ungetestet
Vielen lieben Dank. Es funktioniert noch nicht ganz, aber es ist bessergeworden:

Java:
    public static char[] shiftImproved(final char[] txt, final int shift) {
        int position = 0;
        char temp = txt[0];
        for (int i = 0; i <= txt.length; i++) {
            position = (position + shift) % txt.length;
            char temp2 = txt[position];
            txt[position] = temp;
            temp = temp2;
        }
        System.out.println("txt = " + Arrays.toString(txt));
        return txt;
    }

    public static void main(String[] args) {
        for (int i = 1; i < 10; i++) {
            System.out.println("i = " + i);
            shiftImproved("Guten Tag".toCharArray(), i);
        }
        for (int i = 1; i < 10; i++) {
            System.out.println("i = " + i);
            shiftImproved("Guten Tag!".toCharArray(), i);
        }
    }

i = 1
txt = [g, G, u, t, e, n, , T, a] ✅
i = 2
txt = [a, g, G, u, t, e, n, , T] ✅
i = 3
txt = [G, u, t, e, n, , G, a, g]
i = 4
txt = [ , T, a, g, G, u, t, e, n] ✅
i = 5
txt = [n, , T, a, g, G, u, t, e] ✅
i = 6
txt = [G, u, t, G, n, , T, a, g]
i = 7
txt = [t, e, n, , T, a, g, G, u] ✅
i = 8
txt = [u, t, e, n, , T, a, g, G] ✅
i = 9
txt = [G, u, t, e, n, , T, a, g] ✅

i = 1
txt = [!, G, u, t, e, n, , T, a, g] ✅
i = 2
txt = [T, u, g, e, G, , t, a, n, !]
i = 3
txt = [a, g, !, G, u, t, e, n, , T] ✅
i = 4
txt = [t, u, n, e, T, , g, a, G, !]
i = 5
txt = [G, u, t, e, n, , T, a, g, !] (✅)
i = 6
txt = [g, u, G, e, t, , n, a, T, !]
i = 7
txt = [e, n, , T, a, g, !, G, u, t] ✅
i = 8
txt = [n, u, T, e, g, , G, a, t, !]
i = 9
txt = [u, t, e, n, , T, a, g, !, G] ✅

Auffällig ist, dass es für i=3 nicht funktioniert, für 1, 2 und 4 hingegen schon. Woran liegt das? Kann es etwas mit "gerade"/"ungerade" zu tun haben? 🤔

Vielen Dank, diese Aufgabe ist sehr knifflig!
 
Java:
public static char[] shiftImproved(final char[] txt, final int shift) {
    int position = 0;
    char temp = txt[0];
    System.out.println(txt.length);
    boolean moduloProtect =txt.length % shift == 0;
    for (int i = 0; i < txt.length; i++) {

        position = ((position + shift)%txt.length);

        char temp2 = txt[position];
        System.out.println(position + " " +temp);
        txt[position] = temp;
        temp = temp2;
        if ( position == 0 && moduloProtect)
        {
            position = position +1 ;
            temp = txt[1];
        }
    }
    System.out.println("txt = " + Arrays.toString(txt));
    return txt;
}

public static void main(String[] args) {
    shiftImproved("Guten Ta".toCharArray(),2);
    shiftImproved("Guten Ta".toCharArray(),3);
}
}
ich muss mich entshculdigen da ich vergessen hatte mit einzukalkulieren dass sich die schleife im kreis drehen kann ... so funktioniert es

und jetzt siehst du diesen aufwand vs die rekursive variante
 
Ja stimmt

PS aber bei shift 3 und Array länge 9
Was macht da das modulo?
Pos 3,6, und nun
6 + 3 =9 und jetzt modulo 9 ist pos gleich 0 und nicht 9.

Deshalb ein klassisches prüfen.
jap hab ich gerade gepostet wie du gepostet hast... hab die korrektur eingebaut um den loop zu verhindern


es ist halt ... das problem war wie gemacht für rekursion xD
 
das problem lag daran
in der idee kommst du nie wieder bei der 0 an da sich der sprung in der mitte des strings überschniedet und somit kommst ud bei array[1] irgendwann an und dann kannst du die zweite hälfte bespringen

jedoch wenn shift ein teiler von dem array ist liefert der modulo zweimal 0

jedoch darfst du bei der idee nicht zweimal auf 0 kommen dh ich erzwinge es dass ich um 1 nach vorne geh um den sprung zu schaffen und nicht permanent auf 0 wieder zu kommen




ich hoffe ich habe dich nicht verwirrt dadurch aber es gehört dazu den fehler zu finden und nun musste ich den fehler sogar in miener eigenne logik finden was noch schlimmer ist xD
 
Wenn du vor der Schleife die pos auf shift setzt
In der Schleife erst
Merker2 =Array[pos-1]
Array[pos-1]=Merker1
Merker1=Merker2
Pos=pos+shift

Dann prüfen ob pos größer als das
Array ist wenn ja pos = pos - arrray Länge - 1

Wichtig die variable Pos ist immer eins mehr als der Index von dem Array.
Array[pos-1]=merker


Bei shift 3
Pos 3,6,9,2,5,8,1,4,7
Index 2,5,8,1 4,7,0,3,6

Bin nur am Handy und da ist coden schlecht. Deshalb so
 
So ganz kommplet ist der Code wie ich es beschrieben habe auch nicht wenn der shift grosser ist bei dem Beispiel 9 Felder ab shift 4
 
vom groben denken daran wie du es umsetzen möchtest wirst du auf folgenden fehler treffen

array der länge 10
pos = 0
shift = 3000 -> pos = 3000 - 10 -1
=> out of bounds

da du einen doppelten überlauf nicht behandelst soweit ich das erkennen kann



WAS MIR ZUSÄTZLICH EINFÄLLT

wenn 0 als shift übergeben wird sollte das gleiche array zurückgegeeben werden ansonsten läufst du in eine exception jedoch ist das gleiche array richtiger als in die exception zu laufen
und dass keine negativen zahlen übergeben werden dürfen, vllt macht man es mit einer richtung ob man von links oder von rechts shifted
 
vom groben denken daran wie du es umsetzen möchtest wirst du auf folgenden fehler treffen

array der länge 10
pos = 0
shift = 3000 -> pos = 3000 - 10 -1
=> out of bounds

da du einen doppelten überlauf nicht behandelst soweit ich das erkennen kann



WAS MIR ZUSÄTZLICH EINFÄLLT

wenn 0 als shift übergeben wird sollte das gleiche array zurückgegeeben werden ansonsten läufst du in eine exception jedoch ist das gleiche array richtiger als in die exception zu laufen
und dass keine negativen zahlen übergeben werden dürfen, vllt macht man es mit einer richtung ob man von links oder von rechts shifted
Habe ich auch schon gemerkt
 
... so funktioniert es
Funktioniert Post #32? Das Problem scheinen echt die Teiler der Eingabedatenlänge zu sein.

Ich mach jetzt FA, weil ich kapier heute echt gar nix mehr...

Danke euch für jede Anstrengung.

Aber hier nochmal schnell die Anforderungen:
- Verschiebung aller Zeichen um shift Stellen,
- iterativer Algorithmus,
- zusätzliche Speicherplatzanforderung: O(1),
- Laufzeitanforderung: O(n),
- clean code.
 
Funktioniert Post #32? Das Problem scheinen echt die Teiler der Eingabedatenlänge zu sein.

Ich mach jetzt FA, weil ich kapier heute echt gar nix mehr...

Danke euch für jede Anstrengung.

Aber hier nochmal schnell die Anforderungen:
- Verschiebung aller Zeichen um shift Stellen,
- iterativer Algorithmus,
- zusätzliche Speicherplatzanforderung: O(1),
- Laufzeitanforderung: O(n),
- clean code.
#32 sollte funktionieren aber keine angabe auf gewähr


dass es clean code wird müssen die cases die oben von mir genannt wurden noch implementiert werden
 
Tut mir leid, Mart. Du hast mir Blödsinn als eine valide Lösung verkauft:

Java:
    public static char[] shiftImproved(final char[] txt, final int shift) {
        int position = 0;
        char temp = txt[0];
        for (int i = 0; i < txt.length; i++) {
            position = (position + shift) % txt.length;
            char temp2 = txt[position];
            txt[position] = temp;
            temp = temp2;
            if (position == 0 && txt.length % shift == 0) {
                position = 1;
                temp = txt[1];
            }
        }
        System.out.println("txt = " + Arrays.toString(txt));
        return txt;
    }

    public static void main(String[] args) {
        for (int i = 1; i < 15; i++) {
            System.out.println("i = " + i);
            shiftImproved("Guten Tag".toCharArray(), i);
        }
        for (int i = 1; i < 15; i++) {
            System.out.println("i = " + i);
            shiftImproved("Guten Tag!".toCharArray(), i);
        }
    }

i = 1
txt = [g, G, u, t, e, n, , T, a]
i = 2
txt = [a, g, G, u, t, e, n, , T]
i = 3
txt = [T, n, t, G, u, , e, u, g] 💥

hmm ....
 
Tut mir leid, Mart. Du hast mir Blödsinn als eine valide Lösung verkauft:

Java:
    public static char[] shiftImproved(final char[] txt, final int shift) {
        int position = 0;
        char temp = txt[0];
        for (int i = 0; i < txt.length; i++) {
            position = (position + shift) % txt.length;
            char temp2 = txt[position];
            txt[position] = temp;
            temp = temp2;
            if (position == 0 && txt.length % shift == 0) {
                position = 1;
                temp = txt[1];
            }
        }
        System.out.println("txt = " + Arrays.toString(txt));
        return txt;
    }

    public static void main(String[] args) {
        for (int i = 1; i < 15; i++) {
            System.out.println("i = " + i);
            shiftImproved("Guten Tag".toCharArray(), i);
        }
        for (int i = 1; i < 15; i++) {
            System.out.println("i = " + i);
            shiftImproved("Guten Tag!".toCharArray(), i);
        }
    }

i = 1
txt = [g, G, u, t, e, n, , T, a]
i = 2
txt = [a, g, G, u, t, e, n, , T]
i = 3
txt = [T, n, t, G, u, , e, u, g] 💥

hmm ....
siehe kommentar #32


du bist noch auf dem alten stand
 
Java:
public static char[] shiftImproved(final char[] txt, final int shift) {
    int position = 0;
    char temp = txt[0];
    System.out.println(txt.length);
    boolean moduloProtect =txt.length % shift == 0;
    for (int i = 0; i < txt.length; i++) {

        position = ((position + shift)%txt.length);

        char temp2 = txt[position];
        System.out.println(position + " " +temp);
        txt[position] = temp;
        temp = temp2;
        if ( position == 0 && moduloProtect)
        {
            position = position +1 ;
            temp = txt[1];
        }
    }
    System.out.println("txt = " + Arrays.toString(txt));
    return txt;
}

public static void main(String[] args) {
    shiftImproved("Guten Ta".toCharArray(),2);
    shiftImproved("Guten Ta".toCharArray(),3);
}
}
ich muss mich entshculdigen da ich vergessen hatte mit einzukalkulieren dass sich die schleife im kreis drehen kann ... so funktioniert es

und jetzt siehst du diesen aufwand vs die rekursive variante
das da
 
Tut mir leid, Mart. Du hast mir Blödsinn als eine valide Lösung verkauft:

Java:
    public static char[] shiftImproved(final char[] txt, final int shift) {
        int position = 0;
        char temp = txt[0];
        for (int i = 0; i < txt.length; i++) {
            position = (position + shift) % txt.length;
            char temp2 = txt[position];
            txt[position] = temp;
            temp = temp2;
            if (position == 0 && txt.length % shift == 0) {
                position = 1;
                temp = txt[1];
            }
        }
        System.out.println("txt = " + Arrays.toString(txt));
        return txt;
    }

    public static void main(String[] args) {
        for (int i = 1; i < 15; i++) {
            System.out.println("i = " + i);
            shiftImproved("Guten Tag".toCharArray(), i);
        }
        for (int i = 1; i < 15; i++) {
            System.out.println("i = " + i);
            shiftImproved("Guten Tag!".toCharArray(), i);
        }
    }

i = 1
txt = [g, G, u, t, e, n, , T, a]
i = 2
txt = [a, g, G, u, t, e, n, , T]
i = 3
txt = [T, n, t, G, u, , e, u, g] 💥

hmm ....
ausserdem ist das dein code 😂
 
Also das Verschieben um eine Position nach rechts würde durch Vertauschen funktionieren:

[CODE title="Verschieben um eine Position nach rechts durch Vertauschen"]a b c d e

um eine Position tauschen

b a c d e
| |
+-+

b c a d e
| |
+-+

b c d a e
| |
+-+

b c d e a
| |
+-+
[/CODE]

Die nächste Idee wäre, dies zu skalieren:
[CODE title="Verschieben um zwei Positionen nach rechts durch Vertauschen"]a b c d e

um zwei Positionen tauschen

c b a d e
| |
+---+

c d a b e
| |
+---+

c d e b a
| |
+---+

c d e a b
| |
+-+
[/CODE]

Der letzte Tausch ist irgendwie komisch.

Ich habe keine Idee, dies in einen Algorithmus zu giessen.

Also ist IMHE mehrmals um eine Position Verschieben die einzig mögliche Lösung.
 
Ein Trick wäre noch, den Stack als Speicher für die temporären Merker zu verwenden, also einen rekursiven Algorithmus zu verwenden/erschaffen.

Das ist ein bisschen Betrug und meist ist die Stackgröße auch nicht besonders gross
 
Ein Trick wäre noch, den Stack als Speicher für die temporären Merker zu verwenden, also einen rekursiven Algorithmus zu verwenden/erschaffen.

Das ist ein bisschen Betrug und meist ist die Stackgröße auch nicht besonders gross
mein ding funktioniert ja nur er hat das falsche kopiert und es soll insitu ohne rekursion sein
 

Neue Themen


Zurück
Oben