Problem mit Liste

Klaus1

Grünschnabel
Hi ich habe ein wirklich großes Problem und ich hoffe ihr könnt mir helfen.
Ich sitze gerade an einer Hausarbeit fürs Studium und komme einfach nicht weiter. Das Programm soll später einmal die Molamasse eines eingegebenen Stoffes berechnen. Heißt ein Stoff wird eingegeben z.B: CH3CH2OH das Programm erkennt 2 mal C 6 mal H und ein mal O in einer Datenbank ist die jeweilige MAsse hinterlegt also hier: H=1,008 C=12,01 O=16 berechnet wird dann 6*1,008+2*12,01+1*16. Habe jetzt eine schleife geschrieben die den Stoff einlesen müsste und die einzelnen Atome bzw. Häufigkeiten in eine Liste schreibt. aber jetzt weiß ich nicht wie ich wieder auf die Elemente in dieser Liste zugreifen kann um damit weiter zu rechnen.
Hier schon ma mein Ansatz:
PHP:
#include <iostream>

using namespace std;

int main ()
{
    string Molekuel;                                                            
    
    struct stoff
{
    char atom;
    int haeufigkeit;
    stoff *next;                                                         
};

    cin >> Molekuel;                                                              
    int laenge = Molekuel.length();                                               
    stoff *Anker = 0;                                                   
    stoff *node = new stoff;                                                      
    node->next = Anker;                                                           
    for (int i=0; i < laenge; i++)                                               
        {
            if(64 < Molekuel[i] < 91)                                                   // Großbuchstaben erkenennen mit ASCII Tabelle 
                               {                             
                                     i++;                                        // eine Stelle weitegehen 
                                   if (47 < Molekuel [i] < 58)                   // ZAhlen erkennen    
                                     {
                                           i--;                                        // wurde eine ZAhl erkannt gehe wieder zurüch (um Atombezteichnungen aus einen Buchstaben zu erkennen)          
                                           node-> atom = Molekuel [i];}
                                   if (96 < Molekuel [i] < 123)                        // Erkenenn von kleinbuchstaben 
                                      {  
                                          i--;                                    // wurde ein Kleinbuchstaben erkannt gehen eine stelle zurück        
                                          node -> atom = Molekuel [i];            //schreibe den vorangegangenen Großbuchstaben in die Liste
                                          i++;                                    //gehen wieder vor zum Kleinbuchstaben          
                                          node -> atom += Molekuel [i];}          //und hänge diesen an den Großbuchstaben in der Liste an 
                               }
             if (47 < Molekuel [i] < 58)                                           // Wird eine Zahl erkannt
                               {   i++;                                            //Gehe eine Stelle weiter        
                                   if (47 < Molekuel [i] < 58)                     //gucke ob auf ZAhl eine weitere folgt 
                                   {  i--;                                         // wenn ja gehe eine Stelle zurück           
                                      node -> haeufigkeit = Molekuel [i] * 10;     // Multipliziere Zahl mit 10 (aus Einstelliger Zahl wird zweistellige) dann schreibe die in Liste
                                      i++;                                         // gehe eine stelle weiter   
                                      node -> haeufigkeit += Molekuel [i];         // Hänge 2. Zahl an erste an    
                                      }
                                   else                                            // Wenn auf die 1. ZAhl keine 2. folgt    
                                   {
                                        i--;                                       // gehe eine Stelle zurück   
                                        node -> haeufigkeit = Molekuel [i];        // schreibe die Zahl in die List 
                                        } 
                                        } 
                                        }
    Anker =0;                                    
    cout <<   << endl;                                                             
    cout << Molekuel << endl;
    system("Pause");
}
schon einmal vielen dank!
 
Hi.

Man kann binäre Operatoren nicht so
Code:
if (3 < x < 5)
kombinieren, du musst schreiben
Code:
if (3 < x && x < 5)
.

Man verwendet keine magischen Zahlen im Code. Kein Mensch weiß was 64, 96, 47 etc. bedeutet. Verwende doch einfach Zeichenliterale, also z.B.
Code:
if ('a' <= Molekul[i] && Molekul[i] <= 'z')


Allerdings gibt es auch Standardfunktionen um zu prüfen ob ein Zeichen eine Ziffer ist bzw. ein Buchstabe: http://www.cplusplus.com/reference/clibrary/cctype/isdigit/ bzw. http://www.cplusplus.com/reference/clibrary/cctype/isalpha/ und siehe http://www.cplusplus.com/reference/clibrary/cctype/tolower/

Nun zu deinem Problem ;)

Du hast eine einfach verkettete Liste, d.h. du kannst nur vorwärts durchlaufen und nicht wieder zurück.

Du mußt also erstens Immer einen Zeiger auf den Kopf der Liste speichern und du mußt einen "Cursor" verwenden, wo du immer neue Elemente an die Liste anhängst.

Gruß
 
Hat das einen Grund warum du eine einfach verkette Liste baust? Warum benutzt du keinen std::vector oder ähnliches?
 
Super schon mal vielen vielen dank leider sind meine Kenntnisse in c++ sehr beschränkt, daher kann ich noch nicht sagen in wie weit mir die Antwort weiterhilft aber jetzt wei0 ich wenigstens was ich googeln muss.
Ich habe mich für eine verkettete Liste entschieden weil das das erste war auf das ich gestoßen bin und ich im ersten Moment den Anschein hatte das mir das weiterhilft. Daher habe ich jetzt wie oben begonnen.
Viele Grüße
 
Hi,

falls du dir das Leben etwas einfacher machen willst, kannst du dann wie gesagt auch einen vector zum Beispiel verwenden. Google mal nach std::vector wenn du möchtest. Mehr verrate ich erstmal nicht. Soll ja eine Übungsaufgabe fürs Studium sein. ;)
 
Sitze jetzt schon den ganzen Tag vor googel und versuche einen der beiden Vorschläge mir bei zubringen allerdings muss ich sagen ich verzweifle. Verschiedenen internetbeispiele funktionieren nicht und cih weiß nicht wie ich das noch schaffen soll daher bitte helft mir ein wenig konkreter ich wäre euch wirklich sehr dankbar.
@ Wolf natürlich soll das eine Übungsaufgabe sein, allerdings studiere ich Chemie muss das also nur bestehen und dann brauche ich das nie mehr.
 
Hey,
ich meinte so etwas in der Art ...

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

struct Molecule {
	char atom;
	int number;
};

int
main(int argc, char* argv[]) {

	std::vector<Molecule> list;

	std::string input;

	std::cout << "Bitte Molekül eingeben: ";	
	std::cin >> input;

	for (int i = 0; i < input.length(); i++) {

		char tmp = input[i];
		
		/** Do something with the char. */		

		Molecule mo;
		mo.atom = 'c';		// If char is a real char store it here.			
		mo.number = i + 2;		// If char is a number store it here.

		list.push_back(mo);	

	}

	for (int i = 0; i < list.size(); i++) {
		std::cout << list[i].atom << " " << list[i].number << std::endl;
	}

}

Dann kannst du nach dem parsen des Strings ganz bequem auf dem vector list weiterarbeiten.

Ob ein Buchstabe im String ein Buchstabe oder eine Zahl ist kannst du testen durch
if (tmp >= 'A' && tmp <= 'Z') und if (tmp >= '0' && tmp <= '9') ...
und guck dir mal atoi() an.
Damit solltest du schonmal weiterkommen. Ansonsten melde dich nochmal.

Gruß
Der Wolf
 
Zuletzt bearbeitet:
Tausend dank
Damit ich das richtig verstehe, das programm speichert Buchstaben jetzt in list[ i ].atom und zahlen in list[ i ].number ? wenn ich das programm starte und ein Molekül eingebe spuckt er mir
c 2
c 3
c 4
c 5
aus egal was ich eingebe.
Wie sieht das denn jetzt aus wenn ich z.B. Co (Cobalt) eingebe kann das auf diese weise von CO (Kohlenstoffmonooxid) unterschieden werden?
 
In Der Wolfs Code hat sich scheinbar ein Fehler eingeschlichen?
Zeile 28 sollte doch eher so aussehen:
C:
mo.atom = tmp;
Co und CO kannst du damit im Moment eigentlich nicht sonderlich gut unterscheiden, zumal ja der Atom-Name als char hinterlegt ist, also immer nur ein Zeichen lang sein darf. Das wäre das erste, was man ändern müsste.
Hm... auch die Zeile 29 sieht komisch aus. Du möchtest doch in "number" die Anzahl der Atome speichern? Wieso zählst du dann einfach 2 zum Index dazu? Selbst "input[i+2]" würde nicht gehen, weil du ja nicht sicher sein kannst, dass immer nach zwei Buchstaben die Anzahl kommt. Vielmehr müsste man, wenn man eine Zahl findet, doch das Atom, das davorsteht, so oft nehmen.
Edit: Ich hab das grade mal schnell probiert... vielleicht kommst du damit weiter:
C:
boost::regex r("([A-Z]{1}[a-z]{0,2})([0-9]*)");
Mit so einer Regex kannst du ganz einfach den Eingabestring in seine Einzelteile zerlegen, auch wenn er z. B. so aussieht: "CH3CUuq25OH"
 
Zuletzt bearbeitet:
Hmm ... hey, sorry. Das war eigentlich nicht als Fehler im Code gedacht. Der ganze Teil war nur als Beispiel. Deswegen auch die Kommentare alla /** Do something with char */ und // If char is char store it here ...
;)
Wollte nicht den ganzen Teil mit dem parsen vorweg nehmen. Sorry, falls dadurch Missverständnisse aufgekommen sind.

Wenn du dich mit den regulären Audrücken auskennst ist die Sache von engelmarkus natürlich super elegant und sollte auf jedenfall vorgezogen werden.

Ansonsten habt ihr natürlich recht. In atom sollte die Bezeichnung stehen und in number halt die Häufigkeit. :P
 
Zurück