Satzarten bestimmen

der Fehler ist so trivial, dass für Antworter hier, auch mich, etwas peinlich nicht zuvor geantwortet zu haben,
wirft aber auch ein Licht auf deinen nicht vorhandenen Beitrag,

hast du nicht die geringsten eigenen Untersuchungen angestellt?
die beiden Parameter sind einmal der aktuelle ‘sentence’ sowie die immer gleiche ‘eingabe’, der Gesamtstring,
sentence wird in der Methode nicht verwendet, immer nur eingabe…

wieso überhaupt zwei Parameter, welcher hat welchen Sinn?
das erscheint ja nun stark zusammengewürfelt, in dem Stadium kann jede Variable, jede Code-Zeile falsch sein,
lohnt gar nicht recht, nach Fehlern zu suchen

Ich habe zwar einige Zeit herumprobiert, allerdings kam ich gestern einfach nicht auf die Loesung. Deine Verstimmung ist nur nachvollziehbar. Das haette mir nicht passieren duerfen. Da aendere ich alles ab und komme nicht auf die Idee, dass ich auch die Variable innerhalb des Strings aendern muss. Das ich wegen so eines dummen Fehlers andere Menschen beheillige darf natuerlich nicht sein.

von Entschuldigung und Verstimmung will ich nichts hören,
der Fehler ist auch nicht schlimm, passiert mir 10x am Tag,

man muss dann einfach nur strukturiert vorgehen, in der Methode mit System.out.println() anschauen, was als satzAnfang herauskommt,
wovon das abgesplittet wird, schon Problem gefunden

Arbeit von Sekunden statt Tage im Forum zu warten, ohne nötige Kreativität, vertieftes Java-Wissen, ohne echte Chance die Lösung zu verpassen,
einfach anfangen, herausfinden, fertig

anderen gegenüber musst du dich nicht rechtfertigen, für deine eigene Effizienz aber besser überlegen, wie du vorgehst

Und wieder Mal muss ich Euch auf die Nerven gehen…

Ich habe ein Main-Programm, dass festlegt, dass die Ausgabe:
String ausgabe = (Satzarten.satzAntworten(eingabeAusgeschrieben));
ist (Der String “eingabeAusgeschrieben” ist ein System.in). Diese verweist wie man sieht auf auf die andere Classe Satzarten:

import java.text.BreakIterator;
import java.util.*;

public class Satzarten {
    
   static String satzAntworten (String eingabeAusgeschrieben){      
                
        String satzAntworten = null;
       
        BreakIterator breaker = BreakIterator.getSentenceInstance();
        breaker.setText(eingabeAusgeschrieben);
        int index = 0;
        while (breaker.next() != BreakIterator.DONE) {
                    String einzelSaetze = satzart(eingabeAusgeschrieben.substring(index, breaker.current()));
                               index = breaker.current();
                satzAntworten = einzelSaetze;                
                return satzAntworten;
            }
                
      return satzAntworten;
     } 
   
   private static String satzart(String einzelSaetze){
       
             
       String satzZeichen = einzelSaetze.substring(einzelSaetze.length()-1);
       String[] satzteile = einzelSaetze.split("\\s");
       String satzAnfang = satzteile[0];
                             
       Collection<String> wFragen= Arrays.asList("wessen", "wer", "wie", "welche", "was", "wem", "wann", "wo", "wohin", "weshalb", "wieso", "warum", "weswegen", "inwiefern", "inwieweit");
       Collection<String> verb= Arrays.asList("geh\u00f6rt", "ist", "hat" );
       
       String satzOhneZeichen = einzelSaetze.replaceAll("[\\\\.,-/]", "");
       
       String satzart;
              
       if (einzelSaetze.equals(satzAnfang)){
                satzart = "C";
        }
        
        else if (satzZeichen.equals("?")){
        
               if (wFragen.contains( satzAnfang.toLowerCase() )){
                 satzart = "A";
                }
                else {
                 satzart ="B";  
                }
        }
        else 
        {
            if (verb.contains( satzteile[1].toLowerCase() )){  
                satzart = "D"; 
             }
            else if ((verb.contains( satzAnfang.toLowerCase() ))) {
                         
            satzart = "E";
            }
            else {
            satzart = "F";    
            } 
             
      }
       return satzart;
     }
}

Wenn ich nur einen Satz eingebe funktioniert auch alles wunderbar. Bei mehreren leider nicht mehr, denn er gibt dennoch nur einen Satz aus.

Der Fehler wird allem Anschein nach zwischen der Satzzerlegung und ** private static String satzart(String einzelSaetze)**
liegen. Als Argument hat **private static String satzart(String einzelSaetze) **den String einzelSaetze, der eigentlich jeder einzelne Satz sein soll. Hier vermute ich die Probleme. Bevor ich das ganze an das Hauptprogramm uebergeben habe und statt des Strings ein System.Out.println hatte gab er mir auch tatsaechlich fuer jeden einzelnen Satz etwas aus.

Folglich kann man das Problem hier lokalisieren:

   static String satzAntworten (String eingabeAusgeschrieben){      
                
        String satzAntworten = null;
       
        BreakIterator breaker = BreakIterator.getSentenceInstance();
        breaker.setText(eingabeAusgeschrieben);
        int index = 0;
        while (breaker.next() != BreakIterator.DONE) {
                    String einzelSaetze = satzart(eingabeAusgeschrieben.substring(index, breaker.current()));
                               index = breaker.current();
                satzAntworten = einzelSaetze;                
                return satzAntworten;
            }
                
      return satzAntworten;
     } 

Vermutlich ist es falsch einen String anzulegen, jedoch komme ich nicht auf eine andere Loesung, da hier mein Wissen aufhoert.

Eigentlich wollte ich, dass mir das Programm einen Fertigen String ausgibt, der jeden Satz des Ausgangsstrings einzeln durchgearbeitet hat und sie dann wieder zu einem String zusammen gesetzt hat.

etwas komische Variablennamen, ‘sentence’ in der Schleife war früher besser, ‘einzelSaetze’ und ‘satzAntworten’ sind ziemlich unverständlich,
letzteres meinte ich als Variable, die Methode heißt auch noch satzAntworten(), was soll man sich darunter nun vorstellen?

‘eingabeAusgeschrieben’, was gibt es noch für Eingaben, unausgeschriebene?

im Zweifel ist Schlichtheit auch wieder interessant, für Variablen sogar die an sich verpöhnten a, b, c,
oder neutral ‘satz’ bzw. wie zuvor ‘sentence’,

Einzahl statt Mehrzahl grundsätzlich immer zu bedenken, ganz schlimm sind auch Klassennamen wie Personen statt Person,
hier wäre ‘einzelSatz’ auch schon eine Stufe besser als aktuell,
in einer Variablen, gar Parameter der Untermethode, musst du nicht die allgemeine Schleifenverarbeitung mit ausdrücken
(‘String[] satzteile’ dagegen ok)


das return in der Schleife beendet die Methode, unabhängig von allem ist das klare Sache,
auch hier lohnt sich, sich nicht von den Details verwirren zu lassen sondern immer den Überblick zu behalten,

egal was die eigentliche Arbeit ist, wenn du mehrere Ergebnisse zusammenfassen willst, dann musst du einen String zusammenbauen, evtl. StringBuilder nutzen

public class Test
{
    public static void main(String[] args)
        throws Exception
    {

        String eingabe = "ist Panama weit weg? wo ist es?";
        System.out.println(analyze(eingabe));

    }

    static String analyze(String eingabe)
    {
        StringBuilder ergebnis = new StringBuilder();

        BreakIterator breaker = BreakIterator.getSentenceInstance();
        breaker.setText(eingabe);
        int index = 0;
        while (breaker.next() != BreakIterator.DONE)
        {
            String satz = eingabe.substring(index, breaker.current());
            index = breaker.current();

            ergebnis.append("noch ein Satz gefunden: " + satz.length() + "
");
        }
        return ergebnis.toString();
    }
}

Ich danke Dir.

Und wieder habe ich eine Frage… ich habe Deinen Code ein wenig angepasst um auszuprobieren ob ich es hinbekommen.

Java Code:

[ol]
[li] [/li]
[li]public class Test[/li]
[li]{[/li]
[li] public static void main(String[] args)[/li]

[li] throws Exception[/li]
[li] {[/li]
[li] [/li]
[li] String eingabe = “Keks. Keks.”;[/li]
[li] System.out.println(analyze(eingabe));[/li]
[li] [/li]
[li] }[/li]
[li] [/li]
[li] static String analyze(String eingabe)[/li]
[li] {[/li]
[li] StringBuilder ergebnis = new StringBuilder();[/li]
[li] [/li]
[li] BreakIterator breaker = BreakIterator.getSentenceInstance();[/li]
[li] breaker.setText(eingabe);[/li]
[li] int index = 0;[/li]
[li] while (breaker.next() != BreakIterator.DONE)[/li]
[li] {[/li]
[li] String satz = veraendere(eingabe.substring(index, breaker.current()));[/li]
[li] index = breaker.current();[/li]
[li] [/li]
[li] ergebnis.append(satz + " ");[/li]
[li] }[/li]
[li] return ergebnis.toString();[/li]
[li] }[/li]
[li] [/li]
[li] static String veraendere (String satz){[/li]
[li] [/li]
[li] String veraendere;[/li]
[li] [/li]
[li] if (satz.equals(“Keks.”)){[/li]
[li] veraendere = “a”;[/li]
[li] }[/li]
[li] else{[/li]
[li] veraendere = “b”;[/li]
[li] }[/li]
[li] [/li]
[li] return veraendere; [/li]
[li] }[/li]
[li] [/li]
[li]}[/li]
[/ol]

Doch das Ergebniss ist irgendwie erstaunlich. Gebe ich nur einen Satz ein klappt alles wunderbar. Bei zwei Saetzen schon nicht mehr:

String eingabe = “Keks.”;
Ausgabe: a -->Soweit so gut.

String eingabe = “Keks. Keks.”;
**Ausgabe: b a **–>Doch eigentlich muesste hier doch aa stehen.

String eingabe = “Keks. Keks. Keks”;
**Ausgabe: b b a **–>Doch eigentlich muesste hier doch aa stehen.

Zuerst dachte ich, dass ich

Java Code:

[ol]
[li] [/li]
[li]String satz = veraendere(eingabe.substring(index, breaker.current()));[/li]
[li] index = breaker.current();[/li]
[li] [/li]
[li] ergebnis.append(satz + " ");[/li]
[/ol]

Diese Zeile falsch ist, und aenderte sie in:

Java Code:

[ol]
[li] [/li]
[li]String satz = (eingabe.substring(index, breaker.current()));[/li]
[li] index = breaker.current();[/li]
[li] [/li]
[li] ergebnis.append(veraendere(satz + " "));[/li]
[/ol]

Doch da waren die Ergebnisse noch falscher:

String eingabe = “Keks.”;
Ausgabe: b

String eingabe = “Keks. Keks.”;
Ausgabe: b b

String eingabe = “Keks. Keks. Keks”;
Ausgabe: b b b

Also wird das nicht der Weissheit letzter Schuss gewesen sein. Am BreakIterator kann es auch nicht liegen, wie die Ausgabe ohne veraendere zeigt:

String eingabe = “Keks.”;
Ausgabe: Keks.

String eingabe = “Keks. Keks.”;
**Ausgabe: ****Keks. **Keks.

String eingabe = “Keks. Keks. Keks”;
**Ausgabe: ****Keks. ****Keks. **Keks.

Am einfachen if-else in String veraendere kann der Fehler allerdings auch nicht liegen. Selbst das habe ich in meiner Ratlosigkeit getestet. Wo kann mein Fehler sein?

Was genau funktioniert an unseren Code-Tags nicht?

@Abholschein
ich habe die Frage zwar direkt gesehen und jetzt beim Anschauen ist das in wenigen Minuten zu klären,
die Wartezeit schadet aber auch nicht, vielleicht lehrt sie dich, endlich etwas mehr oder effektiver zu arbeiten,

wie das zu schaffen ist weiß ich nicht, aber es muss irgendwann gehen


Selbst das habe ich in meiner Ratlosigkeit getestet.

was kann das nur für Testen gewesen sein?
es wird a oder b zurückgegeben, du musst prüfen was da passiert, was macht das if?
so ein einfaches equals ist keine Zauberei, da musst du dann lediglich nachschauen, was denn als Parameter kommt, kann ja was falsches sein

hast du das gemacht, diesen einfachst denkbaren Schritt, den Parameter ausgeben?
ein kleiner Haken ist da freilich noch dabei, in der Ausgabe sieht es eigentlich ok aus,

da gibt es dann eine Sache zu bedenken, die nicht komplett auf der Hand liegt:
es können Leerzeichen im String sein, hier auch der Fall, dafür braucht man genaue Ausgabe, z.B.

System.out.println("Paramater satz: |"+satz+"|");

es kann noch mehr Besonderheiten wie nicht darstellbare Zeichen geben,
letztlich müsste man im Zweifel immer ins Detail gehen, den String zerlegen, Zeichen für Zeichen als char-Zahlwert ausgeben


beim substring() kommen also die Leerzeichen mit rein, darauf musst du achten, ich überlasse erstmal dir, anderen Code zu finden,
trim()-Methode von String sei noch genannt

beim letzten Satz ist kein Leerzeichen dahinter, deswegen kann es dafür funktionieren,

hier im Forum gepostet “Keks. Keks. Keks” ist wohl nicht dein Test, passt nicht zu b b a,
da fehlt ja schon ein Satz-Punkt, bitte genau darauf achten


wenn veraendere() b oder a zurückliefert ist natürlich komplett ausgeschlossen, darauf nochmal veraendere() aufzurufen, kann nur b werden,
das ist noch ne Stufe bedenklicher, darüber nicht nachzudenken,
mit Ausgabe des Parameters in der Methode,

System.out.println("Paramater satz: |"+satz+"|");

würde diese Absurdität freilich auch stark auffallen

edit: oh, du rufst es ja gar nicht doppelt auf, sondern fügst ein Leerzeichen hinzu, Richtung also erkannt,
aber hilfreich kann ein zusätzliches Leerzeichen ja kaum sein


System.out.println() ist vom ersten Hello World-Programm an bis zur allerletzten Mars-Mission der erste und wichtigste Ritter, äh Java-Befehl,
das bitte als einziges heute lernen…

edit: und eben nicht nur fürs Endergebnis gut, sondern jeden Zwischenschritt,
alternativ Debugger