Anfang von Wörtern in Java Array?

3 Antworten

Vom Fragesteller als hilfreich ausgezeichnet

Wieder mehrere Probleme.

  1. In deiner for-Schleife gehst du jeden Buchstaben und nicht jedes Wort durch. Also, wenn du z.B. im Text "Ich bin ein Berliner" nach "ch" suchst, prüft deine Routine in der ersten Runde, ob "Ich bin ein Berliner" mit "ch" anfängt und in der nächsten Runde sucht er im Text "ch bin ein Berliner" und packt das Ergebnis in das Array.
  2. Der Grund für das Problem, was du gefunden hast: Wenn du ein Ergebnis gefunden hast, kürzt du die Variable text auf das Ergebnis. Also bei meinem Beispiel oben hättest du dann das "ch" von "ch bin ein Berliner" gefunden und setzt dann text auf "ch", wodurch du natürlich nicht noch mehr findest.

Ich geb dir mal wieder zwei Varianten. Einmal, wie ich es normalerweise machen würde, mit regulären Ausdrücken:

public static String[] getWordsStartWith(String text, String start) {
    return Pattern
            // Das Symbol \\b bedeutet "word boundary", also Start oder Ende eines Wortes
            // Danach starten wir eine "capture group" (die Klammern), womit wir sagen,
            // dass wir den Teil im Ergebnis haben wollen
            // Dann kommt das, was wir suchen und danach noch beliebig viele "word characters"
            // also Buchstaben oder Zahlen
            // Case_Insensitive ist klar. Das "Unicode_Character_Class" sorgt dafür, dass z.B.
            // auch Umlaute als Buchstaben erkannt werden.
            .compile("\\b(" + Pattern.quote(start) + "\\w*)", Pattern.CASE_INSENSITIVE + Pattern.UNICODE_CHARACTER_CLASS)
            .matcher(text)
            .results()
            // Diesmal wollen wir nur das haben, was jeweils in der ersten "capture group" gefunden wurde
            .map(match -> match.group(1))
            .toArray(String[]::new);
}

und einmal die Alternative per Scanner:

public static String[] getWordsStartWith(String text, String start) {
    // Erstmal text und start in Kleinbuchstaben umwandeln
    text = text.toLowerCase();
    start = start.toLowerCase();
    
    // Der Scanner kann uns gleich den Text immer Wortweise geben
    Scanner scanner = new Scanner(text);
    
    // Mit der List müssen wir uns nicht darum kümmern, dass wir
    // von Anfang an die richtige Größe wissen müssen.
    List<String> result = new LinkedList<>();
    
    // Wir gehen jedes Wort im Scanner durch
    while (scanner.hasNext()) {
        String word = scanner.next();
        // und fügen es ans Ergebnis an, falls es mit <start> anfängt
        if (word.startsWith(start))
            result.add(word);
    }
    scanner.close();
    
    // Zum Schluss müssen wir es noch in ein Array umwandeln, bevor
    // wir es zurückgeben.
    return result.toArray(String[]::new);
}
orochi02  03.05.2022, 12:18

ich glaube man muss den scanner nicht schließen

0
daCypher  04.05.2022, 08:32
@orochi02

Hmm, stimmt. Eclipse zeigt mir eine Warnmeldung an, wenn ich den Scanner nicht schließe, aber eigentlich sollte es egal sein, wenn man den Scanner mit einem String initialisiert. Nur bei Dateien oder bei System.In sollte man ihn immer explizit schließen.

1

Splitte den Text ersteinmal in seine einzelnen Komponenten (am ',' aufteilen und die Klammern vorne und hinten entfernen, zudem die Leerzeichen).

Dann kannst du über die Komponenten iterieren und für jede entscheiden, ob die Bedingung erfüllt ist oder nicht, entsprechend diese zur Ausgabe hinzufügen.

Zum Aufteilen von Strings kannst du z.B. String.split verwenden. String.trim und String.substring können dabei helfen, Leerzeichen und klammern zu entfernen.
Du kannst aber auch direkt mit RegEx arbeiten.

simpel aber naiv:

var words = text.split(" ");
return Stream.of(words)
    .filter(word -> word.toLowerCase().startsWith(start.toLowerCase()))
    .toArray(String[]::new);
daCypher  04.05.2022, 08:41

Muss natürlich ...startsWith(start.toLowerCase())... heißen. Würde auch mit dem Scanner gehen:

return new Scanner(text).tokens()
        .filter(word->word.toLowerCase().startsWith(start.toLowerCase()))
        .toArray(String[]::new);
1