C++ Buchstabenzählung, Probleme mit while



  • Erstmal danke für die vielen Antworten! Ich werde gleich mal testen :-).

    Ja es sollen die Buchstaben gezählt und dann nach Häufigkeit gereit werden. Dachte mit Vektor müsste es doch gut klappen.

    lg



  • Skym0sh0 schrieb:

    volkard schrieb:

    fr33g schrieb:

    Außerdem empfehle ich dir std::string

    Ich nicht. Schon std::vector war fehl am Platze.

    wieso das denn, soll er C-Arrays nutzen?

    Ich nenne sie liebevoll C++-Arrays.



  • Danke hat mit while (cin.get(eing)) hats funktioniert 🙂 . Jetzt noch überlegen wie man das sortieren kann.



  • wieso das denn, soll er C-Arrays nutzen?

    Ja, was spricht denn dagegen? Ich hätte wahrscheinlich std::array gewählt, wegen der schöneren Iterationsmöglichkeiten, aber bei solchen Beispielen geht es auch wunderbar mit den guten alten C-Arrays.



  • wenn sortieren inherent ist, warum nicht ne map?

    #include <iostream>
    #include <map>
    
    int main()
    {
        std::map<char,int> myMap;
        typedef std::map<char,int>::const_iterator const_iter_myMap;
    
        // fill and initialize allowed characters
        for (char c='a'; c <= 'z'; ++c)
        {
            myMap[c]==0;
            myMap[std::toupper(c)]==0;
        }
    
        char eing;
        // capture, end with '\0'
        while ( std::cin.get(eing) )
        {
            if (myMap.find(eing) != myMap.end())
                myMap[eing]=myMap[eing]+1;    
        }
    
        // output
        for (const_iter_myMap it=myMap.begin() ; it != myMap.end(); it++ )
            if ((*it).second != 0)
                std::cout << (*it).first << " => " << (*it).second << " times" << std::endl;
    }
    


  • #include <iostream>
    #include <string>
    #include <cctype>
    
    int main()
    {
    	int vec[26] = {};
    
    	std::string buf;
    	std::getline(std::cin, buf);
    
    	for (std::string::iterator it = buf.begin(); it != buf.end(); ++it)
    	{
    		if (isalpha(*it))
    		{
    			++vec[std::tolower(*it) - 'a'];
    		}
    	}
    
    	for (unsigned int i = 0; i < 26; ++i)
    	{
    		if (vec[i] > 0) // ==> Ausgabe nur, falls Buchstabe existiert
    		{
    			std::cout<< static_cast<char>(i + 'a') << " = " << vec[i] << std::endl;
    		}
    	}
    }
    


  • padreigh schrieb:

    wenn sortieren inherent ist, warum nicht ne map?

    Weil for(int i='a';i<='z';++i) nicht minder sortiert ist.



  • volkard schrieb:

    padreigh schrieb:

    wenn sortieren inherent ist, warum nicht ne map?

    Weil for(int i='a';i<='z';++i) nicht minder sortiert ist.

    Das *mag* in irgend einer exotischem Fall nicht geordnet sein, die Map sortiert aber nach < und das ist für char's entsprechend überladen - also wird es bei der Ausgabe "irgendwie" über operator< sortiert sein... mag sein das sowas in C# dann als aAbBcCdD oder so sortiert ist - aber sortiert ist es 😃



  • padreigh schrieb:

    Das *mag* in irgend einer exotischem Fall nicht geordnet sein, die Map sortiert aber nach < und das ist für char's entsprechend überladen

    Cybermax007 will aber nach Häufigkeit und nicht nach Zeichen sortieren. Das heisst, char als Key bringt dabei nichts. int als Key geht aber auch nicht.

    Aber man könnte die Zeichen in einem zusätzlichen Schritt in einem anderen Container nach Häufigkeit sortiert abspeichern.



  • cybermax007 schrieb:

    <SNIPP> ... die eingegeben Buchstaben zählt und danach sortiert ausgibt. ...<SNAPP>

    Davon steht aber nichts im Ursprungspost - nur was von sortiert ausgeben. Ich habe für mich mal entschieden das er alphabetische Sortierung haben will 😉 wenn er was anderes will muss er das schon ein bisserl besser formulieren 🤡

    edith: Hubbs seh gerade, er hat ja nachspezifiziert. Der Fluch aller Informatiker 😛



  • Ja sollte dann nach Häufigkeit sortieren. Im Moment schaff ich es aber nur alphabetisch sortiert und ein weiteres problem hab ich auch noch, wenn ich eine eingabe mache die z.b. so aussieht "dsf jsaas" wertet er nur bis dsf aus und den rest des textes nicht mehr.

    Als Ausgabe hab ich mal gemacht:

    for(int i = 0; i < 26; i++)
    cout << static_cast<char>(i + 'A')
    << charcount[i];

    Kann man das noch sortieren oder muss man das generell anders machen?



  • Zu dem anderen Problem. Komme aus der Schleife nur mit Break, sonst ist ne endlos Schleife.Ich nehme an das ist der Grund warum er bei einem Leerzeichen dazwischen abbricht und nicht bis zum Ende des Textes auswertet. Im Endeffekt will ich ja mit dem Programm alle möglichen Texte,Mails auswerten können.

    while((cin.get(eing))){
    if((eing >= 'a') && (eing <= 'z')) charcount[eing - 'a']++;
    else if((eing >= 'A') && (eing <= 'Z')) charcount[ch - 'A']++; else break;
    }



  • Cybermax007 schrieb:

    Im Endeffekt will ich ja mit dem Programm alle möglichen Texte,Mails auswerten können.

    WAHHHH noch eine Nachspezifizierung. gib halt mal \0 ein, dann brauchste kein break



  • Cybermax007 schrieb:

    Zu dem anderen Problem. Komme aus der Schleife nur mit Break

    Doch, Du kommst raus, wenn Du das Betriebssystemspezifische Dateiendezeichen eingibst.
    Unter Linux [Strg]+[d], unter Windows [Strg]+[z]. Wenn ich mich recht erinnere.



  • padreigh schrieb:

    Cybermax007 schrieb:

    Im Endeffekt will ich ja mit dem Programm alle möglichen Texte,Mails auswerten können.

    WAHHHH noch eine Nachspezifizierung. gib halt mal \0 ein, dann brauchste kein break

    Das wird nicht klappern,
    Eingabe von \0 kommt ja als '\' '0' rein.
    Nur auf Sourcecodelevel gibt's die Escape-Sequenzen.



  • Buchstaben in map speichern (buchstabe als key, anzahl als value)
    Durchiterieren durch map und in ein multiset speichern mit größen vergleich nach .second als vergleich. Multiset ausgeben. Sollte doch so gehen, oder?



  • #include <vector>
    #include <iostream>
    #include <algorithm>
    #include <string>
    #include <iomanip>
    
    typedef std::vector<std::pair<int, char>> PairVec;
    
    void Inc(PairVec& vec, char c);
    
    int main()
    {
    	PairVec vec;
    
    	std::string buf;
        std::getline(std::cin, buf); 
    
    	double total = 0;
    
    	for (std::string::iterator it = buf.begin(); it != buf.end(); ++it)
        {
            if (isalpha(*it))
            {
    			Inc(vec, *it);
    
    			++total;
            }
        }
    
    	std::sort(vec.rbegin(), vec.rend());
    
    	std::cout.precision(3);
    
    	for (PairVec::iterator it = vec.begin(); it != vec.end(); ++it)
    	{
    		std::cout << it->second << " = " << (it->first / total) * 100 << "%" << std::endl;
    	}
    }
    
    void Inc(PairVec& vec, char c)
    {
    	for (PairVec::iterator it = vec.begin(); it != vec.end(); ++it)
    	{
    		if (it->second == c)
    		{
    			++it->first;
    			break;
    		}
    	}
    
    	vec.push_back(std::make_pair(1, c));
    }
    


  • Korrektur:

    #include <vector>
    #include <iostream>
    #include <algorithm>
    #include <string>
    #include <iomanip>
    
    typedef std::vector<std::pair<int, char>> PairVec;
    
    void Inc(PairVec& vec, char c);
    
    int main()
    {
    	PairVec vec;
    
    	std::string buf;
        std::getline(std::cin, buf); 
    
    	double total = 0;
    
    	for (std::string::iterator it = buf.begin(); it != buf.end(); ++it)
        {
            if (isalpha(*it))
            {
    			Inc(vec, *it);
    
    			++total;
            }
        }
    
    	std::sort(vec.rbegin(), vec.rend());
    
    	std::cout.precision(3);
    
    	for (PairVec::iterator it = vec.begin(); it != vec.end(); ++it)
    	{
    		std::cout << it->second << " = " << it->first << " : " << (it->first / total) * 100 << "%" << std::endl;
    	}
    }
    
    void Inc(PairVec& vec, char c)
    {
    	for (PairVec::iterator it = vec.begin(); it != vec.end(); ++it)
    	{
    		if (it->second == c)
    		{
    			++it->first;
    
    			return;
    		}
    	}
    
    	vec.push_back(std::make_pair(1, c));
    }
    

Anmelden zum Antworten