Arrays vergleichen

Man kann natürlich auch einfach streichen.

  1. Sind die Arrays A und B gleich lang? Falls nicht, gib false zurück.
  2. Für jedes Element aus A: suche ein Element mit dem gleichen Wert in B. Falls gefunden: streiche, das Element, ansonsten gib false zurück.
  3. Gib true zurück.
Beispiel:

A={1,2,3,4,5,1}, B={5,1,3,2,1,4}

Arrays sind gleich lang, also weiter.

1. Element aus A = 1 -> streiche das erste Vorkommen von 1 aus B -> B = {5,-,3,2,1,4}
2. Element aus A = 2 -> streiche das erste Vorkommen von 2 aus B -> B = {5,-,3,-,1,4}
3. Element aus A = 3 -> streiche das erste Vorkommen von 3 aus B -> B = {5,-,-,-,1,4}
4. Element aus A = 4 -> streiche das erste Vorkommen von 4 aus B -> B = {5,-,-,-,1,-}
5. Element aus A = 5 -> streiche das erste Vorkommen von 5 aus B -> B = {-,-,-,-,1,-}
6. Element aus A = 1 -> streiche das erste Vorkommen von 1 aus B -> B = {-,-,-,-,-,-}

Da jedes Element aus A in B gestrichen werden konnte -> true

Wäre z. B. B = {5,1,3,2,6,4} gewesen, dann hätte im 6. Schritt die zweite 1 aus A nicht in B gestrichen werden können -> false.
Ich habe mich jetzt nochmal hingesetzt und versucht, das Problem zu lösen. Hab mit dem von dir beschriebenen Ansatz angefangen und konnte die Aufgabe jetzt in einem ziemlich simplen und überschaubaren Code lösen:
Java:
public class A5_main {

public static boolean compareArraysVal(int [] a, int [] b) {
     
     
        Arrays.sort(a);
        Arrays.sort(b);
        if (a.length == b.length && Arrays.equals(a,b)) {
            return true;
        }
        return false;
}

public static void main (String [] args) {
        int[] a = {5,4,3,2,1};
        int[] b = {1,2,3,4,5};
         System.out.println(compareArraysVal(a, b));
         System.out.println(compareArraysVal(a, a));
    }}


Wenn ich diesen Code ausführe, bekomme ich zweimal true, also Reihenfolge egal, nur gleiche Länge und gleiche Werte werden geprüft.
Natürlich habe ich hier eine Abkürzung genommen, aber ich habe auch versucht, die Aufgabe ohne die Abkürzung zu lösen.

Java:
 public class A5_main


public static boolean compareArraysVal(int [] a, int [] b) {
     
        Arrays.sort(a);
        Arrays.sort(b);
        if (a.length == b.length) {    //Prüfung auf gleiche Länge
            return true;
        }
            return false;
        }
 
    int [] c = new int [a.length -1];   // zweites Arrays von a -1, um die Werte streichen zu können
    int [] d = new int [b.length -1];   //zweites Array für b -1, um die Werte streichen zu können
    int removeIndex = 0;                // Index, der gestrichen werden soll
 
    for (int i =0; i < removeIndex; i++) {
        for(removeIndex = 0; removeIndex < a.length && removeIndex < b.length; removeIndex++);  // ist der Index kleiner als die Länge a, dann Index erhöhen. Index soll hier erhöht werden, da das Programm ja sonst nicht starten würde (mit 0)                                                                                                                                    

    }
        c[i] = a[i];    // Index des neuen arrays -1 = dem Index von a
        d[i] = b[i];
    }
    for (int i = removeIndex +1; i < a.length && i < b.length; i++) {
        c[i-1] = a[i];     // hier soll der  Index von a entfernt und an c zugewiesen werden
        d[i-1] = b[i];
    }
}

public static void main (String [] args) {
    int[] a = {5,4,3,2,1};
    int[] b = {1,2,3,4,5};
     System.out.println(compareArraysVal(a, b));
     System.out.println(compareArraysVal(a, a));
}}



Ich kann das Programm jetzt nicht prüfen, weil sich einige Fehler eingeschlichen haben z.B. in Z.17&18: "a cannot be resolved into a variable", aber das liegt wahrscheinlich an einer fehlerhaften Zeichensetzung.

Mich würde jetzt nur interessieren, ob die Idee richtig war, ich habe ja bereits einen funktionierenden Code.
 
und konnte die Aufgabe jetzt in einem ziemlich simplen und überschaubaren Code lösen:
Das ist aber der Ansatz über das Sortieren 🙂 Das Sortieren wollte ich ja gerade umgehen.

weil sich einige Fehler eingeschlichen haben z.B. in Z.17&18: "a cannot be resolved into a variable", aber das liegt wahrscheinlich an einer fehlerhaften Zeichensetzung.
Das liegt an der schlechten Formatierung. Wenn Du ordentlich einrücken würdest, würdest Du sofort sehen, dass die Methode compareArrayVal() in Zeile 12 endet, der folgende Code also unzulässigerweise außerhalb einer Methode liegt.

Die Frage, wie "gestrichen" wird, hatte ich offen gelassen. Das kann man z. B. mit einem boolean Array lösen:
Java:
public static boolean compareArrayVals(int[] a, int[] b) {
    if (a.length != b.length) {
        return false;
    }

    int n = a.length;
    boolean gestrichen[] = new boolean[n];

    for (int wert : a) {
        // suche das erste Element in b mit dem Wert wert,
        // das noch nicht gestrichen wurde
        int ix = 0;
        while (ix < n && (gestrichen[ix] || b[ix] != wert)) {
            ix++;
        }

        // wurde ein solches Element gefunden?
        if (ix < n) {
            gestrichen[ix] = true; // streichen
        } else {
            return false; // ansonsten sind die Array unterschiedlich
        }
    }

    // alle Werte aus a konnten in b gestrichen werden -> Arrays "gleich"
    return true;
}
Anzumerken wäre noch, dass man den kommentierten Code durch entsprechende Methoden ersetzen würde. Natürlich ist das Streichen nur eine Möglichkeit. Man kann z. B. auch Elemente im Array vertauschen, oder eben auch sortieren.
 
Also das:
Java:
public static boolean compareArraysVal(int [] a, int [] b) {
 
 
        Arrays.sort(a);
        Arrays.sort(b);
        if (a.length == b.length && Arrays.equals(a,b)) {
            return true;
        }
        return false;
}
kann man auch einfach so schreiben:
Java:
public static boolean compareArraysVal(int [] a, int [] b) {
        Arrays.sort(a);
        Arrays.sort(b);
        return Arrays.equals(a,b);
}
Der Längenvergleich wird da schon mit erledigt. Bei den meisten Anfängeraufgaben dürfen aber die Methoden aus dem JDK nicht verwendet werden, da der Umgang mit Schleifen geübt werden soll.

Durch das sortieren wird aber die Anforderung: "wenn die Werte, die in a und in b enthalten sind, gleich sind und gleich oft vorkommen und in der gleichen Reihenfolge in den jeweiligen Arrays enthalten sind." nicht erfüllt, die Reihenfolge wird ja u.U. verändert und ist damit nicht mehr vergleichbar.

Also einfach:
Java:
public static boolean compareArraysVal(int [] a, int [] b) {
        return Arrays.equals(a,b);
}

dann kann man noch ins JDK schauen, was Arrays.equals eigentlich macht:
Java:
    /**
     * Returns <tt>true</tt> if the two specified arrays of ints are
     * <i>equal</i> to one another.  Two arrays are considered equal if both
     * arrays contain the same number of elements, and all corresponding pairs
     * of elements in the two arrays are equal.  In other words, two arrays
     * are equal if they contain the same elements in the same order.  Also,
     * two array references are considered equal if both are <tt>null</tt>.<p>
     *
     * @param a one array to be tested for equality
     * @param a2 the other array to be tested for equality
     * @return <tt>true</tt> if the two arrays are equal
     */
    public static boolean equals(int[] a, int[] a2) {
        if (a==a2)
            return true;
        if (a==null || a2==null)
            return false;

        int length = a.length;
        if (a2.length != length)
            return false;

        for (int i=0; i<length; i++)
            if (a[i] != a2[i])
                return false;

        return true;
    }
Also genau das, auf was du die ganze Zeit hingewiesen wurdest.
 
Zuletzt bearbeitet:
Durch das sortieren wird aber die Anforderung: "wenn die Werte, die in a und in b enthalten sind, gleich sind und gleich oft vorkommen und in der gleichen Reihenfolge in den jeweiligen Arrays enthalten sind." nicht erfüllt,
Diese Anforderung war im Thread abgehakt und es wurde dann die Frage behandelt, wie man vorgeht, wenn die Reihenfolge keine Rolle spielen soll. Wir hatten uns daher von den ursprünglichen Anforderungen entfernt.
 
Das ist aber der Ansatz über das Sortieren 🙂 Das Sortieren wollte ich ja gerade umgehen.


Das liegt an der schlechten Formatierung. Wenn Du ordentlich einrücken würdest, würdest Du sofort sehen, dass die Methode compareArrayVal() in Zeile 12 endet, der folgende Code also unzulässigerweise außerhalb einer Methode liegt.

Die Frage, wie "gestrichen" wird, hatte ich offen gelassen. Das kann man z. B. mit einem boolean Array lösen:
Java:
public static boolean compareArrayVals(int[] a, int[] b) {
    if (a.length != b.length) {
        return false;
    }

    int n = a.length;
    boolean gestrichen[] = new boolean[n];

    for (int wert : a) {
        // suche das erste Element in b mit dem Wert wert,
        // das noch nicht gestrichen wurde
        int ix = 0;
        while (ix < n && (gestrichen[ix] || b[ix] != wert)) {
            ix++;
        }

        // wurde ein solches Element gefunden?
        if (ix < n) {
            gestrichen[ix] = true; // streichen
        } else {
            return false; // ansonsten sind die Array unterschiedlich
        }
    }

    // alle Werte aus a konnten in b gestrichen werden -> Arrays "gleich"
    return true;
}
Anzumerken wäre noch, dass man den kommentierten Code durch entsprechende Methoden ersetzen würde. Natürlich ist das Streichen nur eine Möglichkeit. Man kann z. B. auch Elemente im Array vertauschen, oder eben auch sortieren.
Hab jetzt versucht, den kommentierten Code mit den entsprechenden Methoden zu ersetzen.

Ich bin nicht weit gekommen und dazu ist der Code auch noch falsch. Ich glaube, dass ist noch zu hoch für mich und ich muss mich erstmal darum kümmern, die Aufgabenblätter zu erledigen, statt zu viel Zeit mit den verschiedenen Möglichkeiten, einen Code zu schreiben, zu verbringen.

Java:
package a5;

import java.util.Arrays;

    public class A5_main {

    public static boolean compareArraysVal(int [] a, int [] b) {
        
        
        if (a.length != b.length) {
            return false;
        }
        int n = a.length;
        boolean gestrichen [] = new boolean [n];
        
        for (int wert : a) {
            
            if (int [a] < n &&  a != b; a++) {  // Meine Ergänzung/Idee:
                 b++;                                   // Wenn ein Wert aus a kleiner ist als die Länge,
                                                         // und array a ungleich array b ist, dann soll der nächste Wert aus a geprüft werden
            }   
        int ix = 0;
        while (ix < n && (gestrichen[ix] || b[ix] != wert)) {
            ix++;
        }

        // wurde ein solches Element gefunden?
        if (ix < n) {
            gestrichen[ix] = true; ix-- // soll das gleiche Element entfernen
        } else {
            return false; // ansonsten sind die Array unterschiedlich
        }
    }

    // alle Werte aus a konnten in b gestrichen werden -> Arrays "gleich"
    return true;
}
 
Sorry, aber Dein Code macht so keinen Sinn. Und Du hast da sehr viel vermischt in Zeile 18. Da hast Du ein if, aber teilweise scheint es, als wolltest Du eine for Schleife. Aber eine Variable deklarierst Du da auch nicht... Dann das a++ macht keinen Sinn, denn a ist doch eines der Arrays.
 
Ich war verwirrt, weil du geschrieben hast, dass man den Code mit den entsprechenden Methoden ersetzen soll und hab versucht, da noch irgendwas reinzubasteln.
Ach so. Das war nur der obligatorische Wink auf Clean Code. Wenn man - wie in diesem Fall - mit Kommentaren erklärt, was der Code macht, dann ist das ein sicheres Zeichen dafür, dass man den kommentierten Code in Methoden auslagern sollte.

Zum Beispiel habe ich hier
Java:
        // suche das erste Element in b mit dem Wert wert,
        // das noch nicht gestrichen wurde
        int ix = 0;
        while (ix < n && (gestrichen[ix] || b[ix] != wert)) {
            ix++;
        }
im Kommentar erklärt, was der kommentierte Code macht. Ein Kommentar ist aber toter Text und statt hier großartig zu erklären, was das Ding macht, kann man den Spaß auch einfach in eine Methode auslagern und den Kommentar (inkl. des Codes) ersetzen durch:
Java:
    int ix = sucheZuStreichendesElement(wert, b, gestrichen);

Wenn man das vervollständigt, dann sieht die Schleife so aus:
Java:
    for (int wert : a) {
        int ix = sucheZuStreichendesElement(wert, b, gestrichen);
        if (elementGefunden(ix)) {
            gestrichen[ix] = true; 
        } else {
            return false; 
        }
    }
Das ist noch nicht wirklich schön, aber zumindest wird dem Leser mit einem Blick auf den Code (nicht Kommentar!) nun wesentlich schneller deutlich, worum es in der Schleife geht.

Warum ist der Code immer noch nicht wirklich schön? Weil das "Streichen" ein Implementierungsdetail ist, auf das hier sehr stark Bezug genommen wird. Das kann man ändern, führt hier aber etwas zu weit.
 

Zurück
Oben