Ergebnis 1 bis 13 von 13

Algorithm (C++) um Buchstaben in einem Wort zu vergleichen.

  1. #1 Zitieren
    Legende Avatar von Testgrave
    Registriert seit
    Jan 2007
    Ort
    Florida
    Beiträge
    7.451
    Hi,
    ich bin ein bisschen am Ende meines Wissens
    Ich bin gerade am Planen eines Programmes fuer meinen C++ Programmier Kurs...

    Kurz zum Problem:
    Ich muss ein Proramm schreiben, das eine txt datei einliest mit mindestens einigen tausend Woertern (Woerterbuch). Diese Woerter muss ich nach Woertern durchsuchen, die alphabetisch ansteigen... Also z.B. almost, adept, ghost, etc. Dann muss ich die gefunden Woerter alphabetisch sortiert ausgeben.

    Nungut... Das Einlesen ist kein Problem, das durchsuchen auch nicht wirklich, das ausgeben in alphabetischer Reihenfolge auch nicht...
    Aber... Ich weis einfach nicht wie ich den Algorithmus anpacke, der mir diese Woerter raussuchen soll. Also dass ich ein Wort nehme, dieses dann in Buchstaben aufsplitte und alle Buchstaben im Wort darauf untersuche, dass es aufsteigend Alphabetisch ist.

    Kann mir da evtl. jmd. helfen bzw. haette da jmd. eine Idee wie man soetwas anstellt?


    mfg Test-Grave
    [Bild: Newknightsig.gif]
    Der schrickestu gerñ kain uechtñ nÿmer gelerñ
    Testgrave ist offline

  2. #2 Zitieren
    Abenteurer Avatar von TheNok
    Registriert seit
    Aug 2013
    Ort
    Berlin
    Beiträge
    76
    Du kannst einfach in einer Schleife testen, ob der ASCII-Wert des aktuellen Buchstabens größer ist als der des vorherigen, ansonsten brichst du die Schleife ab.
    TheNok ist offline

  3. #3 Zitieren
    Legende Avatar von Testgrave
    Registriert seit
    Jan 2007
    Ort
    Florida
    Beiträge
    7.451
    Zitat Zitat von TheNok Beitrag anzeigen
    Du kannst einfach in einer Schleife testen, ob der ASCII-Wert des aktuellen Buchstabens größer ist als der des vorherigen, ansonsten brichst du die Schleife ab.
    Code:
    char IstAlpha(char Wort[])
    {
    	for (int index = 0;index < 10;index++)
    	{
    		if (Wort[index] < Wort[index-1])
    		{
    			return Wort[];
    		}
    	}
    }
    Ich hab das jetzt nur so hingeklatscht, wird wohl nicht so funktionieren und muss ins Bett : / Aber wollte nur noch einen Gedankengang rausbringen... Wuerde das "so in etwa" klappen?
    [Bild: Newknightsig.gif]
    Der schrickestu gerñ kain uechtñ nÿmer gelerñ
    Testgrave ist offline

  4. #4 Zitieren
    Abenteurer Avatar von TheNok
    Registriert seit
    Aug 2013
    Ort
    Berlin
    Beiträge
    76
    Nein.

    Das liefert ein positives Ergebnis, wenn bereits der zweite Buchstabe alphabetisch hinter dem ersten ist. Der Rest wird ignoriert.
    TheNok ist offline

  5. #5 Zitieren
    Ritter Avatar von ojas
    Registriert seit
    Jun 2008
    Ort
    Erde
    Beiträge
    1.787
    Zitat Zitat von Testgrave Beitrag anzeigen
    ... Woerter ... die alphabetisch ansteigen...
    Code:
    #include <algorithm>
    #include <string>
    
    bool istAlphabetischAnsteigend(const std::string& str)
    {
      return std::is_sorted(str.cbegin(), str.cend());
    }
    ojas ist offline

  6. #6 Zitieren
    Legende Avatar von Testgrave
    Registriert seit
    Jan 2007
    Ort
    Florida
    Beiträge
    7.451
    Zitat Zitat von ojas Beitrag anzeigen
    Code:
    #include <algorithm>
    #include <string>
    
    bool istAlphabetischAnsteigend(const std::string& str)
    {
      return std::is_sorted(str.cbegin(), str.cend());
    }
    Das ist schon alles?

    Ich werd mich wrsl heute ans Programm machen wenn ichs schaff (Erster Tag im Semester -.- ) dann probier ich mal rum, aufjedenfall Danke euch schonmal .


    mfg Test-Grave
    [Bild: Newknightsig.gif]
    Der schrickestu gerñ kain uechtñ nÿmer gelerñ
    Testgrave ist offline

  7. #7 Zitieren
    Ritter Avatar von ojas
    Registriert seit
    Jun 2008
    Ort
    Erde
    Beiträge
    1.787
    Zitat Zitat von Testgrave Beitrag anzeigen
    Das ist schon alles?
    Viele Algorithmen lassen sich beschleunigen, wenn die Eingabedaten sortiert sind. Wenn du zum Beispiel für zwei Arrays herausfinden möchtest, ob sie die gleichen Elemente enthalten, dann hat das normalerweise quadratische Laufzeit, bei sortierten Arrays aber lineare. Das wird wohl der Grund sein, warum std::is_sorted() seit C++11 Teil der Standardbibliothek ist.

    Bei gcc musst du das mit g++ -std=c++0x kompilieren; sonst werden C++11-spezifische Features nicht verwendet..
    ojas ist offline Geändert von ojas (26.08.2013 um 19:22 Uhr)

  8. #8 Zitieren
    Legende Avatar von Testgrave
    Registriert seit
    Jan 2007
    Ort
    Florida
    Beiträge
    7.451
    Okay... Also vorneweg... Mein Programm ist ziemlich chaotisch, das saeubere ich und fuege Kommentare ein wenn es endlich so laeuft wie es soll... Also bitte nichts dazu sagen (Auch, dass ich mal true/false und mal 1/0 verwende, die Files nicht wirklich ueberpruefe auf Fehler/ob sie ueberhaupt da sind, etc. )

    Also... Ich hab das Program gut zum laufen gebracht, alles laeuft, es durchsucht alles, gibt alles richtig aus findet alle Woerter bei denen die Buchstaben alphabetisch ansteigend sind, also passt super...
    Jetzt war heute Vorlesung und einer meiner Kommilitonen hat darauf bestanden, dass wenn wieder Program abgeben, es doch auch Woerter sein sollen, wo die Buchstaben Aufsteigend und/oder gleich sind... Sprich, nicht nur Woerter wie Ghost, Almost, etc. sondern auch Woerter wie Billowy...

    Super hab ich mir gedacht, kein Stress, nimmst du einfach das "=" hinter ">" weg und dann hab ich auch das geregelt...
    Das funktioniert aber jetzt ueberhaupt nicht mehr, ich krieg direkt die Rueckmeldung vom Debugger:
    Unhandled exception at 0x5adeca58 (msvcr100d.dll) in Wordlist.exe: 0xC0000005: Access violation writing location 0xabababab.
    Und das im File "memcpy.asm" in der Zeile:
    mov [edi],al ;U - write second byte to destination
    Ich weis, dass das Problem hier liegt:
    Code:
    bool searchWords(string word,int length)
    {
    
    	for(int index = 1;index < length;index++)
    	{
    		if(word[index-1] > word[index])                   //Mit >=  funktioniert es so
    			return false;										
    	}
    	return true;
    }

    Hier das gesamte Programm:
    Code:
    #include "stdafx.h"
    #include <iostream>
    #include <iomanip>
    #include <cctype>
    #include <string>
    #include <fstream>
    
    using namespace std;
    
    const int MIN_LENGTH = 4;
    
    void loadFile(fstream &,fstream &, string &,float,float);
    void writeOnFile(string [],fstream &);
    void alphaSortResult(string [],int);
    bool searchBadList(string,string [],int);
    bool searchWords(string,int);
    void Printwords();
    void Printresults(float,float,string);
    float yield(float,float);
    void findLongestWord(string,string, int);
    
    
    int main()
    {
    	int exit;
    	fstream list;
    	fstream examplewords;
    	string word;
    	string upword;
    	float Upword_Count = 0;
    	float Word_Count = 0;
    
    
    	list.open("Wordlist1.txt");
    	examplewords.open("Examplewords.txt");
    	loadFile(list,examplewords,word,Upword_Count,Word_Count);
    
    
    	list.close();
    
    	cout << "Press any key to exit..." << endl;
    	cin >> exit;
    	return 0;
    }
    
    void loadFile(fstream &list,fstream &examplewords, string &word,float Upword_Count,float Word_Count)
    {
    	bool found = 0;
    	bool found_bad = 0;
    	int wordlength;
    	int badwordlength;
    	string *goodlist;
    	goodlist = new string[200];					
    	string badword;
    	string badlist[30];
    	string longestword;
    	int c = 0;
    	int i = 0;
    	int wordlengthlongest = 4;
    	fstream results("Results.txt", ios::out);
    
    
    	while(examplewords)
    	{
    		examplewords >> badword;
    		badwordlength = badword.length();
    		for(int d = 0;d < badwordlength; d++)
    			{
    				badword[d] = tolower(badword[d]);
    			}
    		badlist[c] = badword;
    		c++;
    	}
    
    	if (list)
    	{
    		cout << "Processing File..." << endl;
    		while (list >> word)
    		{
    			found = 0;
    			Word_Count++;
    			wordlength = word.length();
    			if (wordlength >= MIN_LENGTH)
    			{
    				for(int count = 0;count < wordlength; count++)
    				{
    					word[count] = tolower(word[count]);
    				}
    				found = searchWords(word,wordlength);
    				if(found == 1)
    				{
    					found_bad = searchBadList(word,badlist,c);		
    					if(found_bad == 0)
    					{
    						Upword_Count++;
    						goodlist[i] = word;												
    						i++;															
    						findLongestWord(longestword,word,wordlengthlongest);
    					}
    				}
    				else
    				{
    					found = 0;
    				}
    			}
    		}
    	}
    	cout << longestword << endl;
    	alphaSortResult(goodlist,c);
    	writeOnFile(goodlist,results);
    	results.close();
    	Printwords();
    	Printresults(Upword_Count,Word_Count,longestword);
    	delete [] goodlist;
    	goodlist = 0;
    }
    
    void writeOnFile(string goodlist[],fstream &results)
    {	
    	int index = 0;
    
    	while (index < 173)
    	{
    		results << goodlist[index] << endl;
    		index++;
    	}
    }
    
    bool searchWords(string word,int length)
    {
    	for(int index = 1;index < length;index++)
    	{
    		if(word[index-1] > word[index])
    			return false;											
    	}
    	return true;
    }
    
    void Printwords()
    {
    	string upword;
    	fstream results("Results.txt", ios::in);
    	int a = 1;
    
    	while(results >> upword)
    	{
    		cout << a << ". \t" << upword << endl;
    		a++;
    	}
    }
    
    void Printresults(float Upword_Count,float Word_Count, string longestword)
    {
    	cout << "Words processed: " << Word_Count << endl;
    	cout << "Upwords found: " << Upword_Count << endl;
    	cout << "Longest Upword: " << longestword << endl;
    	cout << setprecision(2);
    	cout << "Percent found: " << yield(Upword_Count,Word_Count) <<"%" << endl;
    	cout << "\n\t\t\t\tCOMMENTS\n" << endl;
    	cout << "All Words in the list were processed." << endl;
    	cout << "The statistics are displayed without taking the example words into account." << endl;
    }
    
    float yield(float upwordcount,float wordcount)
    {
    	return (upwordcount / wordcount) * 100;
    }
    
    bool searchBadList(string word,string badlist[],int size)
    {
    	int index = 0;
    	bool found = false;
    
    	while(index<size && !found)
    	{
    		if (badlist[index] == word)
    		{
    			found = true;
    			return found;					
    		}
    		index++;
    	}
    	return false;
    }
    
    void alphaSortResult(string goodlist[],int size)
    {
    	int startScan, minIndex;
    	string minValue;
    
    	for (startScan = 0; startScan < (size - 1);startScan++)
    	{
    		minIndex = startScan;
    		minValue = goodlist[startScan];
    		for (int index = startScan + 1; index < size; index++)
    		{
    			if (goodlist[index] < minValue)
    			{
    				minValue = goodlist[index];
    				minIndex = index;
    			}
    		}
    		goodlist[minIndex] = goodlist[startScan];
    		goodlist[startScan] = minValue;
    	}
    }


    Irgendjmd. eine Idee was ich machen kann, ohne gleich alles zu aendern?
    Wie kann ich so einen Fehler verhindern?

    Danke schonmal


    mfg Test-Grave
    [Bild: Newknightsig.gif]
    Der schrickestu gerñ kain uechtñ nÿmer gelerñ
    Testgrave ist offline Geändert von Testgrave (30.08.2013 um 04:05 Uhr)

  9. #9 Zitieren
    Ritter Avatar von ojas
    Registriert seit
    Jun 2008
    Ort
    Erde
    Beiträge
    1.787
    Zitat Zitat von Testgrave Beitrag anzeigen
    ... das saeubere ich und fuege Kommentare ein wenn es endlich so laeuft wie es soll...
    Mit Verlaub, das wirst du warhscheinlich nicht; trotz guter Vorstätze. Wahrscheinlich wirst du dich stattdessen and die zwei Grundätze Never change a running system und If it ain't broke, dont fix it halten. Ich spreche da aus eigener Erfahrung.

    Zitat Zitat von Testgrave Beitrag anzeigen
    Unhandled exception at 0x5adeca58 (msvcr100d.dll) in Wordlist.exe: 0xC0000005: Access violation writing location 0xabababab.
    Und das im File "memcpy.asm"

    ...

    Wie kann ich so einen Fehler verhindern?
    Verwende keine Arrays, sondern std::vector aus <vector>. Verwende keine C-Strings sondern std::string aus <string>. Vorteil dieser zwei Klassentemplates ist, dass deren Objekte wissen, wie groß sie sind. Dadurch sparst du dir, die Parameter length und size (die eine Fehlerquelle darstellen, da sie möglicherweise nicht den Tatsachen entsprechen). Außerdem können sie die Größe des verwalteten Speichers bei Bedarf anpassen.

    Verwende keine Zeiger.

    Zitat Zitat von Testgrave Beitrag anzeigen
    Code:
    if(word[index-1] > word[index])                   //Mit >=  funktioniert es so
    Das ist Zufall. Der Fehler liegt wo anders.

    Zitat Zitat von Testgrave Beitrag anzeigen
    Code:
    using namespace std;
    Es ist verantwortungslos, einem C++-Anfänger soetwas beizubringen. Aktuell ist damit zwar kein Schaden angerichtet, kann aber leicht passieren wenn man nicht weiß worauf man achten muss.
    ojas ist offline Geändert von ojas (30.08.2013 um 09:14 Uhr)

  10. #10 Zitieren
    Legende Avatar von Testgrave
    Registriert seit
    Jan 2007
    Ort
    Florida
    Beiträge
    7.451
    Zitat Zitat von ojas Beitrag anzeigen
    Mit Verlaub, das wirst du warhscheinlich nicht; trotz guter Vorstätze. Wahrscheinlich wirst du dich stattdessen and die zwei Grundätze Never change a running system und If it ain't broke, dont fix it halten. Ich spreche da aus eigener Erfahrung.
    Ne, das muss ich machen, auf jedes Programm gibt es eine Note im Semester, da waer ich schoen bloed das nicht so sauber wie moeglich abzugeben


    Verwende keine Arrays, sondern std::vector aus <vector>. Verwende keine C-Strings sondern std::string aus <string>. Vorteil dieser zwei Klassentemplates ist, dass deren Objekte wissen, wie groß sie sind. Dadurch sparst du dir, die Parameter length und size (die eine Fehlerquelle darstellen, da sie möglicherweise nicht den Tatsachen entsprechen). Außerdem können sie die Größe des verwalteten Speichers bei Bedarf anpassen.
    Ja das mit den C-Strings weis ich, aber wie koennte ich dieses Problem jetzt konkret mit Strings loesen? Bzw. ich meine jetzt nicht unbedingt, dass du mir die Loesung gibst, aber wie man damit umgehen kann, damit man solche Fehler vermeidet. Vectoren hatte ich leider noch nicht, die kommen erst in 1 oder 2 Monaten dran.

    Verwende keine Zeiger.
    Klar im Endeffekt hat ein Zeiger diesen Fehler ausgeloest, aber neben der dynamically allocated Memory fuer goodlist, hab ich doch eigentlich keine Zeiger drinnen, und ich meine jetzt direkt benutzt.



    Das ist Zufall. Der Fehler liegt wo anders.


    Es ist verantwortungslos, einem C++-Anfänger soetwas beizubringen. Aktuell ist damit zwar kein Schaden angerichtet, kann aber leicht passieren wenn man nicht weiß worauf man achten muss.
    Ohne using namespace std; kann ich z.B. cout/cin nicht benutzten, oder taeusche ich mich da? Zumindest in VS 2010...
    Was waere denn die Alternative? std::cout/cin? Habe damit noch nie gearbeitet und wurde auch nie von meinem Professor angesprochen...



    Aber jedenfalls schonmal vielen vielen Dank fuer die Antwort!


    mfg Test-Grave
    [Bild: Newknightsig.gif]
    Der schrickestu gerñ kain uechtñ nÿmer gelerñ
    Testgrave ist offline Geändert von Testgrave (30.08.2013 um 09:54 Uhr)

  11. #11 Zitieren
    Ritter Avatar von ojas
    Registriert seit
    Jun 2008
    Ort
    Erde
    Beiträge
    1.787
    Zitat Zitat von Testgrave Beitrag anzeigen
    Code:
    while(examplewords) /* ... */
    Was du damit wohl sagen möchtests ist
    So lange es im Stream noch Daten gibt, die ich noch nicht gelesen habe ...
    So funktionieren Streams aber nicht. Vielmehr liest examplewords >> badword irgendwann bis zum Ende des Streams, bool(examplewords) ist dann aber immer noch true. Erst bei einem erneuten examplewords >> badword wechselt bool(examplewords) auf false. Aus diesem Grund hast du mit
    Zitat Zitat von Testgrave Beitrag anzeigen
    Code:
    badlist[c] = badword;
    eine leere Zeichenkette in badlist aufgenommen.

    Verwende stattdessen while (examplewords >> badword) /* ... */, so wie du es auch beim Lesen von list machst.

    Zitat Zitat von Testgrave Beitrag anzeigen
    Code:
    	string badlist[30];
    	/*...*/
    	while(examplewords)
    	{
    		/* ... */
    		badlist[c] = badword;
    		c++;
    	}
    Du musst hier auf jeden Fall sicherstellen, dass c < 30 ist. Ebenso musst du bei
    Zitat Zitat von Testgrave Beitrag anzeigen
    Code:
    goodlist[i] = word;												
    i++;
    sicherstellent, dass i < 200 ist.

    Zitat Zitat von Testgrave Beitrag anzeigen
    Was waere denn die Alternative? std::cout/cin?
    Ja, genau. Funktioniert genau so wie cin. Besser gesagt, durch using namespace std; sagst du, dass du alles was im Namensraum std liegt ohne den std::-Präfix ansprechen können willst. Das führt zu Problemen wenn du in einem GIS-Programm den Namen map für die Klasse verwenden möchtest, die Landkarten repräsentiert oder in einem Börsenprogramm eine Klasse future für bestimmte Arten von Wertparpieren haben möchtest. Diese zwei Namen kollidieren dann nämlich mit std::map und std::future.

    Zitat Zitat von Testgrave Beitrag anzeigen
    ... wurde auch nie von meinem Professor angesprochen...
    Das habe ich befürchtet. Spätestens wenn ihr mit Headern arbeitet sind aber ein paar mahnende Worte angebracht. Hoffentlicht ist using namespace std; dann noch nicht zur Gewohnheit geworden, die schwer wieder abgelegt werden kann..
    ojas ist offline Geändert von ojas (30.08.2013 um 13:13 Uhr)

  12. #12 Zitieren
    Legende Avatar von Testgrave
    Registriert seit
    Jan 2007
    Ort
    Florida
    Beiträge
    7.451
    Vielen vielen dank nochmal!!! Danke das du dir die Zeit nimmst!
    Alles aufgenommen und wird umgebaut.

    Ich versuch mich grad mit vectoren... Und das mag sich jetzt bloed anhoeren, aber kann man einen vector<string> xxx in einen vector<string> zzz(999) speichern? Bzw. nur den string von dem einen in den naechsten Speicherplatz vom naechsten speichern?

    Ich krieg das irgendwie nicht so ganz hin mit Vectoren.
    Kann ich meine variable "word" als vector<string> durch die funktionen laufen lassen und dann diesen vector<string> word in meinem vector<string> goodlist() einspeichern? Oder bin ich da jetzt total auf dem Holzweg? (Bedenke, bei mir ist es fast 6 Uhr morgens und ich muss noch ins Bett, wuerde aber gerne zumindest etwas naeher an die Loesung ran kommen :O )


    mfg Test-Grave
    [Bild: Newknightsig.gif]
    Der schrickestu gerñ kain uechtñ nÿmer gelerñ
    Testgrave ist offline

  13. #13 Zitieren
    Ritter Avatar von ojas
    Registriert seit
    Jun 2008
    Ort
    Erde
    Beiträge
    1.787
    Zitat Zitat von Testgrave Beitrag anzeigen
    ... kann man einen vector<string> xxx in einen vector<string> zzz(999) speichern?
    Ich verstehe nicht was du meinst. In einem vector<string> kannst du strings speichern, und zwar genau so wie du sie in einem Array speicherst:

    • std::vector<std::string> vec;
      Vektor hat die Größe 0, kann also nichts speichern
    • vec.resize(10);
      Vektor besteht jetzt aus 10 leeren Zeichenketten
    • vec[0] = "Hello World!";
      Vektor besteht jetzt aus "Hello World!" gefolgt von 9 leeren Zeichenketten.
    • vec[10] = "Ich bin dann mal weg.";
      FEHLER, vec hat nur die Elemente 0 bis 9;
    • vec.push_back("Da bin ich wieder");
      Jetzt hat vec 11 Elemente, vec[0] ist "Hello World!", vec[1] bis vec[9] sind leere Zeichenketten, vec[10] ist "Da bin ich wieder";
    ojas ist offline

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •