Alle Array-Elemente um x weiterschieben

Könnt ihr mir sagen, wie die Methode filling_shift_in_place auch für zum Beispiel

filling_shift_in_place(new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}, 3);

funktionieren könnte?:

    public static void filling_shift_in_place(int[] a, int x) {
        if (a.length / x * x == a.length) {
            System.out.println("not solvable");
        }
        int to = a.length - ((x % 2 == 1) ? 1 : 0);
        int t2 = a[0];
        int first = t2;
        int j = 0;
        for (int i = 0; i < to; i++) {
            int k = getIndex(j, a.length, x);
            System.out.println(j + " <-> " + k);

            int t1 = a[k];
            a[j] = a[k];
            a[k] = t2;
            t2 = t1;
            j = k;
        }
        a[j] = first;
        System.out.println(Arrays.toString(a));
    }

    public static int getIndex(int i, int n, int x) {
        return (i + x) % n;
    }

    public static void main(String[] args) {
        filling_shift_in_place(new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 3);
        filling_shift_in_place(new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 3);
        filling_shift_in_place(new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}, 5);
        filling_shift_in_place(new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}, 3);
    }

Oder ist das schon theoretisch ausgeschlossen? Danke vorab.

(Beitrag vom Verfasser gelöscht)

Habe noch einmal „genau“ (nach bester Sorgfalt …) überlegt, und ein paar Tests hinzugefügt … So würde es für alle Fälle (auch für negative) funktionieren:

    public static void filling_shift_in_place(int[] a, int x) {
        if (x < 0) {
            x = a.length - x;
        }
        x = (x + a.length) % a.length;
        if (x == 0) {
            System.out.println(Arrays.toString(a));
            return;
        }

        while (x >= a.length / 2 || x % 2 == 0 || a.length / x * x == a.length) {
            for (int i = 0; i < a.length - 1; i++) {
                int t1 = a[i + 1];
                a[i + 1] = a[i];
                a[i] = t1;
            }
            x--;
            if (x == 0) {
                System.out.println(Arrays.toString(a));
                return;
            }
        }

        int to = a.length - 1;
        int t2 = a[0];
        int first = t2;
        int j = 0;
        for (int i = 0; i < to; i++) {
            int k = getIndex(j, a.length, x);
            // System.out.println(j + " <-> " + k);

            int t1 = a[k];
            a[j] = a[k];
            a[k] = t2;
            t2 = t1;
            j = k;
        }
        a[j] = first;
        System.out.println(Arrays.toString(a));
    }

    public static int getIndex(int i, int n, int x) {
        return (i + x) % n;
    }

    public static void main(String[] args) {
        // test with odd number of elements
        for (int i = 0; i <= 20; i++) {
            int len = 5;
            int x = i - 10;
            int[] a = new int[len];
            for (int j = 0; j < len; j++) {
                a[j] = j + 1;
            }
            System.out.println("len: " + len + ", x: " + x);
            filling_shift_in_place(a, x);
            System.out.println();
        }

        // test with even number of elements
        for (int i = 0; i <= 20; i++) {
            int len = 6;
            int x = i - 10;
            int[] a = new int[len];
            for (int j = 0; j < len; j++) {
                a[j] = j + 1;
            }
            System.out.println("len: " + len + ", x: " + x);
            filling_shift_in_place(a, x);
            System.out.println();
        }
    }

Kleine Gegenfrage: Kannst du die Methode f so umschreiben, dass sie auch mit geraden Zahlen funktioniert?

class A
{
    public static void main(String args[])
    {
        int n = 5;
        int a[][] = new int[n][n];
        f(n,1,n/2,n-1,a);
        print(a);
    }

    static int f(int ì,int i,int í,int î,int ï[][])
    {
        return i>ì*ì?i-1:(ï[í][î]=f(ì,i+1,(í+(i%ì==0?0:1))%ì,(î+(i%ì==0?-1:1))%ì,ï))-1;
    }

    public static void print(int a[][])
    {
        for (int i=0; i<a.length; i++)
        {
            for (int j=0; j<a[i].length; j++)
            {
                System.out.print((a[j][i]<10?" ":"")+a[j][i]+" ");
            }
            System.out.println();
        }
    }
}

Ist diese ernstgemeint?

Ich gebe zu, dass die Bezeichnungen: to, t1, t2, j und k ganz ungünstig/suboptimal von mir gewählt wurden. :frowning:

Wäre es für den @Marco13 denn so besser?

    public static void filling_shift_in_place(int[] a, int x) {
        if (x < 0) {
            x = a.length - x;
        }
        x = (x + a.length) % a.length;
        if (x == 0) {
            return;
        }

        while (x >= a.length / 2 || x % 2 == 0 || a.length / x * x == a.length) {
            for (int i = 0; i < a.length - 1; i++) {
                int temp = a[i + 1];
                a[i + 1] = a[i];
                a[i] = temp;
            }
            x--;
            if (x == 0) {
                return;
            }
        }

        int firstElement = a[0];
        int tempIndex = 0;
        int limit = a.length - 1;
        for (int i = 0; i < limit; i++) {
            int jumpIndex = getJumpIndex(tempIndex, a.length, x);

            // swap a[tempIndex] and a[jumpIndex]:
            int tempElement = a[jumpIndex];
            a[jumpIndex] = a[tempIndex];
            a[tempIndex] = tempElement;
            tempIndex = jumpIndex;
        }
        a[tempIndex] = firstElement;
    }

    public static int getJumpIndex(int currentIndex, int n, int x) {
        return (currentIndex + x) % n;
    }

    public static void main(String[] args) {
        // test with odd number of elements
        for (int i = 0; i <= 20; i++) {
            int len = 5;
            int x = i - 10;
            int[] a = new int[len];
            for (int j = 0; j < len; j++) {
                a[j] = j + 1;
            }
            System.out.println("len: " + len + ", x: " + x);
            filling_shift_in_place(a, x);
            System.out.println(Arrays.toString(a));
            System.out.println();
        }

        // test with even number of elements
        for (int i = 0; i <= 20; i++) {
            int len = 6;
            int x = i - 10;
            int[] a = new int[len];
            for (int j = 0; j < len; j++) {
                a[j] = j + 1;
            }
            System.out.println("len: " + len + ", x: " + x);
            filling_shift_in_place(a, x);
            System.out.println(Arrays.toString(a));
            System.out.println();
        }
    }

Ich mein wohin dieser Thread hingeht, ist jedem klar. Aber denkst du wirklich, dass dein „Quellcode“ irgendwas mit programmieren zu tun hat?

Gehst du davon aus, dass jemand im Büro auf dich zukommt und sagt: Programmiere irgendeine Funktion, die irgendwas macht mit X und Y und Z und Q und F und T und B und L und N?

Denkst du, dass du mit deinem Quellcode, der irgendwas, möglichst kryptisch und vor allem Fremd jeglicher praktischer Anwendung ist, irgendwen beeindruckt. So nach dem Motto:

Seht her meine While schleife hat drei Bedinungen.

        while (x >= a.length / 2 || x % 2 == 0 || a.length / x * x == a.length) {

Hier alleine sieht man, dass man sich irgendwas ausgedacht hat, das nix mit der Aufgabe und nix mit Entwicklung zu tun hat. Da muss man nur 2 Minuten drüber nachdenken, wann

a / x^2 = a ist. Das geht ja nur für x^2 = 1 und dann kann ich auch schreiben x == 1. Aber das ist sinnlos, weil ja auch gilt:

x >= a.length / 2

Und ob x nun gerade oder ungerade ist oder 1 ist wurscht, denn diese Bedingung ist inkludiert in der Menge der wahren Ergebnise von x >= a.length.

Füge doch einfach noch || x > 0 und x - 1 > -1 und sowas hinzu. Dann wird das noch besser und vor allem KOMPLEXER. Und das wird uns total beeindrucken. Nicht.

Und den Posting von Marco hast du nichteinmal verstanden oder verstehen wollen. Denn zusätzlich zu deiner notirisch falschen Wahl von Variablennamen, kommt deine Zwangsstörung dazu, einfache Dinge super komplex und unübersichtlich zu implementieren. Und alle fragen sich… Warum?

Ich mein, dass ich das hier für umme schreibe, ist mir klar. Ebenfalls ist mir auch egal, was du darauf antwortest.

Entweder du lernst ernsthaft Java und machst was sinnvolles. Oder du lässt es. Aber das, was du machst, ist scheiße. Und das weißt du.

Wenn man keine Ahnung hat, bitte das (Fr)-Esswerk halten, danke. Aber der Grund ist ganz einfach: Weil man es abgesehen von den Variablennamen nicht besser implementieren kann. Und ich weiß, wovon ich spreche, ich bin Mathematiker.

Du bist vermutlich alles Mögliche, was mit „-iker“ aufhört, aber „Mathemat-“ sicher nicht. Wie das hier läuft, war ja vorhersehbar, also wie üblich: Sperre.

2 Likes

Aber manchmal macht das halt Spaß, in Anlehnung an den https://www.ioccc.org/ :

package bytewelt;
import java.util.Arrays;
public class ArrayShift
{
  public static void shift(int[] î, int j)
  {
    int i,I,ï,í=0,ì=0,l=î.length;
    while(ì!=l){I=î[í];i=í;do{i=(i-j+l)%l;ï=î[i];î[i]=I;I=ï;ì++;}while(i!=í);í++;}
  }
  public static void test(int[] a, int x)
  {
    System.out.println("Before: " + Arrays.toString(a)+", shifting left by "+x);
    shift(a, x);
    System.out.println("Result: " + Arrays.toString(a));
  }
  public static void main(String[] args)
  {
    test(new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 3);
    test(new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 3);
    test(new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}, 5);
    test(new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}, 3);
  }
}

Interessanterweise besser lesbar, als der Code von CB.