Lange Rechenzeit.

  • Themenstarter Themenstarter Fredooo
  • Beginndatum Beginndatum
Status
Nicht offen für weitere Antworten.
F

Fredooo

Gast
Hallo,

habe folgendes Problem: Ich habe eine Methode zum Zählen von Wörtern von großen Textdateien geschrieben,
leider muss mein Rechner sehr lange rumrechnen bis er die Wortanzahl ausspuckt.
Hier is mein Quellcode vielleicht könnt ihr mir ja sagen, wo ich evtl etwas optimieren kann...


Code:
//Methode die prüft ob das jeweilige Zeichen zur "Klasse Wort" gehört
private boolean giltAlsWort (int c)
    {
        if ((c >= (int)'A' && c <= (int)'Z') || (c >= (int)'a' && c <= (int)'z') ||  c == 39 || (c== (int) 'Ä')
             || (c== (int) 'ä') || (c== (int) 'Ö') || (c== (int) 'ö') || (c== (int) 'Ü') || (c== (int) 'ü'))
           return true;
        else return false;
    }
    
public int countWords(String dateiName)
     {  
        boolean test;
        int anzahlWörter = 0; 
        String s = "";
        try {
                FileReader datei = new FileReader(dateiName);
                int c = datei.read();
                
                while (c != -1)
                 { c = datei.read();
                    test = giltAlsWort(c);
                    if (!test) continue;
                    while (test) {
                      s = s + (char) c;
                      c= datei.read();
                      test = giltAlsWort(c); }
                    s = s +" "; } 
               datei.close();
             }
        catch (FileNotFoundException f) {System.out.println( "Datei nicht gefunden!!!"); }
        catch (IOException e) { System.out.println("Error!!!"); }
        
        int anzahl = 0;      
        for (int x = 0; x < s.length(); x++)
         if (s.charAt(x) == ' ') anzahl++; 
        return anzahl;
    }
 
Wieso zählst du nicht gleich die Leerzeichen, die nach einem Buchstaben stehen? Dazu musst du doch nicht erst den Dateiinhalt zu einem einzigen String konkatenieren...

übrigens:

das >>s = s + " ";<< dürfte den großen Zeitaufwand verursachen. Nimm lieber erst nen StringBuffer, ist wesentlich flotter...
 
...aber was ist, wenn hinter einem Wort mehrere Leerzeichen oder Absätze etc stehen??
 
...stimmt, das wäre natürlich auch ne Möglichkeit. Gibt es denn nen Befehl im File Reader mit dem ich "rückwärts" lesen kann?
Aber den Code oben, kann man nich mehr wirklich optimieren?
String Buffer wollte ich eigentlich nich benutzen, weil der deprecated is, soweit ich weiß und zB. String.split() liest mir das ganze ja direkt in ein Array ein und das will ich auch nich bzw. soll ich nich!?
Dankeschön schonmal...
 
...meinst du denn, dass deine Möglichkeit nach dem Fund eines Leerzeichens immer zu überprüfen ob davor ein Buchstabe steht wirklich schneler is?? Ich muss auch alle Satzzeichen rausfiltern!!
 
Übrigens:
Code:
//Methode die prüft ob das jeweilige Zeichen zur "Klasse Wort" gehört 
private boolean giltAlsWort (int c) 
    { 
        if ((c >= (int)'A' && c <= (int)'Z') || (c >= (int)'a' && c <= (int)'z') ||  c == 39 || (c== (int) 'Ä') 
             || (c== (int) 'ä') || (c== (int) 'Ö') || (c== (int) 'ö') || (c== (int) 'Ü') || (c== (int) 'ü')) 
           return true; 
        else return false; 
    }

kannst du vereinfachen zu

Code:
//Methode die prüft ob das jeweilige Zeichen zur "Klasse Wort" gehört 
private boolean giltAlsWort (int c) {
  return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') ||  c == '$' || c== 'Ä' 
             || c=='ä' || c=='Ö' || c== 'ö' || c=='Ü' || c== 'ü';
    }

Oder benutze gleich

Code:
Character.isLetter(c)
 
Fredoo hat gesagt.:
Gibt es denn nen Befehl im File Reader mit dem ich "rückwärts" lesen kann?
Warum prüfst nicht einfach ob nach deinem Leerzeichen noch ein 2. oder 3. kommt? Sodass du entsprechend diese Leerzeichen einfach überspringst.
Mfg André
 
Fredoo hat gesagt.:
String Buffer wollte ich eigentlich nich benutzen, weil der deprecated is, soweit ich weiß
wo haste denn das her?

Ich nutze StringBuffer fast täglich und der ist von der Performance her einfach wesentlich schneller als Stringkonkatenation mittels "+".
Wenn du mir nicht glaubst, kannst du dir ja mal ein kleines Beispiel mit beiden Varianten basteln (also for-Schleife mit 20.000 Werten und die aneinander reihen - einmal mit +, einmal mit StringBuffer) und die Rechenzeit messen.

Deshalb würde ich dir zum StringBuffer raten, denn da ist massig Potential die Rechenzeit einzuschränken, besonders wenn du schreibst, es soll die Wortzahl großer Texte ausspucken.
 
StringBuffer ist NICHT deprecated und hat in Java 5 noch Zuwachs durch eine unsynchronisierte Variante, den StringBuilder, erhalten. Letzterer ist nochmal etwas flotter in unterwegs, wenn sichergestellt ist, dass nur aus einem Thread heraus zugegriffen wird,
 
...aber habs jetzt ganz anders gemacht un dso läufts auch echt ziemlich schnell

Code:
static boolean giltAlsZeichen(int c)
    {
        return ( (c >=65 && c <=90) || (c>=97 && c<=122) || c==39 || c=='Ä' 
                  || c=='ä' || c=='Ü' || c=='ü' || c=='Ö' || c=='ö');
    }

static int countWords(String dateiname) throws FileNotFoundException, IOException
    {
        BufferedReader datei = new BufferedReader(new FileReader(dateiname));
        int c = datei.read();
        int words=0;
        boolean vergleich=false;
        while (c != -1)
        {
            if (giltAlsZeichen(zeichen)) {
                if (!vergleich) { words++; vergleich=true; }
            }
            else vergleich=false;
            c=datei.read();
        }
        datei.close();
        return wordsr;
    }
 
Status
Nicht offen für weitere Antworten.

Zurück
Oben