Verschachtelter Array
-
Hi Leute!
Ich habe ein komplexeres Problem. Ich versuchs euch erstmal so gut wie möglich zu Schildern.Ich habe einen String der beliebig viele Backslashe (\) beinhaltet.
Dieser String soll in mehrere Strings unterteilt werden. Die Trennung soll bei jedem Backslash erfolgen.
Diese Teile des Strings sollen nun in einen Array gespeichert werden. Um genauer zu sein in einen verschachtelten Array, der nicht nur aus einem einzigen besteht. Man kann auch sagen, dass es eine sehr komplexe Zuordnung ist. Um euch das besser zu zeigen seht ihr hier eine "Grafik"dazu:
TV-Karte => Terratec => Cinergy TV Unterhaltung => Games => Port Royale 2 Winamp 5 Musik => WMP 10 Sonic Stage Programme => DVD => DVD Player Software Word Office => Excel Access
Ist das irgendwie möglich?
-
Das ist doch kein Array, sondern ein Baum.
Bye, TGGC (Pipe my World.)
-
TGGC schrieb:
Das ist doch kein Array, sondern ein Baum.
Bye, TGGC (Pipe my World.)
Was ist das für eine Klasse, die ich für einen solchen Baum benutzen muss?
-
Keine Ahnung, siehe MSDN.
Bye, TGGC (Pipe my World.)
-
Ok. Danke soweit.
Aber jetzt zu meinem anderen Problem. Wie kann ich den String in mehrere teilen (beim Backslash)? Am besten in einen Array.
-
Einen String aufteilen kannste mit CStringParser
einfach mal danach googlen
oder direkt bei codeproject.com
-
.. schrieb:
Einen String aufteilen kannste mit CStringParser
einfach mal danach googlen
oder direkt bei codeproject.com
DANKE
-
Also...ich hab jetzt nach etlichen Begriffen in der MSDN gesucht, doch das kann man vergessen!
Weiß vielleicht jemand etwas genaueres?
-
nimm doch die Standard C++ Library (STL):
#include <string> #include <map> // fuer STL und RTTI Compiler-Optionen /GX /GR verwenden typedef std::string String; class Node; typedef std::map<String,Node*> NodeMap; typedef std::pair<String,Node*> NodePair; typedef NodeMap::const_iterator NodeCIter; typedef NodeMap::iterator NodeIter; class Node { // "Knoten"-Klasse public: String title; NodeMap nodemap; Node( const String& _title ); ~Node( void ); Node* findOrCreate( const String& name ); void addPath( const String& path ); }; Node::Node( const String& _title ) : title(_title) { } Node::~Node( void ) { // loescht die Knoten in "nodemap". NodeCIter iter = nodemap.begin(); while ( iter != nodemap.end() ) { Node* node = iter->second; iter++; delete node; } nodemap.clear(); } Node* Node::findOrCreate( const String& name ) { NodeCIter iter = nodemap.find( name ); if ( iter != nodemap.end() ) { // Knoten mit diesem Namen existiert bereits return iter->second; // Node*-Feld in Iterator } Node* node = new Node( name ); // neuer Knoten nodemap.insert( NodePair( name, node ) ); // einfuegen return node; } void Node::addPath( const String& path ) { // fuegt Knoten unterhalb dieses Knotens hinzu size_t pos = path.find( '\\' ); // Backslash \ suchen if ( pos == String::npos ) { // \ nicht gefunden: leeren Knoten mit Namen einfuegen. findOrCreate( path ); return; } // sonst: Pfad hat einen oder mehrere \, String leftPart = path.substr( 0U, pos ); // linker Teil (vor \) String rightPart = path.substr( pos + 1U ); // rechter Teil (nach \) Node* node = findOrCreate( leftPart ); node->addPath( rightPart ); }
Um das Ganze zu verwenden, muss man nur einen Basis-Knoten haben:
Node* rootNode = new Node( "(root)" ); // ... void splitPath( const String& path ) { rootNode->addPath( path ); } // ... splitPath( "alpha\\beta\\gamma" );
-
Danke PowerOff!
Ich habs ausprobiert, aber irgendwie krieg ich es nicht richtig hin, den Code richtig zu benutzen bzw. in mein Projekt aufzu nehemen.Kannst du mir nochmal beschreiben, wie ich das machen muss? Ich wäre dir sehr dankbar!
-
Wahrscheinlich weil du den Code nicht verstehst. Das ist das Problem bei c&p.
Bye, TGGC (Pipe my World.)
-
Ja, deswegen will ich vielleicht, dass mir einer Hilft und einfach meine Fragen beantwortet?
Ich hoffe einer kann mir meine Fragen beantworten, die ich gestellt hatte.
Denn sonst nutzt mir auch nichts der beste Code.
-
Du musst einen Baum aufbauen.
Bye, TGGC (Ein Jahr Helden)
-
TGGC schrieb:
Du musst einen Baum aufbauen.
Bye, TGGC (Ein Jahr Helden)
P.S.: du weißt, dass du mir überhaupt nix neues gesagt hat?
-
hallo,
naja es gibt immer welche die nicht sonderlich hilfsbereit sind ... aber egal
also dein baumproblem habe ich nicht ganz verstanden, aber ich kann dir vielleicht bei der aufteilung des einen strings in mehrere strings helfen
In dem Codebeispiel unten wird eine Datei ausgelesen, deren Zeilen einzeln ausgelesen und die darin enthaltenen Werte (die durch ein Trennzeichen (zb "\") getrennt sind) auf ein neues Array geschrieben werden
CString Trennzeichen ="\"; while(File.ReadString(CString_hlp)) { Produktnr++; Spaltennr=0; while(1) { if(CString_hlp=="") break; Spaltennr++; //CString_hlp ist die aktuelle Zeile der Datei ... also bei dir das original Array CString_array_neu[Spaltennr][Produktnr] = CString_hlp.Left(CString_hlp.Find(Trennzeichen,0)); //in CString_hlp wird nach dem trennzeichen gesucht und der linke teil des //strings (bis zum trennzeichen auf das neue Array geschrieben, danach wird //der linke teil + dem trennzeichen aus dem original string gelöscht, so dass //der nächste auszulesende wert im original string an vorderester //stelle steht ... nun wird die selbe prozedur mit diesem wert vollzogen int_hlp=CString_array_neu[Spaltennr][Produktnr].GetLength(); CString_hlp.Delete(0,int_hlp+1); } }
sicherlich nicht die eleganteste variante, aber vielleicht eine der einfachsten. wirklich wichtig sind die funktionen
CString.Left(...) -> gibt den linken teil eines strings bis zu einem bestimmten string zurück
CString.Find(...) -> findet ein bestimmtes zeichen
CString.GetLength -> bestimmt die länge deines herausgezogenen wertes
CString.Delete -> löscht unter angabe der länge den eben auf ein neues array geschriebenen wert aus dem original arrayich hoffe es ist halbwegs verständlich, ansonsten nochmal nachfragen
mfg, TFTS
-
Stimmt, es "hilft" ja total einfach 'nen Code zu pasten, den man nicht versteht. Tja, jetzt wär eben Autocogito gefragt.
Bye, TGGC (Ein Jahr Helden)
-
Hi.
Also, danke TFTomSun für die Hile.Ich schildere euch jetzt lieber mein eigendliches Problem.
Ich lese ein paar Verzeichnisse aus (aber nur die Ordner + n-viele Unterordner). Im moment sind dies drei Stück. Das besondere ist, dass diese Ordner zum Teil gleichbenannte Ordner beinhalten.
Ein Beispiel wäre:
C:\xyz Verzeichnis 1\Profile\
C:\xyz Verzeichnis 1\Profile\
Diese Verzeichnisse sollen in EIN TreeView. Sodass jedes Child nur einmal im jeweiligen Parent existiert.Daher auch dieses Beispiel:
TV-Karte => Terratec => Cinergy TV Unterhaltung => Games => Port Royale 2 Winamp 5 Musik => WMP 10 Sonic Stage Programme => DVD => DVD Player Software Word Office => Excel Access
Ich wollte daher erstmal einen Baum erstellen (Arrays bringen ja in dem Falle nix), in dem auch jedes Child nur einmal in jedem Parent existiert. Daher fand ich schon den Code von Power Off recht interessant.
Nur wie kann ich diesen Baum in ein TreeView transportieren?Ich hoffe das hat euch mein Problem euch näher gebracht.
-
Genau, schreibs da rein.
Bye, TGGC (Ein Jahr Helden)
-
Hier ist ein komplettes Programm, das Du ausfuehren kannst. Vielleicht hilft Dir diese Version weiter.
Leider komm ich nicht oft dazu, das Forum hier zu lesen. Sorry!!
#include <string> #include <map> // fuer STL und RTTI Compiler-Optionen /GX /GR verwenden typedef std::string String; class Node; typedef std::map<String,Node*> NodeMap; typedef std::pair<String,Node*> NodePair; typedef NodeMap::const_iterator NodeCIter; typedef NodeMap::iterator NodeIter; class Node { // "Knoten"-Klasse public: String title; NodeMap nodemap; Node( const String& _title ); ~Node( void ); Node* findOrCreate( const String& name ); void addPath( const String& path ); void print( int indent ); }; Node::Node( const String& _title ) : title(_title) { } Node::~Node( void ) { // loescht die Knoten in "nodemap". NodeCIter iter = nodemap.begin(); while ( iter != nodemap.end() ) { Node* node = iter->second; iter++; delete node; } nodemap.clear(); } Node* Node::findOrCreate( const String& name ) { NodeCIter iter = nodemap.find( name ); if ( iter != nodemap.end() ) { // Knoten mit diesem Namen existiert bereits return iter->second; // Node*-Feld in Iterator } Node* node = new Node( name ); // neuer Knoten nodemap.insert( NodePair( name, node ) ); // einfuegen return node; } void Node::addPath( const String& path ) { // fuegt Knoten unterhalb dieses Knotens hinzu size_t pos = path.find( '\\' ); // Backslash \ suchen if ( pos == String::npos ) { // \ nicht gefunden: leeren Knoten mit Namen einfuegen. findOrCreate( path ); return; } // sonst: Pfad hat einen oder mehrere \, String leftPart = path.substr( 0U, pos ); // linker Teil (vor \) String rightPart = path.substr( pos + 1U ); // rechter Teil (nach \) Node* node = findOrCreate( leftPart ); node->addPath( rightPart ); } void Node::print( int indent ) { printf( "%-*.*s%s\n", indent, indent, "", title.c_str() ); NodeCIter iter = nodemap.begin(); while ( iter != nodemap.end() ) { Node* node = iter->second; iter++; node->print( indent+3 ); } } Node* rootNode = new Node( "(root)" ); void splitPath( const String& path ) { rootNode->addPath( path ); } void printTree( void ) { rootNode->print( 0 ); } int main( int argc, char** argv ) { splitPath( "Programme\\Unterhaltung\\TV-Karte\\Terratec\\Cinergy TV" ); splitPath( "Programme\\Unterhaltung\\Games\\Port Royale 2" ); splitPath( "Programme\\Unterhaltung\\Musik\\Winamp 5" ); splitPath( "Programme\\Unterhaltung\\Musik\\WMP 10" ); splitPath( "Programme\\Unterhaltung\\Musik\\Sonic Stage" ); splitPath( "Programme\\Unterhaltung\\DVD\\DVD Player Software" ); splitPath( "Programme\\Office\\Word" ); splitPath( "Programme\\Office\\Excel" ); splitPath( "Programme\\Office\\Access" ); printTree(); return 0; } /* AUSGABE: (root) Programme Office Access Excel Word Unterhaltung DVD DVD Player Software Games Port Royale 2 Musik Sonic Stage WMP 10 Winamp 5 TV-Karte Terratec Cinergy TV */
-
Danke PowerOff für deine Antwort.
Ich hab jetzt schon ein paar Stunden lang versucht deine Klasse zu erweitern bzw. abzuändern, sodass ich den Baum in ein CTreeCtrl bekomme (da SDI-Anwendung). Ich bekomme es aber wirklich nicht hin und bin am verzweifeln.Hättest du vielleicht noch einen Tipp oder ähnliches parat, um mir in diesem Punkt vielleicht sogar noch weiter zu helfen?