String zu Integer einmal anders
-
Hallo!
Alleine bei der Überschrift gähnen wahrscheinlich alle.
Jedoch konnte ich leider in keinem Beitrag irgendeines Forums etwas finden, das mit weiterhilft...Das Problem:
Aus einer datei wird ein text eingelesen und ist fortan in einem String xyz hinerlegt. Dieser String teilt sich in zwei Bereiche auf. Zum einen in den bereich, der einen festen regelsatzes steuern soll ("abacad" Regel a->b>a....) und einen zweiten binären bereich in dem parameter für die regeln gespeichert werden. nun muss ich aus den 0en und 1en im zweiten bereich irgendwie integer/bzw. floats machen. Leider funktioniert das mit einem einfachen zeiger auf den zweiten bereich nicht! (int i =&z (da wo die 0en und 1en liegen). sscanf("00010", %i, i) macht zwar etwas, allerdings nicht auf basis des binären systems sondern de 8er-Systems!
Frage:
- weiß jemand, wie man sscanf dazu bekommt im 2er-system zu arbeiten?
- oder eine andere Lösung?Grüße und schon einmal vielen Dank!
-
Wenn du nicht selbst was schreiben willst, könntest du ggf das bitset Template verwenden:
unsigned long x = 0; std::bitset<8> xyz( std::string( "01010" ) ); x = xyz.to_ulong();
-
j-o-e schrieb:
Aus einer datei wird ein text eingelesen und ist fortan in einem String xyz hinerlegt.
ist das schon fix, oder darf man auch direkt aus der Datei lesen?
j-o-e schrieb:
Dieser String teilt sich in zwei Bereiche auf. Zum einen in den bereich, der einen festen regelsatzes steuern soll ("abacad" Regel a->b>a....) und einen zweiten binären bereich in dem parameter für die regeln gespeichert werden. nun muss ich aus den 0en und 1en im zweiten bereich irgendwie integer/bzw. floats machen.
wie ist das genaue Format? steht das
"abacad" Regel a->b>a....genau so in der Datei, wenn Du sie mit einem Texteditor öffnest?
Sind die Parameter wirklich binär gespeichert - d.h. in einem Texteditor siehst Du nur wirres Zeug - oder kann man die 0'en und 1'en im Texteditor sehen?
:xmas2: Werner
-
[quote="Werner Salomon"] ist das schon fix, oder darf man auch direkt aus der Datei lesen?[/quote]
fix ist relativ, aber eigentlich sollten die Daten (steuerdaten und parameter( schon in einer Datei gespeichert werden und dann eben auch gemeinsam eingelesen werden.
[quote="Werner Salomon"] wie ist das genaue Format? steht das
"abacad" Regel a->b>a....genau so in der Datei, wenn Du sie mit einem Texteditor öffnest? [/quote]
nein, das Format steht noch nicht fest. die beschreibung soll an die DNA des Menschen angelehnt sein, in der datei sind also verschiedene Gene/Module enthalten, welche einen erzeugungsalgorithmus steuern sollen(der steht wenigstens) die Datei reiht also beliebig viele module aneinander, ein Modul hat die ungefähre Form:
mi0101101010...ea1111bcabb...[quote="Werner Salomon"] Sind die Parameter wirklich binär gespeichert - d.h. in einem Texteditor siehst Du nur wirres Zeug - oder kann man die 0'en und 1'en im Texteditor sehen?[/quote]
also im texteditor sind die 1en und die 0en sichtbar - ist aber kein muss....
löst man das besser anders??
-
j-o-e schrieb:
Werner Salomon schrieb:
ist das schon fix, oder darf man auch direkt aus der Datei lesen?
fix ist relativ, aber eigentlich sollten die Daten (steuerdaten und parameter( schon in einer Datei gespeichert werden und dann eben auch gemeinsam eingelesen werden.
das war nicht was ich meinte, das in eine Datei zu seichern ist schon ok. .. Die Frage war, ob Du beim Einlesen den Umweg über den String nehmen willst/musst. Ich unterstelle mal, dass das nicht zwingend ist, d.h. der String ist Dir nicht als Schnittstelle vorgegeben.
In C++ benutzt man einen Stream, um Daten (float, int, eigenen Objekte) einzulesen.
j-o-e schrieb:
Werner Salomon schrieb:
wie ist das genaue Format? steht das
"abacad" Regel a->b>a....genau so in der Datei, wenn Du sie mit einem Texteditor öffnest?
nein, das Format steht noch nicht fest. die beschreibung soll an die DNA des Menschen angelehnt sein, in der datei sind also verschiedene Gene/Module enthalten, welche einen erzeugungsalgorithmus steuern sollen(der steht wenigstens) die Datei reiht also beliebig viele module aneinander, ein Modul hat die ungefähre Form:
mi0101101010...ea1111bcabb...Puh .. könntest Du noch ein paar Beispiele angeben, und auch erklären was was ist, und in welche C++-Typen das abgelegt werden soll. Dann kann ich Dir erklären, wie das geht.
j-o-e schrieb:
Werner Salomon schrieb:
Sind die Parameter wirklich binär gespeichert - d.h. in einem Texteditor siehst Du nur wirres Zeug - oder kann man die 0'en und 1'en im Texteditor sehen?
also im texteditor sind die 1en und die 0en sichtbar - ist aber kein muss....
löst man das besser anders??ja - schreibe die Zahlen einfach in die Datei - also im Dezimalformat. Wenn dort eine 1075 steht dann heißt das auch 1075 - eigentlich ganz einfach. Wichtig ist, dass die Zahl durch Freizeichen (Space, Tabulator oder Zeilenende) begrenzt wird; dann kann sie per Stream auch einfach eingelesen werden.
:xmas2: Werner
-
Also als erstes einmal vielen Dank für die schnelle Hilfe!
also noch ein paar hintergrundinformationen:
- im Endeffekt geht es darum, dass ein gepulstes Neuronales Netz (SNN) simuliert werden soll. Der Simiulator hierfür steht schon. Die Datei/bzw der String soll alle informationen enthalten um das Neuronale Netz zu erzeugen.
- allerdings soll nicht nur ein SNN erzeugt werden sondern viele veschiedene. d.h. die Strings/Dateien sollen über einen Evolutionären Algorithmus verändert (mutiert) und gekreuzt werden. So soll sich im Laufe der Evolution ein SNN entwickeln, welches das gegebene Klassifikationsproblem lösen kann.-> von daher ist der weg über den String wichtig, da das einlesen der Datei eigentlich nur am Anfang des EA benötigt wird. Damit man aber gute Ergebnisse speichern kann sollte jederzeit eine gefundene Struktur in eine Datei geschrieben werden können....
Wie schon erwähnt besteht die Beschreinung aus verschiedenen Modulen. Diese Module bestehen aus Neuronen (mitsammt deren parameter) und Informationen für die verbindung der einzelnen Neuronen/Verbindungen. Mein Gedanke war der, den string mehrfach zu parsen. Dies ist für die verbindung der veschiedenen Module notwendig. im ersten schritt wird nur nach den Modulgrenzen ("m" "i" "e" -Modul ,Intron(parameter), Exon(codierender bereich)) gesucht und diese quasi als zeiger auf Positionen im String in Modul-objekten gespeichert (einfacher int position).
beim zweiten schritt dachte ich daran die Neuronen ("n") und die verschiedenen Marken für die synapsen ("b","c","d"- jeweils mit parametern aus "i") zu erzeugen.
im letzten schritt wird dann alles an den Simulator übergeben.weitere gedanken:
die binäre codierung habe ich mir deshalb gedacht, da ein mutieren recht einfach geht (0->1 oder andersherum) und über die menge der verschiedenen 0en und 1en eine recht guter/sinnvoller parameterbereich eingestellt werden kann. (für parameter x nehme ich nur 2bits, da ich keine werte über 3 benötige....)
lehrzeichen oder sonstiges würde ich gerne vermeiden, da die reihenfolge der codes nicht festgelegt sein soll - bzw durch mutationen verändert werden kann. würde also gerne immer die menge an bits aus dem bereich nehmen, die gerade benötigt werden und den zeiger um die benötigte anzahl weiterschieben...
-
... ganz schon aufwendig.
nur mal so viel: in C++ benutzt man Streams für die Ein- und Ausgabe. Da bei Dir komplexere Strukturen (Module, Neuronen, usw) existieren, so hast Du wahrscheinlich Klassen oder Strukturen, die diese programmtechnisch modellieren.
Dann erstellt man i.A. eine friend-Funktion, die das Einlesen einer solchen Struktur erledigt. Zum Beispiel:#include <iostream> #include <fstream> #include <vector> class Neuron { public: friend std::istream& operator>>( std::istream& in, Neuron& neuron ) { // hier steht der Code um das Neuron zu lesen return in; } }; class Modul { public: friend std::istream& operator>>( std::istream& in, Modul& modul ) { char c; if( in >> c ) // ersten Buchstaben lesen { if( c == 'm' ) // beginnt mit 'm' ; // usw. for( Neuron neuron; in >> neuron; ) // Neuron lesen { modul.m_neurons.push_back( neuron ); // im Modul aufnehmen // Abbruchbedingung if .. break; ?? } } return in; } private: std::vector< Neuron > m_neurons; }; int main() { using namespace std; ifstream in("Datei.txt"); // Datei zum Lesen öffnen for( Modul m; in >> m; ) // alle Module lesen { // Modul m abspeichern, etc. } return 0; }Das Einlesen der binären Parameter geht von Haus aus nicht, aber man kann es dem Stream beibringen. Ist aber kein Anfänger-Code ..
#include <iostream> #include <fstream> class BinaryGet : public std::num_get< char > // dies Ding liest ein Integer (long, int) { public: typedef std::num_get< char > base_type; explicit BinaryGet( std::size_t ref_cnt = 0 ) : base_type( ref_cnt ) {} protected: virtual iter_type do_get( iter_type in, iter_type end, std::ios_base& /*str*/, std::ios_base::iostate& err, long& val_ ) const { long val = 0; bool read = false; for( ; in != end; ++in, read = true ) { if( *in == '0' ) { val *= 2; } else if( *in == '1' ) { ++(val *= 2); } else break; } if( !read ) err |= std::ios_base::failbit; else val_ = val; if( in == end ) err |= std::ios_base::eofbit; return in; } }; int main() { using namespace std; ifstream in("Datei.txt"); // Datei zum Lesen öffnen in.imbue( locale( in.getloc(), new BinaryGet ) ); // ab jetzt Integer aus 'in' binär lesen char m,i; // die Zeichen int param; // ein (binärer) Parameter if( in >> m >> i >> param && m == 'm' && i == 'i' ) { // mi0101101010 gelesen cout << "Parameter: " << param << endl; } return 0; }Wenn die Datei
mi0101101010enthält, so bekommt man die Ausgabe
Parameter: 362:xmas2: Werner
-
vielen Dank für die vielen Infos.
Werde jetzt versuchen das ganze umzusetzen.
die Variante mit den bitsets scheint auch zu funktionieren - aber das andere ist wohl deutlich eleganter....