FilterStream häufigkeit der Buchstaben

ocsme

Top Contributor
Guten Tag zusammen,

ich möchte sehr gerne ein kleines Programm schreiben in das ich eine Datei eingebe und eine Liste bekomme wie oft ein Buchstabe vorgekommen ist.
Nun habe ich aber schon ein Problem mir fällt derzeit keine Effiziente Möglichkeit ein die Buchstaben eines Textes zu zählen.
Das ganze habe ich erst mal so gemacht:
Java:
public class AnzahlBuchstaben {

    public static void main(String... args) {
        String s = "Das ist ein Test";
        int[] a = new int[300];
        
        for(int i=0;i<s.length();i++)
            if(Character.isLetter(s.charAt(i)))
                a[s.charAt(i)]++;

        for(int i=0;i<a.length;i++)
            if(a[i]!=0)
            System.out.println(a[i]+" "+(char)i);
        
        
    }
}

Erst wenn ich diese Teilaufgabe ordentlich gelöst habe komme ich zu den streams 😉
Ich hoffe mir kann dabei jemand helfen 🙂

LG
 
Nein sortiert sind die Buchstaben ja nicht.
Es geht darum ich lese einen Text ein und zähle einfach die Vorkommenden Buchstaben.
So gesehen könnte ich mir auch das Array sparen doch dann hätte ich dutzend zugriffe auf die Datei.
Denn man könnte ja auch z. B. der Text wäre "Das ist nicht Ihr Haus!", den ersten Buchstaben zählen D und schauen ob der nächste Buchstabe wieder ein D ist denn counter nochmal um eins erhöhen, kommt ein anderer Buchstabe als das "a" dann auf in die Datei mit D und Counter, dass dann für jeden Buchstaben. Doch das wäre doch auch sehr Ineffizient oder 😛

Hat noch jemand eine Idee wenn die Buchstaben nicht sortiert sind?

LG


mihe7 meintest du ich soll die Datei erst sortieren? Dann müsste aber doch der gesamte Text in den Hauptspeicher geladen werde sprich in ein Array. Ist das nicht noch ineffizienter?
 
Das mit dem Sortieren war als Wink mit dem Betonpfeiler gedacht... Du kannst natürlich auch Buchstaben auf Array-Plätze abbilden und diese hochzählen. Dabei hast Du aber entweder ein fixes Alphabet oder aber Du musst das Alphabet dynamisch erzeugen und darin suchen.
 
gut ich verstehe leider immer noch nicht was du meinst 😀

also gibt es keine bessere Möglichkeit als eine von den beiden die du aufgeschrieben hast. Wobei ich nicht verstehe was du mit dem dynamischen erzeugen des Alphabetes meinst? Wieso soll man so etwas tun? Kannst du das etwas genauer erklären?

Mir ist jetzt nur noch eingefallen das man die Plätze des Arrays ja noch sehr drastisch verkleiner kann indem ich die Buchstaben dann einfach umrechne auf die ersten 60 Plätze 🙂 Dann zähle ich in einem Int-Array nur noch hoch und gib es später aus 🙂

LG
 
Sortier die Zeichen, dann kannst Du einfach zählen.
Wobei ich nicht verstehe was du mit dem dynamischen erzeugen des Alphabetes meinst? Wieso soll man so etwas tun? Kannst du das etwas genauer erklären?
Irgendwie musst du ja die Zählwerte den Buchstaben zuordnen. Du kannst ein festes Alphabet verwenden (a-z usw.), dann reservierst Du Platz für Zeicheb, die ggf. Im Wort nicht vorkommen. Oder Du verwendest nur die Buchstaben, die im Wort vorkommen, dann hängt das Alphabet vom Wort ab (dynamisch).
 
achso jetzt habe ich das verstanden 🙂
Dabei könnte man dann auch die von Java zur verfügung gestellten Dynamischen-Arrays nutzen 🙂 die hatten wir zwar noch nicht vom Stoff her aber das macht ja nix 😀 wobei ich es erst einmal nicht dynamisch machen will ob es überhaupt klappt 🙂

was mir jetzt nur leider noch nicht so ganz einleuchtet wäre das sortieren. Wie bekomme ich so eine Aufgabe vernünftig sortiert? Denn es hängt ja von der Datei ab die ins Programm kommt wieviele Buchstaben vorliegen.

LG
 
Dabei könnte man dann auch die von Java zur verfügung gestellten Dynamischen-Arrays nutzen
Es geht in erster Linie nicht um die Datenstruktur sondern um den Inhalt, d. h. zunächst muss nicht das Array dynamisch sein, sondern das Alphabet. Es gibt eine obere Grenze: der String kann nicht mehr Buchstaben als Zeichen enthalten. Dass man dafür dynamische Strukturen verwendet, ist wiederum in erster Linie eine Frage der Speichereffizienz.

Code:
    S   b   z
    --+---+---
>0  D |   |
 1  a |   |
 2  s |   |
 3    |   |
 4  i |   |
 5  s |   |
 6  t |   |

Aktuelles Zeichen (D) ist in b nicht vorhanden, also wird es zu b hinzugefügt und der dazugehörige Zähler wird auf 1 gesetzt. Das nächste Zeichen wird betrachtet usw.

Das Leerzeichen ist kein Buchstabe, wird also ausgelassen, nach ein paar Iterationen landet man bei

    S   b   z
    --+---+---
 0  D | D | 1
 1  a | a | 1
 2  s | s | 1
 3    | i | 1
 4  i |   |
>5  s |   |
 6  t |   |

Jetzt ist das s in b bereits vorhanden, und zwar an Index 2. Der Zähler an Index 2 wird also erhöht und das nächste Zeichen betrachtet.

    S   b   z
    --+---+---
 0  D | D | 1
 1  a | a | 1
 2  s | s | 2
 3    | i | 1
 4  i |   |
 5  s |   |
>6  t |   |

Das t ist wieder nicht in b vorhanden, vorgehen wie bisher. Das letzte Zeichen von S ist erreicht -> Ende.

    S   b   z
    --+---+---
 0  D | D | 1
 1  a | a | 1
 2  s | s | 2
 3    | i | 1
 4  i | t | 1
 5  s |   |
 6  t |   |
>

Das wäre eine Möglichkeit, allerdings nicht besonders effizient. Wesentlich effizienter bzgl. der Laufzeit wäre die Verwendung einer HashMap, die einem Buchstaben den Zählwert zuordnet.
 
@mihe7 :
Java:
import java.text.DecimalFormat;
import java.util.Arrays;

/**
 * @author tn, 13.04.2019
 */
public class AnzahlBuchstaben {
    private final int[] a = new int[Character.MAX_VALUE];
    private int c = 0;

    public static void main(String[] args) {
        AnzahlBuchstaben ab = new AnzahlBuchstaben();
        ab.test("Das ist ein Test.");
        Arrays.stream(ab.a()).forEachOrdered(System.out::println);
    }

    void test(String s) {
        for (char ch : s.toCharArray()) {
            n(ch);
        }
    }

    void n(char ch) {
        a[ch]++;
        c++;
    }

    int s() {
        return c;
    }

    String[] a() {
        StringBuilder b = new StringBuilder();
        DecimalFormat d = new DecimalFormat();
        d.setMinimumIntegerDigits(2);
        d.setMinimumFractionDigits(3);
        d.setMaximumFractionDigits(3);
        d.setMultiplier(100);
        for (int i = 0; i < a.length; i++) {
            int cn = a[i];
            if (cn != 0) {
                b.append((char) i);
                b.append(" ");
                b.append(String.format("%03d", cn));
                b.append(" ");
                b.append(d.format((float) cn / (float) s()));
                b.append(";");
            }
        }
        return b.toString().split(";");
    }
}


Code:
  003 17,647
. 001 05,882
D 001 05,882
T 001 05,882
a 001 05,882
e 002 11,765
i 002 11,765
n 001 05,882
s 003 17,647
t 002 11,765


Will man Es nicht sortiert haben, lässt man das Ordered einfach weg...
 
Das ist eine Implementierung mit einem statischen Alphabet (alle möglichen chars). Wenn Du hier aber irgendwo sortierst, würde ich Dir Punkte abziehen, denn dann wäre ein zusätzliches Alphabet überflüssig.
 
Das ist eine Implementierung mit einem statischen Alphabet (alle möglichen chars). Wenn Du hier aber irgendwo sortierst, würde ich Dir Punkte abziehen, denn dann wäre ein zusätzliches Alphabet überflüssig.
65536 Zeichen reichen doch wohl...
Wenn Du hier aber irgendwo sortierst
siehe
Will man Es nicht sortiert haben, lässt man das Ordered einfach weg...


Huch, den Kommentar habe ich ganz übersehen. Natürlich kann er das, dann verbrät er aber relativ viel Platz. Das wiederum muss man in Relation zur Eingabelänge und zur Laufzeit sehen. Es ist halt wie immer ein Balanceakt.
ja das stimmt schon... Viel schneller geht's aber nicht. 😛

würde ich Dir Punkte abziehen
Fieser Mensch Du. 😀
 
65536 Zeichen reichen doch wohl...
Die reichen für alles, aber 64 KiB für 10 Zeichen ist ..

Nein, schneller als O(n) gehts nicht und sortieren ist auch nicht immer eine Lösung (ich möchte nicht vorher 2 GB sortieren müssen). Er muss sich halt für eine Option entscheiden: will er sortieren, dann kann er die Zeichen einfach abzählen, will er ein fixes Alphabet (z. B. alle chars), dann muss er das Eingabealphabet auf dieses abbilden (bei allen chars trivial) und kann in einem Array zählen, will er das Alphabet während des Einlesens dynamisch aufbauen, dann ist der Algorithmus ausgabesensitiv bzgl. des Platzbedarfs, hat dafür Einbußen bei der Laufzeit.
 
@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. 😀 (?)
 
Meine Frage ist gerade nur jetzt wo ich das verstanden habe mit dem dynamischen erstellen des Alphabetes wieso?
In einem größeren Text kommt ja sicherlich jeder Buchstabe mindestens 1x vor!

Ich habe das bis jetzt so gemacht ist zwar nicht wirklich schön aber es funktioniert erst einmal und das freut mich 😛
Java:
package Insel;
import java.io.*;

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);
              br = new BufferedReader(fr);
              
              while((str = br.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();
     }
        
    }

}
 
Ach scheiße, UFT-8/16 ist ja bereits "sortiert"... Dann wäre das Sortieren eigentlich überflüssig... Das sind noch die Restwirkungen des Alkohols gestern.
@mihe7 Verzeihung.
 
Meine Frage ist gerade nur jetzt wo ich das verstanden habe mit dem dynamischen erstellen des Alphabetes wieso?
Um nicht für jeden möglichen Buchstaben Platz reservieren zu müssen, auch wenn dieser nicht vorkommt. Die einfachste Lösung ist die von @Tobias-nrw. Da wird für jedes erdenkliche Zeichen Platz reserviert (65536 Einträge á 4 Byte = 256 KiB; die int-Breite habe ich oben vergessen). Die Frage ist, ob bzw. wann es gerechtfertigt ist, 256 KiB an RAM zu verbraten, um z. B. 100 mögliche Buchstaben (von denen nur 50 tatsächlich im Text vorkommen) zu zählen.

Ach scheiße, UFT-8/16 ist ja bereits "sortiert"... Dann wäre das Sortieren eigentlich überflüssig... Das sind noch die Restwirkungen des Alkohols gestern.
@mihe7 Verzeihung.
Ich verstehe immer weniger 🙂
 
😀 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 😛
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. 😀 (?)
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. 😀
 
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? 😛

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 😀 dann geht die Zeilennummerierung ja noch einfacher. Einfach für jedes readLine() einmal hoch zählen 😀

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 😀

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
 
Habe übersehen, dass Du nur ausgeben willst, dass Zeichen dabei sind 😡
Nicht schlimm auch Profis wie du dürfen mal etwas übersehen, etc 🙂

Aber so bin ich schon ganz zufrieden mit dem Programm.
Als nächstes möchte ich mir mal die Komprimierung anschauen, Dateien in zip Archive Packen und da fehlt mir auch mal wieder eine Option, wenn das jetzt niemand auf die schnelle weiß dann suche ich selbst 🙂

Möchte eine Datei einlesen und in 1 MB große Zip Dateien Packen. Also ist die Datei 5 MB groß = 5 einzelne Zip Dateien. Packe ich sie zusammen aus habe ich wieder meine Datei 🙂
Mein Problem derzeit wie bekomme ich ihm gesagt mach nur eine 1 MB große Datei draus 😀

wie gesagt gehört nicht hier hin. Dann muss ich erst einmal selbst suchen!

Nochmals Danke 🙂

LG
 

Neue Themen


Zurück
Oben