Rekursiv std::string Splitten



  • Guten Abend,

    ich sitze seit geraumer Zeit an einem Problem das mich langsam verzweifeln lässt.
    Und zwar habe ich einen Vector mit String die als identifier dienen.
    Außerdem habe ich einen ellen langen string den ich splitten will.

    Zur veranschaulichung folgendes

    std::vector<std::string> identifier;
    std::string line = "shkdabfljsdhflahbsdflöhbsadlfjvalsgjvdflakjsdföasdäa654635sdfg52df3g54sd3f4gs3d2fgs3dg"; //halt wahllos zeichen
    

    Im Vector identifier sind nach der reihe split 'regeln' gespeichert. Z.b. wäre das nullte element "äa" und das erste wäre "sd".

    Ich brauche am ende jedoch einen vector von strings die nach dem slitten übrig bleiben würden.

    Ich habe es mehr oder weniger geschafft das ich die ersten zwei stufen splitte aber das habe ich mit schleifen verwirklicht... und ich will nicht pro identifier einen schleifenkopf hin zu fügen 😕

    habt ihr ne Ahnung wie das vllt rekursiv geht?

    mfg


  • Mod

    😕 😕 😕
    Gib mal ein Beispiel an. Eingabemenge und erwartetes Ergebnis.



  • #include <iostream>
    #include <fstream>
    #include <string>
    #include <vector>
    #include <string.h>
    #include <stdlib.h>
    #include <strstream>
    #include <set>
    
    std::vector<std::string> splitString(std::string line, std::string d)
    {
    	std::size_t pos = 0;
    	std::vector<std::string> splitted;
    	while ((pos = line.find(d)) != std::string::npos) {
    		splitted.push_back(line.substr(0, pos));
    		line.erase(0, pos + d.length());
    	}
    	splitted.push_back(line.substr(0, pos));
    
    	return splitted;
    }
    
    int main() {
    	std::string line = "kjsadfhhlasdbföajsdfnäasjdfbhsdföabsdfhasödlhfähasvdäaäjkfgbakdfjgüädfjsökdgbsödbglsjfgssldfhgblshbdg";
    	std::vector<std::string> identifier;
    	identifier.push_back("ad");
    	identifier.push_back("hs");
    
    	std::vector<std::string> vecString = splitString(line, identifier[0]);
    	for each(std::string s in vecString)
    	{
    		std::vector<std::string> nestedvecString = splitString(s, identifier[1]);
    	}
    	return 0;
    }
    

    So in etwa, nur rekursiv o.O ich bekomme es einfach nicht hin v.v



  • Also beispielsweise man hat folgenden string "ghdabcdefghiajklmnbop" und man hat als identifier "a" und "b".
    Dann wäre nach dem ersten plitt folgendes:
    "ghd"
    "bcdefghi"
    "jklmnbop"

    diese wären dann also in einem vector... aber ich muss auf jedes element des vectors solange weiter das split anwenden bis entweder der string leer ist oder aber es keine identifier mehr gibt

    nach der zweiten runde säh der vector dann so aus
    "ghd"
    "cdefghi"
    "jklmn"
    "op"


  • Mod

    Ich nehme an, den entstehenden Leerstring nach dem Splitten von "bcdefghi" an der Stelle "b" hast du vergessen? Oder ist das Absicht?



  • ja du hast recht 🙂 habe ich vergessen.
    Danke 😃


  • Mod

    Ich bin nicht 100% sicher, ob ich alle deine Anforderungen erfülle, aber so oder ähnlich könnte das meines Erachtens nach aussehen:

    #include <iostream>
    #include <string>
    #include <vector>
    #include <iterator>
    
    template <typename InputIterator, typename OutputIterator>
    void splitString(std::string line, 
                     InputIterator begin,
                     InputIterator end,
                     OutputIterator out)
    {
      if (begin != end)
        {
          auto next = std::next(begin);
          std::size_t pos = 0;
          std::size_t next_pos;
          do
            {
              next_pos = line.find(*begin, pos);
              splitString(line.substr(pos, next_pos - pos), next, end, out);
              pos = next_pos + begin->length();
            }
          while (next_pos != std::string::npos);
        }
      else
        *out++ = line;
    }
    
    int main()
    {
      std::string line = "111111aba2222ab333333ab4444444abaab5555abaaba666666ab7777";
      std::vector<std::string> identifier;
      identifier.push_back("aba");
      identifier.push_back("ab");
    
      std::ostream_iterator<std::string> result(std::cout, "\n");
      splitString(line, identifier.begin(), identifier.end(), result);
    }
    

    viele edits: Mir fallen laufend Verbesserungen ein, je länger ich draufgucke :p



  • hammer eil ! danke 😃

    funktioniert super (Y)


Anmelden zum Antworten