Wortlängen bis Leerzeichen einer Stringkette ermitteln.

Hi Leute,

ich soll für eine Übungsaufgabe eine Art Wortlängenhistogramm erstellen. Jetzt hänge ich aber schon bei dem Punkt, wo ich den eingegebenen Satz in Wörter quasi "zerhacke" und die Wortlänge ermittle.


was ich schon habe ist.
Code:
int main()
{
string eingabe;
cout << "Text = ? ";
getline(cin, eingabe);



return 0;
}

also meine frage lautet einfach:
angenommen ich gebe dann einen Satz ein "Mein Name ist Hase".

jetzt will ich von jedem Wort die Länge ermitteln. Das Programm ansich hat zwar noch einige andere Restriktionen und Schwierigkeiten, aber ich hänge gerade an dieser Stelle.

Ausgabe des Programs:
4 ###
3 #
(das nur als kleiner Hinweis!, d.h. es gibt 3 Wörter der Wortlänge 4 und 1 Wort der Wortlänge 3).

-- nebeninfo --
Mein Ansatz war, ich erstelle eine int-Zahl als Array (int b[20] = {0};) und speichere in Array 0 die Wortlänge 1, in Array die Wortlängen 2.. ect... bis max. zur Wortlänge 20, alles andere wird als Wortlänge 20 ausgegeben (das nur als neben info, das mache ich schon selber).


achso:
am hilfreichsten wären vlt. Links (bei google habei ch nichts brauchbares gefunden) oder eine kurze erläuterung, es geht mir im endeffekt nicht direkt um die Lösung, sondern ich will das irgendwie selbst hinbekommen ;-)

danke
 
hier mal eine Lösung:

Code:
#include <iostream>
#include <string>

using namespace std;

int main()
{
	char x='x';
	int i=0,z=0; // Zählervariablen
	int b[20]={0};
	string text;

	cout << "\nText = ? "; 
	getline(cin, text); 


while (text[i] != '\0')
{	
		if (text[i] == ' ') 
		{
			b[z]=b[z]+1;
			z=0;
		}
		else z++;

i++;
	}

b[z]=b[z]+1; //abbruch, + '\0'

	i=0,z=0; // zähler für ausgabe zurücksetzen, eine vari reicht ...
	
	cout << "\n\n"; // formatierung ... 2 Zeilen /.
	
	//Ausgabe ... diag -> ## .. 
	while (i != 20)
	{
		if (b[i] != 0)
		{
		cout << i << " ";
			while (z < b[i])
			{
				cout << "#";
				z++;
			}
			cout << endl;
		}
		i++;
		z=0;
	}
	cout << endl << endl;
	return(0);
}

muss nur noch das mit den Wortlängen >20 = # für 20 einbringen, das is aber kein prob!

die lösung kam von nem freund, muss den code mal verstehen! der hats ohne die string libary gemacht sondern nur mithilfe von arrays, muss mir das nochmal anschauen.... hab ja noch paar tage zeit =D werden dann auch meine lösung präsentieren!
 
also ich würde einfach den string Buchstabe für Buchstabe von Anfang bis Ende durchgehen, und dabei immer die Anzahl der Buchstaben zählen, bis ich bei einem Leerzeichen ankomme. Dann würde ich die Anzahl der bis dahin vergangenen Buchstaben (wortlänge) in ein Element eines Arrays schreiben und das ganze solange machen, bis ich am Ende des Strings angekommen bin.
Dann würde Ich das array mit den Wortlängen durchgehen und schauen, wie oft jede Zahl drin vorkommt, und dann die Zahl und dahinter die Anzahl der Vorkommnisse in Rauten (#) ausgeben.
 
die 100% Lösung, keine Stacküberläufe, alle Werte > 20 werden korrekt als 20er Wortlängen gezählt:


Code:
#include <iostream>
#include <string>
using namespace std;
// Wortlängenhistogramm mit Arrays

int main()
{
	int b[20]={0}; // b[0] b[19] haben alle den Wert 0, Vorsicht: b[20] für zu Stacküberlauf, warum das so ist -> informiere dich ;P
	int c=0, i=0; // Zählervariablen
	string text;
	cout << "Text = ? ";
	getline(cin, text);

	// Buchstaben der einzelnen Wörter zählen & in Arrays speichern
	while (text[i]!='\0')
	{
		if(text[i]==' ')
		{
			if(c!=0){ // Prüfroutine 1: für mehrere Leerzeichen nacheinander 
			b[c-1] = b[c-1]+1; // da Wortlänge 1 = b[0] sein muss, sonst stack-überlauf 
			c=0; 
			}
		}
		else c++;
	if(c>20) c=20;
	i++;
	}
	if(c!= 0)	b[c-1] = b[c-1]+1; // schützt vor Stack-Überlauf wenn am Ende noch leerzeichen stehen. (vgl. Prüfroutine 1)


// # - Erzeugen, sollte mehr oder weniger selbsterklärend sein ;)
	i=0,c=0; // Zählervariablen
	cout << "\n";
	// ab hier beginnt der Ausgabenalgorithmus
	while (c != 20) 
	{				
		if (b[c] != 0) // 0 bedeutet, das Arrays die keine Werte haben, nicht dargestellt werden (alle Arrays wurden anfangs mit 0 definiert)
		{
		cout << c+1 << "  ";
			while (i < b[c]) 
			{
				cout << "#";
				i++;
			}
			cout << endl;
		}
		c++;
		i=0;
	}
	cout << endl << endl;
	return(0);
}

also ich habe mir das von oben bis unten nochmal selber erdacht, auch wenns identisch wie die erste Lösung zu sein scheint, hier sind aber noch einige Fixes drin....
 
Grade dieses Problem mit den Stacküberläufen kannst du vermeiden indem du C++ nutzt und nicht deinen Ansatz der eher C ist.

hier mal eine ungetestete Lösung von mir:

Code:
#include <iostream>
#include <string>
#include <algorithm>
#include <map>

void print_histogram_entry(const std::pair<int, int>& hp)
{
    std::cout<<hp.first<<" ";
    for(int i=0; i<hp.second; ++i)
        std::cout<<"#";
    std::cout<<std::endl;
}
int main()
{
    std::string zeile, wort;
    std::map<int, int> histogramm; //assoziatives array zum speichern des histogramms
    int loc=0, loc1=0;
    std::cout<<"Text eingeben: ";
    getline(std::cin, zeile); //zeile einlesen
    zeile+=" ";            //fürs leichtere parsen ein leerzeichen ranhängen
    while((loc1=zeile.find(" ", loc))!=std::string::npos){
        int tmp=zeile.substr(loc, loc1-loc).length(); //länge des einzelnen wortes ermitteln
        if(histogramm.find(tmp)==histogramm.end()) //wenn es bisher kein wort der länge gibt
            histogramm.insert(std::make_pair(tmp, 1)); //anzahl für die länge auf 1 setzen
        else
            histogramm[tmp]++; //sonst anzahl erhöhen
        loc=++loc1;
    }
    std::for_each(histogramm.begin(), histogramm.end(), print_histogram_entry); //einträge ausgeben
    return 0;
}

Mein Hinweis an dich, guck dir mal die STL an.
 
Hier hab ich mal eine Funktion geschrieben mit der man elegant Strings splitten kann.
Code:
#include <string.h>
#include <stdio.h>

int strToArray(char *string,char **res,int cnt,char *del);

int main(int argc, char* argv[])
{
	char line[100] = "A,B,C,D,E";
	char* res[10];
	char* del = ",";
	int cnt = 0;
	int i=0;

	cnt = strToArray(line,res,10,del);
	
	for(i=0;i<cnt;i++)
	{
		printf("%s\n",res[i]);
	}


	system("pause");
	return 0;
}

int strToArray(char *string,char **res,int cnt,char *del)
{
	int rv  = 0;
	char *tok;

	tok = strtok(string,del);
	
	while(tok && rv<cnt)
	{
		res[rv] = tok;
		tok = strtok(NULL,del);
		rv++;
	}

	return rv;
}
 
Zurück
Oben