Jedes zweite Element eines Arrays entfernen

Aloushi

Mitglied
Java:
public static String[] halfArray(String[] a) {

        String[] half;
        if ((a.length % 2) == 0) {
            half = new String[a.length / 2];
        } else {
            half = new String[a.length / 2 + 1];
        }

        for (int i = 0; i < a.length; i += 2) {
            for (int j = 0; j < half.length; j++) {
                half[j] = a[i];
            }

        }

return half;
}


Hallo, und zwar möchte ich gerne jedes zweite Element eines Arrays entfernen und das Ergebnis in einem neuen Array wiedergeben.
Bsp.: halfArray([“A“,“B“,“C“,“D“,“E“,“F“,“G“]) --> [“A“,“C“,“E“,“G“]
Bsp.: halfArray([“A“,“B“,“C“,“D“]) --> [“A“,“C“]

Sitze schon länger an der Aufgabe und komme leider zu keinem Ergebnis
 
Also als erstes: Die Erzeugung des Arrays hat er ja bereits. Sein Code lässt sich maximal noch verenfachen zu (a.length+1) / 2 als Länge des Arrays. Aber er hat eine funktionierende Lösung für das Ziel-Array.

Ich dachte, ich hätte es getan mit der for-schleife? Wüsste nicht, wie ich es genau anders machen soll.
Spiel Deine Zwei schleifen doch einmal durch. Was genau passiert da?

Für jedes zweite Element des ursprünglichen Arrays schreibst Du dieses in alle Felder? Das macht so relativ wenig Sinn fürchte ich 🙂

Also schreib einfach einmal auf: Welches Feld soll wohin kopiert werden?
0 -> 0
2 -> 1
4 -> 2
6 -> 3
...

Siehst Du da eine Gesetzmäßigkeit? Statt einer inneren Schleife brauchst Du also was?
 
Ich weiß gerade nicht genau wo mein Fehler liegt, damit ich verstehe worauf du genau hinaus möchtest.
Meiner Meinung nach erfülle ich ja mit den zwei Schleifen genau das:
0 -> 0
2 -> 1
4 -> 2
6 -> 3

Die eine Schleife läuft immer in zweier Schritten und die andere in einer Schritten und dann sollen die Werte übertragen werden
 
Nein, das Problem ist, dass die innere Schleife ja nicht parallel bzw. gleichzeitig zur äußeren Schleife läuft, sondern für jede Iteration der äußeren Schleife laufen immer alle Iterationen der inneren Schleife.
Die innere Schleife selbst läuft also half.length * a.length / 2 Mal.
 
Ah oke, vielen Dank. Wäre es möglich mir ein kleines Beispiel zu nennen, in dem es sinnvoll ist, mit einer äußeren und inneren Schleife zu arbeiten?

Also brauche ich statt der inneren Schleife ein einfaches Inkrement?
 
Also brauche ich statt der inneren Schleife ein einfaches Inkrement?
Du brauchst statt der einnen Zuweisung nur eine Zuweisung:

Die äußere Schleife läuft über alle Elemente, die kopiert werden müssen. Also musst Du nur noch kopieren.

Und da kannst Du dann eine weitere Variable nutzen, die Du dann erhöhst, oder Du nutzt einfach den Index, den Du schon hast und berechnest den Ziel-Index einfach.
 
Java:
for (int i = 0, k = 0; i < a.length; i += 2, k++) {
    half[k] = a[i];
          }

habe es so jetzt hinbekommen. wie würde es aussehen, wenn ich die zweite Variable im Anweisungsblock initialisieren möchte?

Code:
for (int i = 0; i < a.length; i += 2) {
            int j = 0;
            j++;
            half[j] = a[i];
        }

Beim zweiten ist irgendwas falsch
 
Java:
for (int i = 0, k = 0; i < a.length; i += 2, k++) {
    half[k] = a[i];
          }

habe es so jetzt hinbekommen. wie würde es aussehen, wenn ich die zweite Variable im Anweisungsblock initialisieren möchte?

Code:
for (int i = 0; i < a.length; i += 2) {
            int j = 0;
            j++;
            half[j] = a[i];
        }

Beim zweiten ist irgendwas falsch
Du setzt in jedem Schritt j zuerst auf 0 und dann auf 1.
Was du da vorhast, klappt nur, wenn j außerhalb gespeichert bleibt.
Falls du j nur für die Dauer der Schleife behalten willst (und es danach nicht mehr existieren soll), kannst du das Ganze noch in einen Block packen.
Java:
{
    int j = 0; //nur innerhalb dieses Blocks sichtbar, danach nicht mehr.
    for (int i = 0; i < a.length; i += 2) {
        half[j++] = a[i]; //erhöht j NACH Verwendung um 1
    }
}
 
Generell kann man bei sowas auch einfach auf eine zweite Variable verzichten:
Java:
for (int i = 0; i < a.length; i += 2) {
    half[i/2] = a[i];
}

Dazu diente ja die Aufstellung der Indices.

Die Verwendung von mehreren Variablen in einer Zählschleife empfinde ich als schwer lesbar und ich würde das immer versuchen zu vermeiden.
 
Grüß dich @Aloushi ,

mit Streams ist es eine andere, etwas kompliziertere Denkweise:
Java:
    public static int[] halven(int[] a) {
        return Stream.iterate(0, i -> i + 2).limit((a.length + 1) / 2).mapToInt(i -> a[i]).toArray();
    }

    public static void main(String[] args) {
        System.out.println(Arrays.toString(halven(new int[]{1})));
        System.out.println(Arrays.toString(halven(new int[]{1, 2, 3})));
        System.out.println(Arrays.toString(halven(new int[]{1, 2, 3, 4})));
        System.out.println(Arrays.toString(halven(new int[]{1, 2, 3, 4, 5})));
    }
 
Wenn schon Streams (Was für einen Anfänger so schlicht keinen Sinn macht, aber egal), dann würde ich zwei kleine Änerungen vornehmen:
a) Direkt mit IntStream arbeiten - dann wird aus dem mapToInt ein einfaches map und man hat generell nur int-Werte.
b) iterate hat auch eine Variante mit 3 Parametern, so dass man das limit nicht mehr benötigt und man hat nicht mehr eine berechnete Anzahl sondern nur noch die Array-Grenze:
Java:
    public static int[] halven(int[] a) {
        return IntStream.iterate(0, i -> i < a.length, i-> i+2)
                .map(i -> a[i])
                .toArray();
    }

Aber das sind so typische Dinge, die ich so nicht auf Zwang als Stream schreiben würde.
 
Stimmt, dann hat Stream.iterate und die funktionale Schreibweise ja gar keine Daseinsberechtigung... Gut, dass das nochmal richtiggestellt wurde...
Das ist ungefähr so, als würde man auf folgenden Code:
Java:
public static String isEvenNumber(int a) {
  if ((a % 2) == 0) return "true" else return "false";
}
die Anmerkung: "Du willst hier ja zwei Zustände (ja und nein) zurückgeben, also nehme lieber einen boolean."
dann kommentieren mit:
"Stimmt, dann hat String ja gar keine Daseinsberechtigung... Gut, dass das nochmal richtiggestellt wurde..."

Natürlich hat Stream.iterate() eine Daseinsberechtigung, aber _offensichtlich_ ist es das falsche Werkzeug, wenn man über int's iteriert.
Hinweis: Man kann ganz allgemeine Objekte per Stream.iterate() als Stream generieren, nicht nur integers.
 
@httpdigest Nicht auf neue Accounts von Tobias herein fallen 🙂

Wobei ich ja bei der Erwiderung schon gut fand, dass da ganz offensichtlich dem IntStream die funktionale Schreibweise abgesprochen wurde. Aber ich denke, darüber muss man nicht weiter nachdenken.
 

Zurück
Oben