Multimap


  • Mod

    .filmor schrieb:

    s.c_str () sollte funktionieren, aber warum nimmst du nicht einfach generell std::string?
    Und solche großen Sachen wie eine Map sollten eigentlich nicht als Referenz übergeben werden.

    stimmt, aber danach darfst du m2 nicht mehr anfassen. denn s wird zerstört und nimmt den speicher, auf den s.c_str zeigte, gleich mit.

    also:
    multimapstd::string,int
    oder evtl bequemer ist:
    map<std::string,std::vector<int> >



  • Ich habe das soweit umgeschrieben. Danke für Eure Hilfe. Nun habe aber noch ein Problem. Ich erhöhe die tmp Variable ja bei jedem Einlesen um 1. Die tmp Variable spiegelt ja die Zeilennummer wieder. Da heisst er soll diese nur erhöhen wenn er eine Zeile weiter geht und nicht bei jedem String.

    #include <iostream>
    #include <stdlib.h>
    #include <map>
    #include <fstream>
    #include <string>
    
    using namespace std;
    
    int main()
    {
        typedef multimap <std::string, int> Mum;
        typedef Mum::iterator Iterator;
        Mum m;
        Iterator j;   
        int line = 0;
        ifstream fin("uebung10.txt");  
        int tmp = 0; 
        while (!fin.eof())
        {
              std::string s; 
              fin >> s;           
              m.insert(pair<std::string, int> (s,++tmp));
        }
        for (j = m.begin(); j != m.end(); ++j)
                cout << " [" << (*j).first << ", " << (*j).second << "]" << endl;
        system("pause");
        return 0;    
    }
    

    Außerdem ignoriert noch nicht das Komma und den Punkt.

    Die Ausgabe ist bei meinem Programm.

    [, 12]
    [Alle, 1]
    [Entchen,, 3]
    [See,, 7]
    [See., 11]
    [dem, 6]
    [dem, 10]
    [in, 5]
    [in, 9]
    [mein, 2]
    [schwimmen, 4]
    [schwimmen, 8]



  • Wie wärs damit:

    std::vector<std::string> parse (const std::string& s)
    {
        std::vector<std::string> v;
    
        for (std::string::iterator j = s.begin (), i = s.begin (); i != s.end (); ++i)
        {
            if (*i == ' ' || *i == ',' || *i == '.')
            {
                if (j != i - 1)
                    v.push_back (std::string (j, i);
                j = i;
            }
        }
        return v;
    }
    
    // in der Schleife:
    
    std::string s;
    getline (fin, s);
    parse (s) // verarbeiten
    


  • Cool, danke für Deine Mühen. Gleichmal ausprobieren. 👍



  • Meintest Du das so? Da gibt es ein Kovertierungsfehler.

    #include <iostream>
    #include <stdlib.h>
    #include <map>
    #include <fstream>
    #include <string>
    #include <vector>
    
    using namespace std;
    
    std::vector<std::string> parse (const std::string& s)
    {
        std::vector<std::string> v;
    
        for (std::string::iterator j = s.begin (), i = s.begin (); i != s.end (); ++i)
        {
            if (*i == ' ' || *i == ',' || *i == '.')
            {
                if (j != i - 1)
                    v.push_back (std::string (j, i));
                j = i;
            }
        }
        return v;
    }
    
    int main()
    {
        typedef multimap <std::string, int> Mum;
        typedef Mum::iterator Iterator;
        Mum m;
        Iterator k;   
        int line = 0;
        ifstream fin("uebung10.txt");  
        int tmp = 0; 
        while (!fin.eof())
        {
              std::string s; 
              getline(fin,s);
              parse(s);       
              m.insert(pair<std::string, int> (s,++tmp));
        }
        for (k = m.begin(); k != m.end(); ++k)
                cout << " [" << (*k).first << ", " << (*k).second << "]" << endl;
        system("pause");
        return 0;    
    }
    


  • Statt

    parse (s); m.insert //blabla
    

    das hier:

    std::vector<std::string> v = parse (s);
    for (std::vector<std::string>::iterator i = v.begin (); i != v.end (); ++i)
        m.insert (std::make_pair (*i, tmp);
    ++tmp;
    


  • Immer noch ein Kovertierungsfehler im stl iterator. Außerdem sagt er in der parse Methode im For Schleifen Kopf "instantiated from here" Kennt der Compiler überhaupt die Variable i in der parse Methode??

    #include <iostream>
    #include <stdlib.h>
    #include <map>
    #include <fstream>
    #include <string>
    #include <vector>
    
    using namespace std;
    
    std::vector<std::string> parse (const std::string& s)
    {
        std::vector<std::string> v;
    
        for (std::string::iterator j = s.begin (), i = s.begin (); i != s.end (); ++i)
        {
            if (*i == ' ' || *i == ',' || *i == '.')
            {
                if (j != i - 1)
                    v.push_back (std::string (j, i));
                j = i;
            }
        }
        return v;
    }
    
    int main()
    {
        typedef multimap <std::string, int> Mum;
        typedef Mum::iterator Iterator;
        Mum m;
        Iterator k;   
        int line = 0;
        ifstream fin("uebung10.txt");  
        int tmp = 0; 
        while (!fin.eof())
        {
              std::string s; 
              getline(fin,s);
              std::vector<std::string> v = parse (s);
              for (std::vector<std::string>::iterator i = v.begin (); i != v.end (); ++i)
                  m.insert (std::make_pair (*i, tmp));
              ++tmp;
        }
        for (k = m.begin(); k != m.end(); ++k)
                cout << " [" << (*k).first << ", " << (*k).second << "]" << endl;
        system("pause");
        return 0;    
    }
    


  • Deine String referenz ist const. nimm einen const_iterator;

    Kurt



  • ZuK schrieb:

    Deine String referenz ist const. nimm einen const_iterator;

    Kurt

    Mann, bist du gut. Super, danke. Jetzt geht es. 😋



  • Die parse Methode macht mir noch Kopfschmerzen. Ich verstehe hier nicht wie die Strings getrennt werden. Wenn ein Punkt, Komma oder Leerzeichen kommt dann wird gefragt ob der string ungleich des strings - 1 ist. Falls ja wird die push_back Methode aufgerufen. Und was wird hier gemacht? Andersrum wenn der string gleich des string - 1 ist wird in j i gespeichert. Ich bin verwirrt. 😕

    Außerdem ist mir bei der Ausgabe der MultiMap aufgefallen, dass außer bei den ersten Wörtern der jeweiligen Zeile jeweils eine Leerzeichen am Anfang des Wortes steht. Beispiel:

    [Alle, 1] //Sieht gut aus
    [ meine, 1] // ?? Was macht dieses Leerzeichen dort?

    vector <string> parseString (string s)
                  {
                      vector <string> v;
    
                      for (string::iterator j = s.begin (), i = s.begin (); i != s.end (); ++i)
                      {
                          if (*i == ' ' || *i == ',' || *i == '.')
                          {
                             if (j != i - 1)
                                 v.push_back (string (j, i));
                             j = i;
                          }
                      }
                      return v;
                  }
    


  • Habs ein wenig umbebaut

    #include <iostream>
    #include <cstdlib>
    #include <map>
    #include <fstream>
    #include <string>
    #include <vector>
    #include <iomanip>
    
    using namespace std;
    
    bool is_separator( string::const_iterator i ) {
        static string sepchars = " \t,.!?";
        return sepchars.find(*i) != string::npos;
    }
    
    std::vector<std::string> parse (const std::string& s){
    
        std::vector<std::string> ret_vect;
    
        for (std::string::const_iterator j = s.begin (), i = s.begin (); i != s.end (); ++i) {
            if ( is_separator( i )  ) {
                if (j != i - 1) {
    	        while ( j < i && is_separator(j) ) 
                        ++j;
                    string word = std::string (j, i);
                    ret_vect.push_back ( word );
                    j = i;
                }
            }
        }
        return ret_vect;
    }
    
    int main()
    {
        typedef multimap <std::string, int> Mum;
        typedef Mum::iterator Iterator;
        Mum m;
        Iterator k;  
        int line = 0;
        ifstream fin("uebung10.txt");  
        int tmp = 0;
        while (!fin.eof()) {
            std::string s;
            getline(fin,s);
            std::vector<std::string> v = parse (s);
            for (std::vector<std::string>::iterator i = v.begin (); i != v.end (); ++i)
                m.insert (std::make_pair (*i, tmp));
            ++tmp;
        }
    
        string prev_word = "";
        for (k = m.begin(); k != m.end(); ++k) {
            if ( (*k).first != prev_word ) {
               prev_word = (*k).first;
               cout << endl << setw( 20 ) << prev_word << " found at line " << setw(4) << (*k).second + 1;
            }
            else {
               cout << ", " << (*k).second;
            }
        }
        cout << endl << endl << "xref done." << endl;
        return 0;    
    }
    

Anmelden zum Antworten