IllegalArgumentException

morry329

Mitglied
Ich habe im Internet eine Quellcode für die Project-Euler-Aufgabe Nr. 42 gefunden, aber ich wollte etwas im Code ändern. Die Änderung funktioniert nicht.
Hier ist mein Änderung, die den IllegalArgumentException wirft.
Java:
//nur diese Methode geändert, sodass das Code die Textfile in die String-Array umwandelt
public String run() {
        File fileReader = new File("/Users/meinName/ProgII/src/projectEuler/words.txt");
        Scanner sc = null;
        try {
            sc = new Scanner(fileReader);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        int count = 0;
        while(sc.hasNextLine()){
            String[] wordBank = sc.nextLine().split(",");
            for (String word : wordBank) {
                if (isTriangularNumber(wordValue(word)))
                    count++;
            }

        }
        return Integer.toString(count);
    }

//diese Methode bleibt unverändert, aber es wirft IllegalArgumentException
private static int wordValue(String s) {
        int sum = 0;
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (c < 'A' || c > 'Z'){ //hier Ausnahme geworfen ("find out why c could be <= 64 or >=91) 
                throw new IllegalArgumentException();
            }
            sum += c - 'A' + 1;
        }
        return sum;
    }

Kann jemand mir eine Hilfstellung geben?
 

Robert Zenz

Top Contributor
Also erstens, solltest du immer die gesamte Ausnahme mit Stapelspur uns sagen.

Zweitens, schau dir mal die Datei an welche du einliest. Das ist eine Zeile:

Code:
"A","ABILITY","ABLE","ABOUT","ABOVE",...

Davon liest du eine Zeile:

Code:
"A","ABILITY","ABLE","ABOUT","ABOVE",...

Dann teilst du es auf nach Beistrichen und nimmst den ersten Wert:

Code:
"A"

Und dann bestimmst du ob das erste Zeichen in diesem String A-Z entspricht.

Und, wo wir schonmal dabei sind, meine Wiederholung zum Thema `String`s, kann in dem Fall auch nicht schaden.
 

morry329

Mitglied
Also erstens, solltest du immer die gesamte Ausnahme mit Stapelspur uns sagen.

Zweitens, schau dir mal die Datei an welche du einliest. Das ist eine Zeile:

Code:
"A","ABILITY","ABLE","ABOUT","ABOVE",...

Davon liest du eine Zeile:

Code:
"A","ABILITY","ABLE","ABOUT","ABOVE",...

Dann teilst du es auf nach Beistrichen und nimmst den ersten Wert:

Code:
"A"

Und dann bestimmst du ob das erste Zeichen in diesem String A-Z entspricht.

Und, wo wir schonmal dabei sind, meine Wiederholung zum Thema `String`s, kann in dem Fall auch nicht schaden.
Herzlichen Dank für die Tipps und den Link - meine Gute, habe ich nicht ganz verstanden, dass das Code das ersten Zeichen liest. Also lautet die gesamte Ausnahme so:
Java:
Exception in thread "main" java.lang.IllegalArgumentException
    at projectEuler.GitHub42.wordValue(GitHub42.java:64)
    at projectEuler.GitHub42.run(GitHub42.java:35)
    at projectEuler.GitHub42.main(GitHub42.java:19)

Aber ist jetzt behoben (evtl. eine banale Lösung), danke nochmals für die Hilfstellung:
Code:
private static int wordValue(String s) {
        int sum = 0;
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            //einfach ausgrenzen, wenn es " ist
            if (c != '"') {
                sum += c - 'A' + 1;
            }
        }
        return sum;
    }
 

Robert Zenz

Top Contributor
Die "sauberere" Loesung waere im uebrigen vorher die Anfuehrungszeichen zu entfernen. Biszchen Pseudo-Code:

Java:
for (String line : lines) {
    for (String quotedWord : line.split(",")) {
        String word = quotedWord.substring(1, quotedWord.length() - 1);
        
        wordValue(word);
    }
}
 

KonradN

Super-Moderator
Mitarbeiter
String.split nimmt einen Regulären Ausdruck als Parameter. Man könnte also bereits im split Aufruf auch die Anführungszeichen entfernen.
 

mihe7

Top Contributor
Schön ist es nicht:
Java:
    private static List<String> toWords(String line) {
        return Stream.of(line.split("\"(,\")?")).skip(1).toList();
    }
 

M.L.

Top Contributor
Auch hier könnten Strukturen und Regeln zur Anwendung kommen um gerade möglichst wenig zu rechnen.
Z.B. könnte man die Wortliste erstmal nach der alphabetischen Reihenfolge der Buchstaben umordnen (SKY -> KSY, YOUTH -> HOTUY, ABSENCE -> ABCEENS...). Da (z.B.) SKY denselben Wert ergibt wie KSY (oder KYS, SYK) bräuchte man nur die ersten 15 (*) Buchstaben (z.B. K) des lateinischen Alphabets als Startwert hernehmen. Und dann nur die Buchstabenpermutationen (auch auf Vorrat) berechnen, die überhaupt auftreten (z.B. gibt es kein Wort mit B exakt gefolgt von Z, was schon mal eine Berechnung erspart)

(*) "SOUP" (<- dessen Buchstaben liegen nur im hinteren Teil des Alphabets, das Wort an sich taucht in der Liste aber (noch) nicht (alleine) auf. )
 

Robert Zenz

Top Contributor
Auch hier könnten Strukturen und Regeln zur Anwendung kommen um gerade möglichst wenig zu rechnen.
Z.B. könnte man die Wortliste erstmal nach der alphabetischen Reihenfolge der Buchstaben umordnen (SKY -> KSY, YOUTH -> HOTUY, ABSENCE -> ABCEENS...). Da (z.B.) SKY denselben Wert ergibt wie KSY (oder KYS, SYK) bräuchte man nur die ersten 15 (*) Buchstaben (z.B. K) des lateinischen Alphabets als Startwert hernehmen. Und dann nur die Buchstabenpermutationen (auch auf Vorrat) berechnen, die überhaupt auftreten (z.B. gibt es kein Wort mit B exakt gefolgt von Z, was schon mal eine Berechnung erspart)

(*) "SOUP" (<- dessen Buchstaben liegen nur im hinteren Teil des Alphabets, das Wort an sich taucht in der Liste aber (noch) nicht (alleine) auf. )
Das klingt aber um einiges aufwaendiger (zumindest Prozessor-Technisch) als einfach einen Haufen `char`s zu addieren.
 

Ähnliche Java Themen

Neue Themen


Oben