Methoden Bestimmung des häufigsten Buchstabens

farah

Mitglied
Hi 🙋🏻‍♀️
ich hab mir eine Aufgabe gesucht aber kann nicht damit zu recht kommen. Ich hoffe Ihr mir helfen könnt, eigentlich ist mein Frage wie ich ein String in int[] umwandeln kann?
 

Anhänge

  • DC63B94B-44A0-47CC-B62F-E5A4154124E2.jpeg
    DC63B94B-44A0-47CC-B62F-E5A4154124E2.jpeg
    988,2 KB · Aufrufe: 3
  • 5. Bestimmung des häufigsten Buchstabens.pdf
    488,2 KB · Aufrufe: 10

kneitzel

Top Contributor
Das ist doch genau das, was Du als Code schreiben sollst. Die Aufgabe beschreibt den Algorithmus doch sogar Schritt für Schritt incl. Hinweise zur String Klasse.
 

kneitzel

Top Contributor
In der Teilaufgabe a, getHistogram soll einen Text als Parameter bekommen und das Histogramm als int[ ] zurückgeben :\
Das ist die Beschreibung, was die Methode machen soll. Die Methode soll getHistogram heißen, einen Text als Parameter bekommen und das sogenannte Histogramm als int[] zurück geben.

Aber die Methode sollst Du natürlich schreiben und die Schritte, wie dies geschehen kann, folgen auch direkt.
 

farah

Mitglied
Java:
public class CaesarChiffre {

    public static final String ENCRYPTED_MESSAGE = "xjmw lzy! iz mfxy ijs htij ljpsfhpy zsi inw xt wzmr zsi jmwj jw|twgjs. nhm rzxx rnw mnjw ojijx xjrjxyjw jnsjs sjzjs yj}y fzxijspjs zsi qfslxfr |jwijs inj nijjs psfuu.";

    public static int[] getHistogram(String text) {
        String str = new String();
        str.toLowerCase();
        int[] histogram = new int[256];
        int l = str.length();
        int i;
        int counter = 0;
        char max;
        for (i = 0; i < l; i++) {

            char letter = str.charAt(i);
            if (histogram[letter]++ >= counter) {
                counter = histogram[letter];
                max = letter;

            }
            i++;



        } return histogram;
    }
        public static void main (String[]args){
  System.out.println(getHistogram(ENCRYPTED_MESSAGE));

        }
}

zur vorherige Aufgabe habe ich die Code geschrieben aber leider bekomme ich nicht die richtige Ausgabe.
Kann jemand vielleicht erklären wo mein Fehler ist?

LG
 

Jw456

Top Contributor
Java:
str.toLowerCase();
Du musst schon den string übergeben der in Kleinbuchstaben gewandelt werden soll. Dein str ist lehr
Java:
String str = text.toLowerCase();

Du bekommst einen neuen String von der Methode zurück.
 
Zuletzt bearbeitet:

Jw456

Top Contributor
Das mit den char Array scheint mir auch nicht richtig. Du hast 256 Felder jedes Feld entspricht dem Zeichen wert in der ascii Tabelle. Also brauchst du beim duchgehen durch den string immer nur den ascii Wert des Zeichens bestimmen und dann dem zugehörigen Feld im Array um eins zu erhöhen.

Das tust du meiner Meinung nach nicht.
 

kneitzel

Top Contributor
Also als kleine Ergänzungen zu @Jw456:

a) Bei
Java:
        String str = new String();
        str.toLowerCase();
ist nicht nur das Problem, dass toLowerCase() den String zurück gibt. Auch schon der Start ist schlecht, denn der Parameter text wird ja hier gar nicht verwendet. Die Verbesserung in #11 deckt das aber natürlich komplett ab und @Jw456 hat diesbezüglich die richtige Lösung geboten.

b) Gerade als Anfänger solltest Du nicht mehrere Dinge in eine Zeile schreiben. Konkret bedeutet dies: Die Pre-/Post- Increment/Decrement Operatoren sollten niemals innerhalb einer komplexeren Zeile stehen! Das ist extrem schlecht. Einzige Ausnahme: In einer for Schleife als Increment an letzter Stelle. Da ist es ok.

Ansonsten sieht das aber prinzipiell korrekt aus - nur eben in einer schlecht lesbaren Form. Und die Variablen würde ich evtl. etwas umbenennen. counter ist ja der maxCounter und max ist maxLetter.
 

kneitzel

Top Contributor
ich suche nach dem Charakter, der am häufigsten in einem Text verwendet wurde.
Ja, aber warum? Wo in der Aufgabe wird dies gefordert? Und da Du ja auch nur das Array zurück gibst, ist das dort in der Methode nicht notwendig. (So ich da nichts übersehen / vergessen habe - das möchte ich natürlich nicht ausschließen.)

Evtl. bist Du schon an einer Folgeaufgabe - aber da soll dann vermutlich mit dem Ergebnis der Methode gearbeitet werden - aber das ist geraten, denn ich habe ja keinerlei Wissen zu einer möglichen Folgeaufgabe.
 

farah

Mitglied
Ja, aber warum? Wo in der Aufgabe wird dies gefordert? Und da Du ja auch nur das Array zurück gibst, ist das dort in der Methode nicht notwendig. (So ich da nichts übersehen / vergessen habe - das möchte ich natürlich nicht ausschließen.)

Evtl. bist Du schon an einer Folgeaufgabe - aber da soll dann vermutlich mit dem Ergebnis der Methode gearbeitet werden - aber das ist geraten, denn ich habe ja keinerlei Wissen zu einer möglichen Folgeaufgabe.
Später mit einer anderen Methode sollte den häufigsten Character ausgegeben werden.
Dazu muss ich zuerst histogram implementieren und danach in der neuen Methode das getHistogram verwenden.
 

kneitzel

Top Contributor
Später mit einer anderen Methode sollte den häufigsten Character ausgegeben werden.
Dazu muss ich zuerst histogram implementieren und danach in der neuen Methode das getHistogram verwenden.
Ja genau! Du drückst das richtig aus:
In der neuen Methode rufst Du getHistogram auf (die Methode ist unverändert, d.h. da wird nichts rein kommen mit dem max Wert und so!) und int Array, das Du da dann bekommst, das wertest Du dann aus. Also unter dem Strich das, was Du jetzt schon recht gut implementiert hast:
Du definierst Variablen für max Wert und/oder Position des max Wertes (was halt die Aufgabe so fordert) und dann prüfst Du in einer Schleife alle Werte um ggf. max Wert / Position max Wert umzusetzen.

Also prinzipiell schon sehr gut angegangen - nur du hast Die Funktionalität etwas an der falschen Stelle mit eingebaut.
 

Jw456

Top Contributor
Java:
for (i = 0; i < l; i++) {

            char letter = str.charAt(i); // letter bekommnt den ascii wert
            histogram[letter]++  // in dem Array wird das Feld was dem ascii wert entspricht  erhöht.
         }
das sollte eigentlich in der for schleife reichen.
 

Jw456

Top Contributor
in der neuen Methode gehst du das historgam duch und suchst den hösten eintrag in den 256 Feldern .
der index ist auch gleich dein ASCII Wert. Wenn der Index 97 zb der höste ist, ist es das "a"

das Lehrzeichen 32 oder auch Enter 13 ....andere sonderzeichen solltest du dabei nicht beachten.

PS wenn es nur um Buchstaben geht weißt du welche indexs du duchsuchen musst nach dem hösten wert.
Eine Ascii Tabelle hilft dabei.
 
Zuletzt bearbeitet:

farah

Mitglied
Ja genau! Du drückst das richtig aus:
In der neuen Methode rufst Du getHistogram auf (die Methode ist unverändert, d.h. da wird nichts rein kommen mit dem max Wert und so!) und int Array, das Du da dann bekommst, das wertest Du dann aus. Also unter dem Strich das, was Du jetzt schon recht gut implementiert hast:
Du definierst Variablen für max Wert und/oder Position des max Wertes (was halt die Aufgabe so fordert) und dann prüfst Du in einer Schleife alle Werte um ggf. max Wert / Position max Wert umzusetzen.

Also prinzipiell schon sehr gut angegangen - nur du hast Die Funktionalität etwas an der falschen Stelle mit eingebaut.
Danke für deine Hilfe:)
 

farah

Mitglied
Am Ende sollte man den häufigsten Buchstabe mit dem Anzahl und Anteil schreiben und in der Main Methode ausgeben.
Java:
public class CaesarChiffre {

    public static final String ENCRYPTED_MESSAGE = "xjmw lzy! iz mfxy ijs htij ljpsfhpy zsi inw xt wzmr zsi jmwj jw|twgjs. nhm rzxx rnw mnjw ojijx xjrjxyjw jnsjs sjzjs yj}y fzxijspjs zsi qfslxfr |jwijs inj nijjs psfuu.";
    public static final char SEPARATOR = ' ';
    public static int getIndexOfMaximumEntry(int[] array) {
        int maxIndex = 0;
          for (int i = 0; i < array.length; i++) {
            maxIndex = (array[i] > array[maxIndex]) ? i : maxIndex;
         }
        return maxIndex;
     }

    public static int[] getHistogram(String text) {
        String str = text.toLowerCase();
        int[] histogram = new int[256];
        for( int i = 0; i < str.length(); i++) {
            char maxLetter = str.charAt(i);
            histogram[maxLetter]++;
         } return histogram;
    }

    public static char getSignificantLetter (String text){
       int[] histogram = getHistogram(text);
        char significantLetter = SEPARATOR;
        for (int i = 0; i < histogram.length; i ++){
        int indexOfMaximumEntry = getIndexOfMaximumEntry(histogram);
            significantLetter = (char)indexOfMaximumEntry;

           int quantity = histogram.length;
           int quota = ((indexOfMaximumEntry / quantity) * 100);
        }
     return significantLetter;
    }

       public static void main (String[]args){
        System.out.println("Most significant letter: " + getSignificantLetter(ENCRYPTED_MESSAGE) );
        }
}
(Muss man auch einen leeren Charakter (SEPERATOR) anlegen)
Ich kann nicht mein Fehler entdecken.
 

Jw456

Top Contributor
Das durchlaufen des Arrays nach dem größten Eintag würde ich vielleicht so machen.
Wenn du nur die Buchstaben brauchst dann reicht es eigentlich das Array nur non 97 bis 122 zu durchlaufen. Mit der for Schleife.


Umlaute sind ja bei den ersten 127 Ascii Zeichnen nicht vorhanden.


Java:
int maxIndex = 0;
int maxAnzahl = 0 ;
for (int i = 0; i < array.length; i++) {
               
     if  (array[i] > maxAnzahl ) {
         maxAnzahl = array[i];
         maxIndex = i;
     }
 
Zuletzt bearbeitet:

farah

Mitglied
Zeige mal deine zweite Aufgabenstellung für die zweite Methode
f) Legen Sie die Methode getSignificantLetter an, die als Parameter einen Text als String
bekommen und den Buchstaben als char zurückgeben soll.
g) Legen Sie eine Klassenkonstante SEPARATOR vom Typ char an und weisen Sie dieser ein
Leerzeichen zu. Dieser Separator dient später dazu, die Information über die Wortgrenzen
nicht zu verlieren. Da die Wortgrenzen keine Rolle bei der Suche nach dem häufigsten
Zeichen spielen, sollen diese im Histogramm nicht mitgezählt werden.
h) Rufen Sie die Methode getHistogram auf und speichern Sie das Ergebnis in einer Variable
histogram.Finden Sie nun im Histogramm den Index des Eintrages mit dem höchsten Wert
mittels getIndexOfMaximumEntry und speichern Sie ihn in einer Variable significantLetter
des Typs char. Dieser Index entspricht, als Zeichen interpretiert, dem am häufigsten
vorkommenden Buchstaben.
i) Der Interesse halber wollen wir dem Benutzer ein Feedback darüber geben, wie oft der
häufigste Buchstabe im Text vorgekommen ist. Legen Sie dafür die Variable quantity
geeigneten Datentyps an, in der Sie eintragen, wie oft der Buchstabe significantLetter
im Text vorgekommen ist (; Histogramm). Legen Sie außerdem die Variable int quota
an, in der Sie den relativen Anteil von significantLetter im Text in Prozent speichern.
j) Geben Sie folgende Meldung auf stdout aus:
Most significant letter: hsignificantLetter i
Quantity: hquantity i times (hquota i % of whole text).
k) Geben Sie zum Schluss significantLetter als Ergebnis der Methode getSignificantLetter
zurück.
 

Jw456

Top Contributor
punkt g
sagt doch schon das du beim suchen in getSignificantLetter das Lehrzeichen nicht beachten sollst machst du aber nicht.
Deshalb bekommst du da auch das zurück, Lehrzeichen Index 32, ist in dem String das häufigste Zeichen.
 
Zuletzt bearbeitet:

Jw456

Top Contributor
Java:
 public static int getIndexOfMaximumEntry(int[] array) {
        int maxIndex = 0;
      for (int i = 0; i < array.length; i++) {
              if(i != SEPARATOR){
                 maxIndex = (array[i] > array[maxIndex]) ? i : maxIndex;
               }
        }
        return maxIndex;
     }
dies ist dann nach Post #32 nicht notwendig
sondern in der ersten Methode
 
Zuletzt bearbeitet:

farah

Mitglied
Das durchlaufen des Arrays nach dem größten Eintag würde ich vielleicht so machen.
Wenn du nur die Buchstaben brauchst dann reicht es eigentlich das Array nur non 97 bis 122 zu durchlaufen. Mit der for Schleife.


Umlaute sind ja bei den ersten 127 Ascii Zeichnen nicht vorhanden.


Java:
int maxIndex = 0;
int maxAnzahl = 0 ;
for (int i = 0; i < array.length; i++) {
              
     if  (array[i] > maxAnzahl ) {
         maxAnzahl = array[i];
         maxIndex = i;
     }
Ich denke aber was ich geschrieben habe reicht, weil in dieser Methode das Ziel nur die Bestimmung des max Index ist
 

Jw456

Top Contributor
Da die Wortgrenzen keine Rolle bei der Suche nach dem häufigsten
Zeichen spielen, sollen diese im Histogramm nicht mitgezählt werden.

Das heißt du sollst das schon in deiner ersten Methode beachten . Würde ich so deuten.
in dem Histogramm soll das ja gar nicht gezählt werden.
 

Jw456

Top Contributor
Ich würde einfach das Feld vom Histogram was dem Seperator entspricht löschen.

Java:
public static int[] getHistogram(String text) {
        String str = text.toLowerCase();
        int[] histogram = new int[256];
        for( int i = 0; i < str.length(); i++) {
            char maxLetter = str.charAt(i);
            histogram[maxLetter]++;
              }
         histogram[SEPARATOR] = 0;
         return histogram;
    }
 

Jw456

Top Contributor
Deine Aufgabenstellung will das es erst gar nicht gezählt wird. Du zählst es erst mit und löschst es anschließend wider .

Geht nur ob das das ist was dein Lehrer will musst du wissen entscheiden.
 

Jw456

Top Contributor
na welcher Buchstabe es ist bzw welcher Index es ist weißt du doch nun. Welchen Wert hat das histogram Array an der Index stelle?

Bei der Frage bin ich mir nicht sicher ob es jetzt nur um die Buchstaben A-Z geht oder ob alle Zeichen die im String gemeint sind zur Prozentualen Auswertung.
Ist für mich nicht eindeutig beschrieben.

Wenn es alle sind Buchstaben, Zahlen, Sonderzeichen, Lehrzeichen dann weist du was du nehmen musst. Wie groß ist der String?

Quantity: hquantity i times (hquota i % of whole text).
würde für mich heißen die Anzahl der Zeichen im String als grundlage der Berechnung.
 
Zuletzt bearbeitet:

Jw456

Top Contributor
Java:
int quantity = histogram.length; // falsch was kommt das raus  immer das gleiche
int quota = ((indexOfMaximumEntry / quantity) * 100); // falsch

int quantity = histogram[indexOfMaximumEntry.....];

int quota = ((wie_gross_ist_dein_String / quantity) * 100);  // denke nach ob das ergebnis  richtig ist

wie werden Prozente berechnet?
 
Zuletzt bearbeitet:

farah

Mitglied
Java:
int quantity = histogram.length; // falsch was kommt das raus  immer das gleiche
int quota = ((indexOfMaximumEntry / quantity) * 100); // falsch

int quantity = histogram[indexOfMaximumEntry.....];

int quota = ((wie_gross_ist_dein_String / quantity) * 100);  // denke nach ob das ergebnis  richtig ist

wie werden Prozente berechnet?
Ja stimmt,
Hier konnte ich das Quota bestimmen aber wusste nicht wie man quantity bekommen kann
Warum quantity ist gleich histogram [ indexofmaximumEntry ]
 

Jw456

Top Contributor
Java:
public class CaesarChiffre {

    public static final String ENCRYPTED_MESSAGE = "xjmw lzy! iz mfxy ijs htij ljpsfhpy zsi inw xt wzmr zsi jmwj jw|twgjs. nhm rzxx rnw mnjw ojijx xjrjxyjw jnsjs sjzjs yj}y fzxijspjs zsi qfslxfr |jwijs inj nijjs psfuu.";
    public static final char SEPARATOR = ' ';


    public static int getIndexOfMaximumEntry(int[] array) {
        int maxIndex = 0;
        for (int i = 0; i < array.length; i++) {
            maxIndex = (array[i] > array[maxIndex]) ? i : maxIndex;
        }
        return maxIndex;
    }

    public static int[] getHistogram(String text) {
        String str = text.toLowerCase();
        int[] histogram = new int[256];
        for (int i = 0; i < str.length(); i++) {
            char maxLetter = str.charAt(i);
            if (maxLetter != SEPARATOR)
                histogram[maxLetter]++;
        }
        return histogram;
    }

    public static char getSignificantLetter(String text) {
        int[] histogram = getHistogram(text);
        int indexOfMaximumEntry = getIndexOfMaximumEntry(histogram);
        char significantLetter = (char) indexOfMaximumEntry;
        float  quantity = histogram[significantLetter];  // oder auch indexOfMaximumEntry  ist ja das gleiche
        float quota = quantity / text.length() * 100;
     
        // hier deine Ausgabe

        return significantLetter;
    }

    public static void main(String[] args) {
        System.out.println("Most significant letter: " + getSignificantLetter(ENCRYPTED_MESSAGE));
    }
}
 
Zuletzt bearbeitet:

Ähnliche Java Themen


Oben