FilterStream häufigkeit der Buchstaben

Bitte aktiviere JavaScript!
wie bekomme ich die 2 Filter ordentlich zusammen gebaut das er mir auch die Zeile ausgibt?
 
A

Anzeige


Vielleicht hilft dir dieser Kurs hier weiter: (hier klicken)
:D liegt das daran das es nicht geht weil die beiden Objekte LineNumberReader und BufferedReader "das gleiche" machen?
wenn ich Ihn Lösche und es so mache geht es :p
Java:
public class AnzahlBuchstabenInDatei {
    
    public static void main(String... args) throws IOException {
        
          FileReader fr = null;
          BufferedReader br = null;
          LineNumberReader lnr = null;
          int i;
          String str;

          try {
              fr = new FileReader("/home/nachinstallierte_pakete.txt");
              lnr = new LineNumberReader(fr);
//              int[] count = new int[58];
//              int test = fr.read();
//              System.out.println(test);
              
              while((str = lnr.readLine()) !=null) {
                  int[] count = new int[58];
                  i = lnr.getLineNumber();
                    System.out.print("("+i+") ");
                    
                    System.out.println(str);

                  for(int j=0;j<str.length();j++)
                        if(Character.isLetter(str.charAt(j))) {
                            int tmp = str.charAt(j) - 65;
                            count[tmp]++;
                        }
                  
                  for(int k=0;k<count.length;k++)
                        if(count[k]!=0)
                            System.out.print(count[k]+" "+(char)(k + 65)+" ");
                
                  
                  System.out.println();

              }
          
        } catch(Exception e) {
            // if any error occurs
            e.printStackTrace();
        } finally {
            // closes the stream and releases system resources
            if(fr!=null)
                fr.close();
            if(lnr!=null)
                lnr.close();
            if(br!=null)
                br.close();
     }
        
    }
 
Ist beantwortet!
Liegt an der überschriebenen Methode read() von LineNumberReader da er ein Kind von BufferedReader ist ;)

LG
 
Warum? Ich hab einfach nicht verstanden, was Du meintest mit den fixen Strings.
@mihe7 Man könnte noch argumentieren, dass max. 65536 Strings fest wären und die Anzahl der zu zählenden Zeichen ja viel größer sein könnte. Dann würde das Sortieren in konstanter Zeit sein - und dann wäre das Sortieren sogar ein legitimes Mittel. :D (?)
Ich meinte das so, wenn man die Anzahl der zu sortierenden String Elems[1] in Relation zu der Anzahl der zu zählenden Buchstaben der Eingabe[2] setzt, so ist bei sehr vielen Eingabebuchstaben die zusätzliche ,für die Sortierung benötigte Performance[3] vernachlässigbar - womit es "nicht schlimm wäre", zu sortieren.
[1]: Die Länge oder die Anzahl der Zeilen der Ausgabe, diese kann max. 2^16 betragen,
[2]: "Länge der Eingabe",
[3]: für den Sortieralgorithmus benötigte Anzahl der Operationen.


Bearbeitung: Das soll jetzt aber keine Doktorarbeit werden. :D
 
Hallo,
ich verstehe zwar leider immer noch nicht so ganz wieso Ihr das Sortieren möchtet. Natürlich kann ich dann später super schnell die Buchstaben zählen doch wenn ich ein Buch mit 2.000 Seiten und 800.000 Wörter einlese, sollte es doch schneller gehen jede Zeile jedes Wort jeden Buchstaben zu zählen oder?
Bis man dabei fertig mit sortieren ist sollte man bei einer sequenziellen abarbeiten schon Fertig sein oder?
Wäre ja mal eine witzige Aufgabe :)
Wie könnte ein sortier verfahren aussehen? Geht es mit dem Java-Framework schneller als mit Arrays, wie schnell ist das sequenzielle abarbeiten etc. ?
LG
 
ich verstehe zwar leider immer noch nicht so ganz wieso Ihr das Sortieren möchtet.
Keiner will sortieren. Es ist eine von vielen Möglichkeiten, die den Vorteil besitzt, dass kein zusätzlicher Speicher belegt werden muss. Der Nachteil ist, dass der Zeitbedarf für die Sortierung in der Größenordnung O(n log(n)) liegt.

wenn ich ein Buch mit 2.000 Seiten und 800.000 Wörter einlese, sollte es doch schneller gehen jede Zeile jedes Wort jeden Buchstaben zu zählen oder?
Natürlich, dafür brauchst Du halt (im schlimmsten Fall) 256 KiB zusätzlich Platz und Du musst das nicht zeilen- oder wortweise machen (eine Textdatei ist ein langer String). Angesichts dieser Datenmenge wären 256 KiB aber vermutlich vernachlässigbar. Umgekehrt: wenn Du nur in kurzen Strings die Buchstaben zählen willst und dafür ein 256 KiB-Array belegst, wäre das ziemlich verschwenderisch.

Wäre ja mal eine witzige Aufgabe
Das ist in der Theorie keine große Aufgabe: ein Algorithmus mit einer Laufzeitkomplexität in O(n) ist einem Algorithmus mit einer Laufzeitkomplexität in O(n log n) vorzuziehen - aber eben nur im Hinblick auf die Laufzeit.

Letztlich geht es darum, einen Algorithmus zu wählen, der für den jeweiligen Fall in Ordnung ist, wobei ggf. diametral zueinander stehende Wünsche zu berücksichtigen sind.

Für das Zählen selbst wäre die Lösung von @Tobias-nrw (ein Array für alle möglichen Zeichen) die schnellste. Bei der Ausgabe musst Du über alle 65536 Zeichen iterieren.
 
Danke für die ausführlich Antwort wie immer :)

Naja dann bleibe ich lieber bei meiner Umrechnung und meinem kleinen Array fürs erste :)
LG
 
Ja, vergiss aber die Prüfung auf das Array-Ende nicht.
Wie meinst du das? :p

eine Frage hab ich eh noch. Ich hab das ganze ja mit dem LineNumberReader gemacht. Ich hatte zuerst versucht einen eigenen LineNumberReader zu schreiben mit dem BufferedReader indem ich versucht habe das char vom String auf == '\n' abzufragen doch er überliest das einfach :(
Das " Return-Zeichen" hat die codierung 10 und das Symbol '\n' doch es klappt nicht wieso?

LG
 
War die Frage ernst gemeint?
Ehrlich gesagt ja.
Ich denke da sicherlich wieder viel zu Kompliziert! Deswegen was meinst du damit konkret?

Wenn Du readLine() verwendet hast, dann wird das Zeilenende bereits gelesen :)
Hab ich also für jede readLine() automatisch einen Zeilenumbruch wenn ich das jetzt richtig verstanden habe!
Das würde Sinn machen und dann ist es mir auch klar wieso er mir kein \n aufzählt :D dann geht die Zeilennummerierung ja noch einfacher. Einfach für jedes readLine() einmal hoch zählen :D

LG
 
Danke mihe7 :) somit kann ich auch Zeilen zählen ohne den LineNumberReader :) denn hatten wir nämlich nicht und dürfen diesen dann auch nicht nutzen ;) aber so geht es ja auch Danke :)

Java:
public class Zeilennummerierung {
   
    public static void main(String... args) throws IOException {
        String s;
        int count=0;
        FileReader fr = null;
        BufferedReader br = null;
       
        try {
            fr = new FileReader("/home/nachinstallierte_pakete.txt");
            br = new BufferedReader(fr);
           
            while((s=br.readLine())!=null) {
                count++;
                System.out.print(count+": ");
                System.out.println(s);
            }
        }
        catch(Exception ex) {
            System.out.println("unknow error");
        }
        finally {
            if(fr!=null)
                fr.close();
            if(br!=null)
                br.close();
        }
       
    }
 
somit kann ich auch Zeilen zählen ohne den LineNumberReader
Klar, der LineNumberReader dient nicht zum Zählen, sondern dazu, bestimmte Zeilen (nach ihrer Nummer) zu lesen :)

Ich denke da sicherlich wieder viel zu Kompliziert! Deswegen was meinst du damit konkret?
Du hast ein Array mit 300 Elementen aber 65536 theoretisch mögliche Codepoints. Wenn Du von einem Codepoint, bei dem Character.isLetter true zurückliefert, 65 abziehst, könnte es also passieren, dass das Ergebnis eine Zahl ist, die außerhalb Deiner Arraygrenzen liegt.
 
Du hast ein Array mit 300 Elementen aber 65536 theoretisch mögliche Codepoints. Wenn Du von einem Codepoint, bei dem Character.isLetter true zurückliefert, 65 abziehst, könnte es also passieren, dass das Ergebnis eine Zahl ist, die außerhalb Deiner Arraygrenzen liegt.
Achso das meinst du.
Das Problem hätte ich jetzt z. B. bei diesem Programmier hier mit "ä,ü,ö,ß".
Das Programm läuft für alle Buchstaben von a-z, A-Z aber wenn dann so ein Character kommt fliegt er raus.
Doch das könnte man ja auch ganz einfach lösen indem ich sage if(str.charAt(i) < 0 || str.charAt(i) > 57) doch dann müsste ich einen Error werfen wäre das Okay?

Wiedermal sry auch für manche "dämliche" Fragen aber Jeder fängt ja mal klein an :)

hier kurz der Code bis jetzt:
Java:
package Insel;
import java.io.*;

public class AnzahlBuchstabenInDatei {
    
    public static void main(String... args) throws IOException {
        
          FileReader fr = null;
          LineNumberReader lnr = null;
          int i;
          String str;
          try {
              fr = new FileReader("/home/test");
              lnr = new LineNumberReader(fr);
//              int[] count = new int[58];
//              int test = fr.read();
//              System.out.println(test);
              System.out.println((int)'ö');
              while((str = lnr.readLine()) !=null) {
                  int[] count = new int[58];
                  i = lnr.getLineNumber();
                    System.out.print("("+i+") ");
                    
                    System.out.println(str);

                  for(int j=0;j<str.length();j++)
                        if(Character.isLetter(str.charAt(j)))
                        //hier die Fehlermeldung sobald kein a-z,A-Z kommt (Exception?)
                        else{
                            int tmp = str.charAt(j) - 65;
                            count[tmp]++;
                        }

                  for(int k=0;k<count.length;k++)
                        if(count[k]!=0)
                            System.out.print(count[k]+" "+(char)(k + 65)+" ");

                  System.out.println();

              }
          
        } catch(Exception e) {
            // if any error occurs
            e.printStackTrace();
        } finally {
            // closes the stream and releases system resources
            if(fr!=null)
                fr.close();
            if(lnr!=null)
                lnr.close();

     }
        
    }

}
Ausgabe Korrekt:
(1) qwertzuioplkjhgfdsayxcvbnm
1 a 1 b 1 c 1 d 1 e 1 f 1 g 1 h 1 i 1 j 1 k 1 l 1 m 1 n 1 o 1 p 1 q 1 r 1 s 1 t 1 u 1 v 1 w 1 x 1 y 1 z
(2) MNBVCXYASDFGHJKLPOIUZTREWQ
1 A 1 B 1 C 1 D 1 E 1 F 1 G 1 H 1 I 1 J 1 K 1 L 1 M 1 N 1 O 1 P 1 Q 1 R 1 S 1 T 1 U 1 V 1 W 1 X 1 Y 1 Z

Wie gesagt sobald ein Zeichen durch geht wie z. B. ö (int-wert 246) dann kommt Indexfehler! soll ich dann wirklich eine Exception werfen?
Denn sagen wir mal ich würde die Ausgabe umlenken und in eine Dateischreiben. Sobald dann eine Exception kommt wie lösche ich dann die erstellte Datei wieder? Kann das Java auch?

LG
 
Das Problem hätte ich jetzt z. B. bei diesem Programmier hier mit "ä,ü,ö,ß".
Genau.

soll ich dann wirklich eine Exception werfen?
Das kannst nur Du beantworten aber ich würde das nicht machen, denn die Funktion soll ja die Häufigkeit von Vorkommen von Elementen eines gegebenen Alphabets zählen. Wenn ein Element in diesem Alphabet nicht vorkommt, dann wird es halt einfach nicht gezählt.

wie lösche ich dann die erstellte Datei wieder? Kann das Java auch?
Natürlich, mit java.io.File#delete oder java.nio.file.Files.delete bzw. .deleteIfExists.
 
Das kannst nur Du beantworten aber ich würde das nicht machen, denn die Funktion soll ja die Häufigkeit von Vorkommen von Elementen eines gegebenen Alphabets zählen. Wenn ein Element in diesem Alphabet nicht vorkommt, dann wird es halt einfach nicht gezählt.
Das hört sich gut an. Man könnte dann noch ausgeben das Zeichen dabei waren die nicht im Alphabet vorgekommen sind und die Anzahl dieser Zeichen mit ausgeben :)

Natürlich, mit java.io.File#delete oder java.nio.file.Files.delete bzw. .deleteIfExists.
das muss ich mir dann später auch mal anschauen :)

Danke für die Hilfe :)

LG
 
Klar, aber wenn Du die Zahl dieser Zeichen zählst, dann frage ich mich, wo der Unterschied zu den anderen Buchstaben ist :)
ganz einfach :)
Ich zähle nur die Zeichen im Intervall:
Java:
    if(str.charAt(j) >= 'a' && str.charAt(j) <='z' ||
                              str.charAt(j) >= 'A' && str.charAt(j) <= 'Z'){
und die anderen Zeichen sind "fremd" und diese Zähle ich in einer Variable einfach hoch. Ausgeben kann ich diese natürlich nicht :D

Hier mal ein kleines Beispiel:
Java:
package Insel;
import java.io.*;

public class AnzahlBuchstabenInDatei {
    
    public static void main(String... args) throws IOException {
        
          FileReader fr = null;
          BufferedReader br = null;
          String str;
          int lineNumber=0;
          int spaceNumber=0;
          int digits=0;
          int letter=0;
          int failLetter=0;
          try {
              fr = new FileReader("/home/test");
              br = new BufferedReader(fr);
              int[] count = new int[58];
              while((str = br.readLine()) !=null) {
                  
                  lineNumber++;
                    
                  System.out.println(str);

                  for(int j=0;j<str.length();j++) {
                      if(Character.isDigit(str.charAt(j)))
                          digits++;
                      if(Character.isWhitespace(str.charAt(j)))
                          spaceNumber++;
                      if(Character.isLetter(str.charAt(j)))
                          if(str.charAt(j) >= 'a' && str.charAt(j) <='z' ||
                              str.charAt(j) >= 'A' && str.charAt(j) <= 'Z'){
                            int tmp = str.charAt(j) - 65;
                            count[tmp]++;
                        }
                          else failLetter++;
                  }
              }
              System.out.println("Die Text analyse ergab: ");
              for(int k=0;k<count.length;k++)
                  if(count[k]!=0)
                      System.out.println(count[k]+" "+(char)(k + 65)+" ");
              System.out.println(digits+" Zahlen");
              System.out.println(lineNumber+" Zeilenumbrueche");
              System.out.println(spaceNumber+" Leerzeichen");
              System.out.println(failLetter+" fremde Zeichen");
                  
          
        } catch(Exception e) {
            // if any error occurs
            e.printStackTrace();
        } finally {
            // closes the stream and releases system resources
            if(fr!=null)
                fr.close();
            if(br!=null)
                br.close();

     }
        
    }

}
Ausgabe:
Die Klasse ist abstrakt, also können keine direkten Objekte erzeugt werden. Dennoch gibt es einen protected-Konstruktor, der für Unterklassen
wichtig ist.
Abgeleitete Klassen bieten in der Regel selbst einen Konstruktor mit dem Parameter vom Typ Writer an und rufen im Rumpf mit super(write)
den geschützten Konstruktor der Oberklasse FilterWriter auf. Über die initialisierte geschützte Objektvariable out kommen wir dann an
diesen Ur-Writer.
Wir wollen im Folgenden einen Filter schreiben, der alle in den Strom geschriebenen Zeichen in Kleinbuchstaben umwandelt.
Drei Dinge sind für einen eigenen FilterWriter nötig:
Die Klasse leitet sich von FilterWriter ab.
Unser Konstruktor nimmt als Parameter ein Writer-Objekt und ruft mit super(out)
den Konstruktor der Oberklasse, also FilterWriter, auf. Die Oberklasse speichert
das übergebene Argument in der geschützten Objektvariablen out, sodass die Unterklassen
darauf zugreifen können.
Wir überlagern die drei write()-Methoden und eventuell noch close() und flush(). Unsere write()-Methoden führen dann die Filteroperationen aus und geben die wahren Daten an den Writer weiter.

Die Text analyse ergab:
2 A
7 D
7 F
9 K
2 M
7 O
2 P
2 R
1 S
1 T
5 U
10 W
1 Z
42 a
24 b
14 c
36 d
161 e
11 f
18 g
17 h
76 i
4 j
20 k
36 l
17 m
91 n
30 o
7 p
87 r
52 s
79 t
29 u
5 v
10 w
1 y
5 z
0 Zahlen
14 Zeilenumbrueche
150 Leerzeichen
12 fremde Zeichen
 
Passende Stellenanzeigen aus deiner Region:

Neue Themen

Oben