Programm dass Palindrome erkennt

wurstm162

Mitglied
Ich habe mich an einem Programm versucht, dass ein Wort darauf überprüft, ob diese ein Palindrom ist. Mein zeigt jedoch folgende Fehlermeldungen an:
Code:
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 3

    at java.base/java.lang.StringLatin1.charAt(StringLatin1.java:48)

    at java.base/java.lang.String.charAt(String.java:711)

    at kleineProjekte.checkPalindrome.<init>(checkPalindrome.java:37)

    at kleineProjekte.checkPalindrome.main(checkPalindrome.java:10)

Das ist mein Code:
Code:
package kleineProjekte;

public class checkPalindrome {
    
    String word = "oma";
    StringBuilder sb1;
    StringBuilder sb2;
    
    public static void main(String[] args) {
        new checkPalindrome();
    }
    
    public checkPalindrome() {
        if(checkEven() == true){
        sb1 = new StringBuilder("");
        sb2 = new StringBuilder("");
            for(int i = 0; i<word.length()/2; i++) {
            //appends a string from the first half of 'word'
                sb1.append(word.charAt(i));
            }
            for(int i = word.length(); i>word.length()/2; i--) {
                sb2.append(word.charAt(i));
            //appends a string from the second half of 'word' but backwards
            }
            if(sb1 == sb2) {
            //checks both appended Strings
                System.out.println("word is a palindrome");
            }
            else {
                System.out.println("word isnt a palindrome");
            }
        }
        else {
            sb1 = new StringBuilder("");
            sb2 = new StringBuilder("");
                for(int i = 0; i<(word.length()-1)/2; i++) {
                //appends a String from the first half of a word-1: tomot --> to
                    sb1.append(word.charAt(i));
                }
                for(int i = word.length(); i>(word.length()+1)/2; i--) {
                //appends a String from the first half of a word+1: tomot --> to
                    sb2.append(word.charAt(i));
                }
                if(sb1 == sb2) {
                    System.out.println("word is a palindrome");
                }
                else {
                    System.out.println("word isnt a palindrome");
                }
        }
    }
    
    public boolean checkEven() {
    //checks whether 'word' is even
        if(word.length()%2==0) {
            return true;
        }
        else {
            return false;
        }
    }
}

Vielen Dank für Eure Zeit
 
charAt startet bei 0 und geht bis length-1.
Du versuchst aber auf den Buchstaben mit index length zuzugreifen, was nicht funktionieren kann.
(Siehe doku von charAt: https://docs.oracle.com/javase/8/docs/api/java/lang/String.html#charAt-int-)

Des weiteren vergleichst Du die Referenzen der StringBuilder und nicht deren Inhalt. Die Referenzen sind nie gleich, da du zwei StringBuilder erstellt hast.

Edit: Link zur String.charAt Dokumentation eingefügt.
 
Warum verwendest du eigentlich den StringBuilder? Ist das notwendig? Mit String.charAt() (wie @JustNobody bereits erwähnt hat) geht es auch und der Code könnte auch wesentlich kürzer sein 😉

z.B. so:

Java:
public static boolean isPalindrom(String input) {
        input = input.replaceAll(" ", "").toLowerCase();
        for(int i = 0, j = input.length()-1; i <= j; i++, j-- ) {
            if(input.charAt(i) != input.charAt(j)) {
                return false;
            }
        }
        return true;
    }
 
So war das nicht gemeint xD Ich kann mich noch selber gut an die Aufgabe im ersten Semester erinnern und da war die Musterlösung ähnlich wie die von mir oben xD

Dort wurde gesagt, dass man das ohne StringBuilder und String(ausgenommen replaceAll und toLowerCase) Methoden machen soll xD
 
Zuletzt bearbeitet:
Das ist mein Code:
Dazu ein paar Anmerkungen:

Zunächst einmal fassen Klassen gleichartige "Dinge" zusammen, die sich mit einem Substantiv bezeichnen lassen. In dem Fall könnte das die Palindrom-Prüfung sein, der Bezeichner wäre dann z. B. PalindromeCheck. Was auch immer Du wählst: in Java herrscht die Konvention, Typnamen in UpperCamelCase zu schreiben. Analog dazu sind Methoden Verben und werden in lowerCamelCase geschrieben.

Dann ist es sehr löblich, dass Du die Prüfung, ob die Zahl der Zeichen im Wort gerade ist, in eine Methode auslagerst. Die Implementierung ist unnötig kompliziert.

Hier der Teil, um den es geht:
Java:
    public boolean checkEven() {
    //checks whether 'word' is even
        if(word.length()%2==0) {
            return true;
        }
        else {
            return false;
        }
    }

Dabei ist word.length() % 2 == 0 ein boolescher Ausdruck, der true oder false liefert. Um zu verdeutlichen, was Du hier machst, führe ich mal eine Variable ein:
Java:
    boolean result = word.length() % 2 == 0;
    if (result) {
        return result;
    } else {
        return result;
    }
Es sollte ziemlich klar sein, dass das if völlig überflüssig ist. Tatsächlich kannst Du das Ergebnis direkt zurückgeben:
Java:
    return word.length() % 2 == 0;

Ein Wort zum Kommentar: brauchst Du den? Wenn nein, warum steht er im Code? Wenn ja, warum heißt die Methode dann nicht einfach anders? Würde die Methode zum Beispiel isWordLengthEven heißen, wäre der Kommentar nur eine Wiederholung des Methodennamens.

Zurück zu checkPalindrome: wenn Du Deinen Code anschaust, steht im then-Zweig fast das gleiche wie im else-Zweig. Der einzige Unterschied besteht in den Grenzen der for-Schleifen und hier wäre die Frage, ob es bei Berechnung tatsächlich einen Unterschied macht, ob die Wortlänge gerade oder ungerade ist:

Wenn n positiv und ungerade ist, liefert die ganzzahlige Division n/2 das gleiche Ergebnis wie (n-1)/2.
Umgekehrt: wenn n positiv und gerade ist, liefert die ganzzahlige Division n/2 das gleiche Ergebnis wie (n+1)/2.

Du brauchst also gar keine Unterscheidung danach, ob die Länge gerade oder ungerade ist, weil Du in beiden Fällen word.length()/2 und (word.length()+1)/2 verwenden kannst.

Dann hätten wir noch den Vergleich sb1 == sb2. Da es sich um zwei verschiedene Objekte handelt, wird dieser nie wahr sein. Du willst nicht wissen, ob es sich um identische Objekte handelt, sondern ob sie sich inhaltlich gleichen. Für diesen Zweck gibt es in Java z. B. equals: sb1.equals(sb2).
 

Zurück
Oben