Hilfe beim Umschreiben von Javascript nach Java

"noramlisiertesWort(String)" würde ich hier durch simplen Aufruf von String.replaceAll(RegEx, String) vereinfachen.
 
Was du geschrieben hast SPiKEe versteh ich nicht so ganz. Kann man REgEx einfach angeben, um alle Sonderzeichen zu meinen?
Ich habe herausgefunden, dass ich erstmal die ganzen RegEx und Leerzeichen entfernen soll.
Das würde ich mit folgender Line machen:
Java:
 String[] Worte = textString.trim().replaceAll("[':.!?]", " ").split(" ");

Das split packt den String doch in folgende Form:

Worte[0] = Herr
Woter[1] = Bundespräsident
.
.
.

Ich kann doch aber in Java die Werthäufigkeit nicht als 2 dimensionales Array schreiben, im Gegensatz zu Javascript, also müsst ich das doch in Form von zwei Arrays schreiben, also z.B: als distinct words und frequencies. Ich will ja im Grunde gleiche Worte als Wiederholungen zählen. Einer eine Idee, wie ich das mache?

Die Länge des Arrays kann ich doch wie folgt anpassen:
int Textlänge = Worte.length();

Ist das so richtig?
 
Zuletzt bearbeitet:
Mit
Java:
int Textlänge = Worte.length();
kannst du gar nix machen, denn:
• Auf die Länge eines Arrays greift man (lesend) mit array.length zu (keine Methode, sondern eine öffentlich sichtbare Variable).
• Schreibend kann man gar nicht auf die Array-Größe zugreifen, da die Größe eines Arrays beim Erzeugen für die gesamte (Objekt-)Laufzeit festgelegt wird.
• Werte werden immer von rechts nach links zugewiesen, nie umgekehrt!

Wenn du einen Datentyp brauchst, bei dem man auf die Größe zugreifen kann, solltest du dir ArrayList ansehen.

Nebenbei: Nach Konvention schreibt man in Java nur Namen von Klassen und Interfaces mit einem Großbuchstaben am Wortanfang, Konstanten vollständig groß und Variablen und Methoden beginnen mit einem Kleinbuchstaben.

Java:
String str = "Hilfe beim Umschreiben von Javascript nach Java";
String[] worte = str.split(" ");
würde folgendes tun:
Es erzeugt ein Array mit 7 Elementen, die wie folgt gefüllt sind:
(Index : Wert)
0 : "Hilfe"
1 : "beim"
2 : "Umschreiben"
3 : "von"
4 : "Javascript"
5 : "nach"
6 : "Java"

Ich würde wie folgt vorgehen um zu zählen, wie oft die Wörter jeweils vorkommen:
Eine TreeMap<String, Integer> erzeugen, in einer for-schleife folgendes prüfen:
wenn dieser String (wort) schon in der TreeMap ist, wird die dazugehörige Zahl inkrementiert
ansonsten wird der String zur TreeMap hinzugefügt, Wert (int): 1

Noch besser wäre natürlich ein Trie (Collection), aber das würde den Rahmen hier deutlich sprengen.
 
ok, ich hab es jetzt so weit geschafft:

Java:
import java.util.Arrays;
public class Zahl {

     public static void main(String[] args) {
		String textString = "Herr Bundespr?sident, Herr Ministerpr?sident, Herr Landtagspr?sident, Herr Kardinal, lieber Herr Zehetmair und lieber Freund Theo Waigel! W?hrend ich mir die Reden anh?re, gingen meine Gedanken in vergangene Zeiten zur?ck, und ich fragte mich: 'Wann warst du zum ersten Mal in M?nchen?' Wenn ich mich recht entsinne, war das Ende M?rz 1945. Ich war damals gerade 15 Jahre alt und ich befand mich als Flaghelfer in Berchtesgaden. Wir fuhren an einem Tag von Berchtesgaden nach M?nchen, um etwas dorthin zu transportieren. Ich kannte M?nchen noch nicht und meine erste Begegnung mit der Stadt war ein Schock, denn sie war ein einziger Tr?mmerhaufen. Angesichts dieses Elends sahen weder wir Kinder noch die Erwachsenen eine positive Zukunft. Doch wir haben es geschafft! Diese gro?artige Generation meiner Eltern, der Gro?eltern und vielleicht der Urgro?eltern verzweifelte trotz allem nicht.";
        String[] Worte = textString.trim().replaceAll("[':.,;!?]", " ").split(" ");
        Arrays.sort(Worte);
		String wort = "";
		int [] count=new int[20];
        for (int i=0;i<Worte.length;i++){

            wort = Worte[i].toLowerCase();

            for (int j=0;j<Worte.length;j++){
                if (Worte[j].toLowerCase().equals(wort)){
                    count[i]++;
                    if (i != j){
                        count[j] = 0;
                    }
                }
            }
        }
        for (int y=0;y<Worte.length;y++){
            System.out.println(Worte[y]+"\t"+count[y]);
		}
		}
		}

Das Problem ist, dass er mir schonmal Werte ausgibt, in dem oben geposteten Fall jedoch ist der String zu lang. Dafür müsste er eigentlich das Array anpassen. Das scheint in Java ja nur mit ArrayLists zu gehen, jedoch habe ich das bis jetzt nicht hinbekommen. Wie genau würde das in dem Bsp. gehen?
 
Zuletzt bearbeitet von einem Moderator:
So... hier mal der erste Teil des Codes:
Java:
import java.util.TreeMap;

public class TextStatistik2 {

	public static void main(final String[] args) {
		String textString = "Herr Bundespräsident, Herr Ministerpräsident, Herr Landtagspräsident, Herr Kardinal, lieber Herr Zehetmair und lieber Freund Theo Waigel! Während ich mir die Reden anhöre, gingen meine Gedanken in vergangene Zeiten zurück, und ich fragte mich: 'Wann warst du zum ersten Mal in München?' Wenn ich mich recht entsinne, war das Ende März 1945. Ich war damals gerade 15 Jahre alt und ich befand mich als Flaghelfer in Berchtesgaden. Wir fuhren an einem Tag von Berchtesgaden nach München, um etwas dorthin zu transportieren. Ich kannte München noch nicht und meine erste Begegnung mit der Stadt war ein Schock, denn sie war ein einziger Trümmerhaufen. Angesichts dieses Elends sahen weder wir Kinder noch die Erwachsenen eine positive Zukunft. Doch wir haben es geschafft! Diese großartige Generation meiner Eltern, der Großeltern und vielleicht der Urgroßeltern verzweifelte trotz allem nicht.";

		// hier drin wird gespeichert, wie oft das Wort jeweils vorkommt
		final TreeMap<String, Integer> wordsCounter = new TreeMap<String, Integer>();

		// "löscht" alle Punkte und Kommata
		textString = textString.replace(".", "");
		textString = textString.replace(",", "");

		// vielleicht auch noch sinnvoll: Groß- und Kleinschreibung ignorieren
		textString = textString.toLowerCase();

		// Text an jedem Leerzeichen aufsplitten
		final String[] words = textString.split(" ");

		for (final String str : words) {
			if (wordsCounter.containsKey(str)) {
				wordsCounter.put(str, wordsCounter.get(str) + 1);
			} else {
				wordsCounter.put(str, 1);
			}
		}
	}
}

Du solltest dir auch noch Gedanken machen, wie man die Daten in das Programm hinein bekommt. In den Code schreiben ist nicht zielführend, sonst müsstest du das Programm für jeden beliebigen Text neu compilieren. Ich würde vorschlagen, du übergibst als Parameter (per Kommandozeile) einen Dateinamen/Pfad und liest den Text dann aus der Datei.
 
oh, habe deinen Post nicht gesehen. Ok, Ist meine Lösung ohne die Map schlechter? Was ist der Vorteil/Nachteil oder ist meine Version einfach nur komplizierter?

Ich habe, wie gesagt, mit der ArrayList herumprobiert, aber ich weiß nicht, wie man damit umgeht. Einen kleinen Tritt vielleicht? ;)
 
Zu deinem Code (sorry, hab gleichzeitig gepostet):
Das mit dem replaceAll wird so nicht funktionieren, da nur die gesamte Zeichenkette ersetzt wird, nicht jedoch jedes einzelne Zeichen.

Problem an Arrays ist, dass die Größe fest steht, du sie also nicht nachträglich vergrößern kannst. Dein Code funktioniert, solange dein Text nicht über 20 verschiedene Wörter hat (, dafür aber wahrscheinlich deutlich performanter).
 
Zuletzt bearbeitet:
Java:
String[] worte=textString.trim().replaceAll("[':.!?]", " ").split(" ");

würde NICHT zu dem Ergebnis führen was du dir dadurch vielleicht erhoffst. In regulären Ausdrücken haben einige Zeichen bestimmte Aufgaben und Gruppen für die sie Stehen. So steht zum Beispiel ein einfacher Punkt für "JEDES ZEICHEN" ... ein Fragezeichen ist ein Anzahl-Operator und bedeutet "EINMAL ODER GARNICHT". Ein große Zusammenfassung wie reguläre Ausdrücke unter Java auszusehen haben bekommst du hier : Java 7 API Doc - java.util.regex.Pattern
Dementsprechend müsste deine RegEx ungefähr so aussehen :
Java:
String replacedString=inputString.replaceAll("[\\p{Punct}]+", "");
Dadurch erhälts du einen String in dem jedes Wort durch EIN LEERZEICHEN *beachte das im zweiten Argument nicht " " sondern "" steht* getrennt ist. Diesen kannst du dann mit
Java:
String splittedString=replacedString.split(" ");
in dein Array splitten und mit diesem weiter arbeiten.

RegEx ist nicht so einach als das du einfach die Zeichen angibst die ersetzt werden sollen. Da RegEx für einen viel größeren Bereich gedacht sind ist der Umgang damit auch dementsprechend kompliziert.

//EDIT : Ich hasse es wenn 5 Leute gleichzeitig posten -.-'
 
Zuletzt bearbeitet von einem Moderator:
Eine Einführung in die Collection-API gibts unter http://openbook.galileocomputing.de/javainsel9/javainsel_13_001.htm
Die wichtigsten Unterschiede zwischen Collections (wie TreeMap, ArrayList, Vector, ...) und Arrays:
• Die Größe von Arrays ist unabänderlich
• Collections bieten einige Hilfsmethoden
Java:
// Zugriff auf Elemente in Arrays:
int[] zahlen = {1, 0, 6, 7, 156}; 
System.out.println(zahlen[0]); // dieser Ausdruck gibt den int 1 auf der Konsole aus
zahlen[2] = 1645 // setzt den Wert mit Index 2 auf 1645

// Zugriff auf Elemente in z.B. einer ArrayList
ArrayList<String> namen = new ArrayList<String>();
namen.add("Hans"); // fügt den String "Hans" an der ersten freien Stelle hinzu
namen.add(0, "Peter"); // fügt den String "Peter" an die erste Stelle, alle anderen werden aufgeschoben
namen.set(1, "Maria"); // setzt den Wert am Index 1 auf "Maria", unabhängig davon was da vorher stand. es werden keine Elemente aufgeschoben
System.out.println(namen.get(1)); // gibt den String "Maria" auf der Konsole aus, da er auf Index 1 gespeichert war

EDIT: Collections sind einfach praktisch, weil ihre Größe automatisch angepasst wird. Theoretisches Limit liegt (für die meisten Collections) bei Integer.MAX_VALUE, das ist (2^31)-1 (auch wenn dein Programm vorher schon wegen Speicherproblemen in die Knie geht ;) )
 
Zuletzt bearbeitet:
Zurück