struct elemente in funktionen



  • Hallöchen,
    also ich steh mal wieder vor einer Wand. Aufgabe ist es mithilfe von array, struct, strings und schleifen ( keine vordefinierten funktionen aus der bibliothek) folgendes Porgramm zu schreiben:
    Schreiben Sie ein C++ Programm, welches einen Text in Form von
    mehreren Eingabezeilen einliest. Das Programm soll die in dem Text
    auftretenden Worte in der Reihenfolge ihres Auftretens mitsamt der
    Häufigkeit ihres Vorkommens im Text ausgeben.
    Auch hier soll jedes wort in einer zeile stehen.
    Dabei sollen wir diese funktionen verwenden:
    1)
    void zaehle_wort(string wort, w_haeufigkeit haeufigkeit[], int& w_count)
    {...}
    2)
    string naechstes_wort(string zeile, int& pos)
    {...}

    Ich weiß nicht, ob meine erste Funktion (zaehle_wort) richtig ist (da ich durch das fehlen der zweiten funktion das programm gar nicht starten kann)
    Bei der zweiten Funktion weiß ich zwar, was ich da stehen haben möchte, aber es wird immer ein fehler angezeigt. Ich möchte, dass der array haeufigkeit mit jeden funktionsaufruf ein weiteres wort speichert. Gleichzeit soll ein counter die worte zählen, welche öfter vorkommen. Aber irgendwie weiß ich nicht wie ich das codieren soll

    Da der Coder so doof ausgegeben wird, werde ich erstmal nur die main und dann seperat als Antwort die beiden Funktionen posten
    Bis auf die eingabe ist die gesamte Main in der aufgabenstellung bereits vorgegeben gewesen. Also darf ich an ihr nichts ändern. Die funktionsrümpfe bisher sind vor mir
    int main()
    {

    const int text = 2;
    string eingabe[text];
    int i = 0;
    int z_count = 0, w_count = 0; // zeilen counter und wort counter
    string wort = "";
    //es gibt maximal 5 eingaben
    
    w_haeufigkeit haeufigkeit[1000]; // es kann maximal 1000 worthäufigkeiten geben
    
    // eigeneder code
    for (; i < text; i++) // ZEILE 11-19 IST VON MIR
    {
    	cout << "Eingabezeile " << i+1<< " : ";
    	getline(cin, eingabe[i]);
    	if (eingabe[i] == "")
    	{
    		break;
    	}
    	z_count = i; // z_counter beschreibt die anzahl der eingegeben zeilen
    }
    
    
    for (int k = 0; k < z_count; k++)
    {
    	int pos = 0;
    	while (true) // solange k kleiner als z_count ist mache...
    	{
    		wort = naechstes_wort(eingabe[k], pos); // wort muss oben in der funktion ausgegeben werden
    		if (wort == "")
    			break;
    		zaehle_wort(wort, haeufigkeit, w_count);
    	}
    }
    
    for (int k = 0; k < w_count; k++)
    	cout << haeufigkeit[k].haeufigkeit<< endl;
    
    system("PAUSE");
    return 0;
    

    }



  • struct w_haeufigkeit {
    string wort;
    int haeufigkeit;
    };

    string naechstes_wort(string zeile, int& pos) // funktion muss einen Rückgabewert vom Typ string haben
    {

    for (int pos = 0; zeile[pos] < zeile.length(); pos++)
    {
    
    	while(zeile[pos] != ' ')
    	{
    		pos++;
    		zeile += pos; // damit bildet sich buchstabe für buchstabe das Wort
    	}
    
    	pos = 0;
    
    	if (zeile[pos] == zeile.length())
    	{
    		zeile = "";
    		break;
    	}
    
    }
    return zeile; // mit zeile ist das wort gemeint
    

    }



  • Mit das größte problem ist diese funktion...
    Zeile 8 wird mir als fehler angezeigt

    void zaehle_wort(string wort, w_haeufigkeit haeufigkeit[], int& w_count)
    {

    w_count = -1; // w_count ist der wert des arrays haeufigkeit vom typ w_haeufigkeit zu anfang ist er auf -1 eingesetzt
    //füge wort als element von haeufigkeit ein und erhöhe w-count
    
    for (int i = 0; i <= wort.length(); i++)
    {
    	haeufigkeit[i] = { wort }; // kann man das so schreiben? wird dann wirklich jeden array element mit dem wort initialisiert
    
    	if (haeufigkeit[i] == wort)
    	{
    		w_count++;
    	}
    }
    

    }



  • also um das nächste wort zu suchen könntest du für jeden buchstaben im im überprüfen, ob dieser und alle weiteren mit dem zu suchenden wort übereinstimmen. beispiel:

    string text = "dies ist ein ganz toller text."
    string wort = "text";
    int wortposition;
    
    
    for(int i = 0; i < text.length() - wort.length; i++) // text zeichen für zeichen durchlaufen - wort.length weil bspw. "tex" nicht zählt
    {
         for(int j = 0; j < wort.length(); j++)
         {
              int anzahl_uebereinstimmende_zeichen = 0;
    
              while(text[i + j] = wort[j])
              {
                   anzahl_uebereinstimmende_zeichen++;
              }
    
              if(anzahl_uebereinstimmende_zeichen == wort.length)
              {
                   //abspeichern von i bzw. i + offset und verlassen der schleifen bzw. der funktion mit positivem rückgabewert
              }
         }
    }
    
    

    und um die anzahl der wörter zu zählen könntest du jedes mal, wenn funktion zum suchen einen positiven rückgabewert liefert, den zähler erhöhen. übrigens:

          //hier werden äpfel mit birnen bzw. eine datenstruktur die ein wort enthält mit einem wort verglichen
    	if (haeufigkeit[i] == wort)
    	{
    		w_count++;
    	}
    
          //hier wird ein wort mit einem wort verglichen
    	if (haeufigkeit[i].wort == wort)
    	{
    		w_count++;
    	}
    

    klappt doch ganz wunderbar den code darzustellen, also einrückungen jetzt mal außen vor. dazu am besten 5 leerzeichen eingeben, markieren und mit copy & paste an den entsprechenden stellen einfügen.

    int main()
    {
    const int text = 2;
    string eingabe[text];
    int i = 0;
    int z_count = 0, w_count = 0; // zeilen counter und wort counter
    string wort = "";
    //es gibt maximal 5 eingaben
    
    w_haeufigkeit haeufigkeit[1000]; // es kann maximal 1000 worthäufigkeiten geben
    
    // eigeneder code
    for (; i < text; i++) // ZEILE 11-19 IST VON MIR
    {
    	cout << "Eingabezeile " << i+1<< " : ";
    	getline(cin, eingabe[i]);
    	if (eingabe[i] == "")
    	{
    		break;
    	}
    	z_count = i; // z_counter beschreibt die anzahl der eingegeben zeilen
    }
    
    
    for (int k = 0; k < z_count; k++)
    {
    	int pos = 0;
    	while (true) // solange k kleiner als z_count ist mache...
    	{
    		wort = naechstes_wort(eingabe[k], pos); // wort muss oben in der funktion ausgegeben werden
    		if (wort == "")
    			break;
    		zaehle_wort(wort, haeufigkeit, w_count);
    	}
    }
    
    for (int k = 0; k < w_count; k++)
    	cout << haeufigkeit[k].haeufigkeit<< endl;
    
    system("PAUSE");
    return 0;
    }
    
    struct w_haeufigkeit {
    string wort;
    int haeufigkeit;
    };
    
    string naechstes_wort(string zeile, int& pos) // funktion muss einen Rückgabewert vom Typ string haben
    {
    for (int pos = 0; zeile[pos] < zeile.length(); pos++)
    {
    
    	while(zeile[pos] != ' ')
    	{
    		pos++;
    		zeile += pos; // damit bildet sich buchstabe für buchstabe das Wort
    	}
    
    	pos = 0;
    
    	if (zeile[pos] == zeile.length())
    	{
    		zeile = "";
    		break;
    	}
    
    }
    return zeile; // mit zeile ist das wort gemeint
    }
    
    void zaehle_wort(string wort, w_haeufigkeit haeufigkeit[], int& w_count)
    {
         w_count = -1; // w_count ist der wert des arrays haeufigkeit vom typ w_haeufigkeit zu anfang ist er auf -1 eingesetzt
         //füge wort als element von haeufigkeit ein und erhöhe w-count
    
    for (int i = 0; i <= wort.length(); i++)
    {
    	haeufigkeit[i] = { wort }; // kann man das so schreiben? wird dann wirklich jeden array element mit dem wort initialisiert
    
    	if (haeufigkeit[i] == wort)
    	{
    		w_count++;
    	}
         }
    }
    


  • @Wade1234 hi, danke erstmal für deine Antwort 🙂
    tut mir leid ich musste gestern dringend weg und konnte dann gar nicht mehr nachschauen ...
    ja das mit if (hauefigkeit [i] == wort) ist wirklich quatsch, aber ich hab die zeile so gelassen, damit man sieht, was ich eigentlich ausdrücken möchte, aber es nicht schaffe:D
    könntest du mir eventuell zeigen, wie ich auf einen struct array zufriff erhalte?
    ich halt mich mal an deine tipps und versuche es erneut



  • Das hat @Wade1234 dir doch in Zeile 8 seines 2. Codes gezeigt.



  • @Th69 oh stimmt das hab ich übersehen 😃 danke



  • @Th69
    kannst du mir eventuell sagen, was genau mit den while(true) gemeint ist?
    ich versuche gerade noch immer zu verstehen, was hier genau gemacht wird. Bieht sich das true auf die äußere Schleife, oder auf int pos=0?
    bisher bin ich davon ausgegangen, dass damit die äußere schleife gemeint ist

    for (int k = 0; k < z_count; k++)
    {
    	int pos = 0;
    	while (true) // solange k kleiner als z_count ist mache...
    	{
    		wort = naechstes_wort(eingabe[k], pos); // wort muss oben in der funktion ausgegeben werden
    		if (wort == "")
    			break;
    		zaehle_wort(wort, haeufigkeit, w_count);
    	}
    }


  • @Wade1234 zu deinem ersten code beispiel. Das geht (meines Erachtens ) nicht, weil ja die wörte noch gar nicht getrennt vorliegen. Ich gehe davon aus, dass dies genau in dieser funktion gemacht werden soll... also wort.length gibt es noch nicht, oder?



  • @mmm_1482_ das sollte eigentlich wort.length() heißen. im prinzip wird text ab position i mit wort verglichen.

    dies ist ein ganz toller text. //i = 0, keine übereinstimmung
    text
    
    dies ist ein ganz toller text. //i = 1, keine übereinstimmung
     text
    
    dies ist ein ganz toller text. //i = 2, keine übereinstimmung
      text
    
    dies ist ein ganz toller text. //i = 3, keine übereinstimmung
       text
    
    ...
    
    dies ist ein ganz toller text. //i = 25, übereinstimmung
                             text
    
    dies ist ein ganz toller text. //i = textlänge - wortlänge, keine übereinstimmung
                              text
    

    ich hab das oben übrigens mal korrigiert: es muss text[i + j] == wort[j] heißen.



  • @Wade1234 wäre dieser Code auch korrekt? also er ist nicht ganze korrekt, weil beim debuggen nimmt er zwar das erste zeichen des strings, aber er überspringt die schleife, obwohl die bedingung noch erfüllt ist
    außer er nimmt den integerwert von zeichen[pos] aber eigentlich sollte es das nicht tun, oder? 😃 ist ja ein string und ich vergleiche die position des strings

    string naechstes_wort(string zeile, int& pos) // zeile ="laura hat" pos=0 (referenz)

    {

    for (; zeile[pos]< zeile.length(); ) // zeile wird übersprungen
    {
    
    	if (zeile.at(pos) != ' ')
    	{
    		zeile += zeile[pos];
    		pos++;
    	}
    	
    	else
    	{
    		break;
    	}
    }
    return zeile; // wort vor leerzeichen wir in zeichen gespeichert
    

    }



  • @mmm_1482_ sagte in struct elemente in funktionen:

    zeile += zeile[pos];

    was soll zeile += zeile[pos]; genau bewirken? und was zeile[pos]< zeile.length();?



  • @Wade1234 eigentlich soll sie bewirken, dass mit jeder positiven ifbedingung ( also alles was ungleich eines leerzeichens ist) buchstabe für buchstabe angehängt wird. Aber mir fällt gerade auf, dass ich dafür am besten einen leeren string definiere .. weil zeile ja bereits den string von eingabe [k] besetzt. ich nehme das zurück XD die positionen des strings werden ja mit neuen werten besetzt

    zeile[pos]< zeile.length() soll bewirken, dass jedes Zeichen des strings durchgegangen wird.
    ich gehe somit jedes zeichen des strings durch. aber irgendwas stimmt mit der bedinungung nicht, weil sie anscheinen direkt falsch ist und übersprungen wird
    Im debugger hat zeichen[pos] auch den wert des ersten buchstabens, aber dieser wert kann nicht in der inneren schleife gespeichert werden, weil die bedingung falsch ist



  • @mmm_1482_ ach jetzt verstehe ich das. ja dafür musst du einen leeren string nehmen und diesen dann zurückgeben.

    mit zeile[pos]< zeile.length(); vergleichst du jedenfalls den wert des zeichens (mindestens 48 für 0 und für z irgendwas noch größeres) mit der länge der zeile. aber du willst ja sicherlich die position mit der länge der zeile vergleichen......



  • @mmm_1482_: Den Fehler bzgl. zeile[pos]< zeile.length() hattest du doch schon mal und ich habe dich drauf hingewiesen (wie man richtig iteriert)?!



  • @Th69 ich komm da irgendwie immer durcheinander.. ich dachte das müsste so gehen und hab mich total gewundert



  • @mmm_1482_ dann ist es mal an der zeit, sich die jeweiligen methoden anzusehen und zu überlegen, ob die überhaupt zusammen passen:

    http://www.cplusplus.com/reference/string/string/operator[]/
    http://www.cplusplus.com/reference/string/string/length/

    string allgemein: http://www.cplusplus.com/reference/string/string/



  • @Wade1234
    Mit dieser bedingung geht es zumindest in die schleife rein 😃

    string tmpstr = "";

    for (int i=0; zeile[i]>='a' && zeile[i]<='z'; i++) // zeile wird übersprungen
    {
    	if (zeile.at(i) != ' ')
    	{
    		tmpstr += zeile[pos];
                        zeile[pos] == tmpstr[pos];
    		pos++;
    		
    	}
    	
    	if(zeile.at(pos)== ' ')
    	{
    		return zeile;
    	}
    	 // wort vor leerzeichen wir in zeichen gespeichert
    }


  • @Wade1234 danke für die links 🙂
    im grunde weiß ich das mit den zahlen, nur hab ich irgendwie gedacht, dass ( wenn es es die position des strings ist) auch das zeichen selbst verglichen wird. Aber das muss ich mir definiv einprägen



  • @mmm_1482_ wie wäre es mit

    while(pos < zeile.length())
    {
         //mach irgendwas
    
         pos++;
    }
    

    ?


Anmelden zum Antworten