Aufgabe korrekt gelöst ?



  • Hallo,

    meine aufgabe war :

    ich soll strings einlesen ,das wort das am meißten vorkommt soll ausgegeben werden und es soll auch angezeigt werden wie oft das wort vorgekommen ist.

    leider gibt es keine musterlösung und ich wollte fragen ob es an diesem programm etwas zu bemängeln gibt.

    #include <iostream>
    #include <vector>
    #include <string>
    using namespace std;
    
    int main ()
    {
    vector<string> svec;
    string tmp, word;
    int i = 0, biggest = 0, howmuch = 0;
    while (cin>>tmp)
    {
    
    	svec.push_back(tmp);
    
    	for(vector<string>::iterator iter=svec.begin(); iter!=svec.end(); ++iter )
    	{
    		for(vector<string>::iterator iter1=svec.begin(); iter1!=svec.end(); ++iter1 )
    		{
    			if (*iter == *iter1)
    			{
    				howmuch++;
    
    			}
    				if (howmuch > biggest)
    				{
    					biggest = howmuch;
    					word = *iter;
    				}
    		}
    		howmuch = 0;
    	}
    
    	cout << "----------------------"<<endl;
    	cout << "Word: " << word <<" = " << biggest << endl; 
    	cout << "----------------------"<<endl;	
    }
    
    }
    


  • Hallo kantaki,

    kantaki schrieb:

    .. ich wollte fragen ob es an diesem programm etwas zu bemängeln gibt.

    Also nur Kleinigkeiten.
    Zunächst der Stil - wenn man korrekt einrückt und einige zu viel gewordenen Leerzeilen enfernt, lässt es sich auch leichter lesen:

    kantaki schrieb:

    #include <iostream>
    #include <vector>
    #include <string>
    using namespace std;
    
    int main ()
    {
        vector<string> svec;
        string tmp, word;
        int i = 0, biggest = 0, howmuch = 0;
        while (cin>>tmp)
        {
            svec.push_back(tmp);
    
            for(vector<string>::iterator iter=svec.begin(); iter!=svec.end(); ++iter )
            {
                for(vector<string>::iterator iter1=svec.begin(); iter1!=svec.end(); ++iter1 )
                {
                    if (*iter == *iter1)
                    {
                        howmuch++;
                    }
                    if (howmuch > biggest)
                    {
                        biggest = howmuch;
                        word = *iter;
                    }
                }
                howmuch = 0;
            }
    
            cout << "----------------------"<<endl;
            cout << "Word: " << word <<" = " << biggest << endl;
            cout << "----------------------"<<endl;   
        }
    }
    

    Dann solltest Du Variablen möglichst spät deklarieren. Man würde dann auch eher merken, dass 'int i' gar nicht benötigt wird. Bei dem relativ kleinem Programm fällt das nicht so auf, aber bei größeren Programmen gewinnt man einiges an Übersicht. Kleiner Nebeneffekt wäre, dass das 'howmuch = 0;' oben in Zeile 30 einfach weg fällt.

    #include <iostream>
    #include <vector>
    #include <string>
    
    int main ()
    {
        using namespace std;  // hier reicht das auch hin; so lokal wie möglich
        vector<string> svec;
        for( string tmp; cin>>tmp; ) // 'tmp' wird nur innerhalb der Schleife gebraucht, daher hier for statt while
        {
            svec.push_back(tmp);
    
            int biggest = 0;
            string word;
            for(vector<string>::iterator iter=svec.begin(); iter!=svec.end(); ++iter )
            {
                int howmuch = 0;
                for(vector<string>::iterator iter1=svec.begin(); iter1!=svec.end(); ++iter1 )
                {
                    if (*iter == *iter1)
                    {
                        ++howmuch;
                    }
                    if (howmuch > biggest)
                    {
                        biggest = howmuch;
                        word = *iter;
                    }
                }
            }
    
            cout << "----------------------"<<endl;
            cout << "Word: " << word <<" = " << biggest << endl;
            cout << "----------------------"<<endl;   
        }
    }
    

    Eventuell könnte man den Algorithmus zwischen Zeile 13 und 30 noch in eine eigenen Funktion fassen, um es mehr zu strukturieren.
    Weiter könnte man noch den Einsatz von Algorithmen aus dem C++-Standard empfehlen, wie z.B. count.
    Und last not least ließe sich der Algorithmus noch verbessern, wenn die Liste der Worte sortiert wäre .. denk mal drüber nach.

    Gruß
    Werner



  • super vielen dank 🙂



  • endl ist schlecht.



  • volkard schrieb:

    endl ist schlecht.

    endl ist gut.



  • Ich denke, hier muß man Struppi folgen und den Trick mit der map einfach zeigen.

    #include <iostream>
    #include <map>
    #include <string>
    using namespace std;
    
    int main ()
    {
    	map<string,int> smap;
    	string tmp,word;
    	int biggest=0;
    	while (cin>>tmp) {
    		int howmuch=++smap[tmp];
    		if (howmuch > biggest) {
    			biggest = howmuch;
    			word = tmp;
    		}
    		cout << "----------------------\n";
    		cout << "Word: " << word <<" = " << biggest << '\n';
    		cout << "----------------------\n";
    	}
    }
    


  • 314159265358979 schrieb:

    volkard schrieb:

    endl ist schlecht.

    endl ist gut.

    Weißt Du, was endl macht? Falls ja, wie begründest Du, daß hier endl verwendet werden soll?



  • 314159265358979 schrieb:

    volkard schrieb:

    endl ist schlecht.

    endl ist gut.

    endl ist gut, wenn einen die Geschwindigkeit nicht interessiert.



  • Wurstinator schrieb:

    314159265358979 schrieb:

    volkard schrieb:

    endl ist schlecht.

    endl ist gut.

    endl ist gut, wenn einen die Geschwindigkeit nicht interessiert.

    Also soll ich mir erst endl angewöhnen, weil die Konsole so langsam ist, und sobald ich in Dateien schreibe, soll ich es mir wieder abgewöhnen. Und später mal überlege ich immer, ob ich '\n' oder endl schreiben sollte, indem ich abschätze, ob zu befürchten ist, daß es schnell gehen soll.
    Nö.
    endl ist gut, wenn ich endl machen will. endl ist nicht gut, wenn ich nur '\n' machen will.



  • Ich fand nur die Aussage: "endl ist schlecht." als solches einfach schwachsinnig. Ich benutze endl, wenn ich \n meine, auch wenn mir gleich alle sagen werden, wie schlecht das doch ist.



  • 314159265358979 schrieb:

    Ich fand nur die Aussage: "endl ist schlecht." als solches einfach schwachsinnig.

    Na, wie gut, daß Du gefragt hast. Und jetzt darfst Du Dir endl wieder abgewöhnen.



  • Endl sagt für mich aber mehr aus als \n.



  • 314159265358979 schrieb:

    Endl sagt für mich aber mehr aus als \n.

    Mir auch. Deswegen nehme ich es nicht, wenn ich gar nicht flushen will.



  • wieviel schneller ist denn /n gegenüber endl ?



  • kantaki schrieb:

    wieviel schneller ist denn /n gegenüber endl ?

    Unendlich.

    endl flusht den Stream. Was zB bei einer Datei bedeutet, dass diese erst vollstaendig auf die Festplatte geschrieben werden muss bevor endl fertig ist. Das bedeutet seeken auf der Platte, Schreibkopf positionieren und schreiben. Das kann dauern.

    Es hebelt ja eine Menge optimierungen des Systems aus: denn solche festplattenzugriffe sind enorm langsam - deshalb wird das alles gecacht und spaeter geschrieben.

    Flush ist extrem teuer. Es macht ja auch so gut wie nie Sinn.



  • aber flushed cout nicht automatisch ?



  • kantaki schrieb:

    aber flushed cout nicht automatisch ?

    cout geht idR auf die Konsole. Die ist so oder so langsam.
    Wo endl teuer wird ist, wenn die Daten auf eine Speichermedium geschrieben werden, oder ins Netzwerk oder so.

    Deshalb faellt es nicht auf, weils bei cout egal ist. Nur wenn man dann cout ploetzlich auf die Platte redirectet oder einen anderen Stream verwendet der auf die Platte/Netzwerk schreibt - dann bricht die Performance ploetzlich komplett ein.

    Deshalb gleich richtig machen.



  • okay danke


Anmelden zum Antworten