Doppelte Einträge aus Textdateienöschen



  • Hallo,

    es geht darum das ich eine Textdatei habe mit einer Grösse von über 70000 Zeilen
    In jeder Zeile stehen Daten ua auch eine Nummer. Diese Nummer kommt einige Male doppelt vor. Nun brauch ich eine Absolut performante C++ Funktion welceh die Datei öffnet, nach doppelten Einträgen sucht und diese entfernt bis auf einen (es können auch dreifach, mehrfach Einträge sein). Was wäre da eine schnelle gute Lösung oder hat evt. jemand sogar ein Beispiel?

    Danke im voraus!
    MfG
    Meddten



  • Eine Möglichkeit mit Verwendung der STL ...

    #include <list>
    #include <fstream>
    #include <iterator>
    #include <iostream>
    
    using namespace std;
    
    int main()
    {
      /**
       * Container für die Speicherung der Werte
      */
      list<int> v;
    
      /**
       * Werte via Streamiterator auf Filestream aus der Datei (test.txt)
       * einlesen
      */
      ifstream fs("test.txt");
      if (!fs)
        return EXIT_FAILURE;
    
      istream_iterator<int> io(fs);
      istream_iterator<int> eos;
    
      copy(io, eos, back_inserter(v));
    
      /**
       * Container sortieren und Werte auf der Standardausgabe
       * ausgeben. Dabei mehrfach auftretende Einträge entfernen
      */
      v.sort();
      unique_copy(v.begin(), v.end()
    	      , ostream_iterator<int>(cout, "\n"));
    }
    


  • Danke!

    Ist ja schoen und gut

    aber ich brauch die eintraeg als Text also hab ich int auf char geaendert

    Jetzt geht ncihts mehr nur Hieroglyphen hab ich im output

    Hab dann das sort weggenommen und die Hieroglyphen waren weg, aber leider die doppelten Eintraege immer noch da? Trotz unique_copy



  • ...hier stand mist...



  • @Meddten
    Wenn ich dich richtig verstehe, besteht eine Zeile aus einer Nummer und anderen Daten (Text?). Wenn eine Nummer doppelt vorkommt, ist der Text der beiden identischen Nummern trotzdem unterschiedlich?

    Gib bitte mal ein paar Beispielzeilen der Datei her, damit wir dir helfen können.

    MfG

    GPC



  • Kleiner Auszug aus einer der besagten Textdateien.

    PS 446A9445B3B20B3CE1000000AC1002A6 20060518 022707 S ->Dokument PS / 446A9445B3B20B3CE1000000AC1002A6 nicht in Verknüpfungstabellen TOA0x enthalten!
    PS 446A9469B3B20B3CE1000000AC1002A6 20060518 022813 S ->Dokument PS / 446A9469B3B20B3CE1000000AC1002A6 nicht in Verknüpfungstabellen TOA0x enthalten!
    PS 446A94A6B3B20B3CE1000000AC1002A6 20060518 022803 S ->Dokument PS / 446A94A6B3B20B3CE1000000AC1002A6 nicht in Verknüpfungstabellen TOA0x enthalten!
    PS 446A9513B3B20B3CE1000000AC1002A6 20060518 022810 S ->Dokument PS / 446A9513B3B20B3CE1000000AC1002A6 nicht in Verknüpfungstabellen TOA0x enthalten!
    PS 446A9525B3B20B3CE1000000AC1002A6 20060518 022748 S ->Dokument PS / 446A9525B3B20B3CE1000000AC1002A6 nicht in Verknüpfungstabellen TOA0x enthalten!
    PS 446B2E0F274800EEE1000000AC1002A6 20060518 021832 S ->Dokument PS / 446B2E0F274800EEE1000000AC1002A6 nicht in Verknüpfungstabellen TOA0x enthalten!
    PS 446B440725F800ECE1000000AC1002A6 20060518 021630 S ->Dokument PS / 446B440725F800ECE1000000AC1002A6 nicht in Verknüpfungstabellen TOA0x enthalten!
    PS 446B44C825F800ECE1000000AC1002A6 20060518 021848 S ->Dokument PS / 446B44C825F800ECE1000000AC1002A6 nicht in Verknüpfungstabellen TOA0x enthalten!
    PS 446B44F825F800ECE1000000AC1002A6 20060518 022056 S ->Dokument PS / 446B44F825F800ECE1000000AC1002A6 nicht in Verknüpfungstabellen TOA0x enthalten!
    PS 446B451325F800ECE1000000AC1002A6 20060518 022345 S ->Dokument PS / 446B451325F800ECE1000000AC1002A6 nicht in Verknüpfungstabellen TOA0x enthalten!
    PS 446B457325F800ECE1000000AC1002A6 20060518 021948 S ->Dokument PS / 446B457325F800ECE1000000AC1002A6 nicht in Verknüpfungstabellen TOA0x enthalten!
    PS 446B458F25F800ECE1000000AC1002A6 20060518 022816 S ->Dokument PS / 446B458F25F800ECE1000000AC1002A6 nicht in Verknüpfungstabellen TOA0x enthalten!
    PS 446B459D25F800ECE1000000AC1002A6 20060518 022039 S ->Dokument PS / 446B459D25F800ECE1000000AC1002A6 nicht in Verknüpfungstabellen TOA0x enthalten!
    PS 446B463325F800ECE1000000AC1002A6 20060518 022324 S ->Dokument PS / 446B463325F800ECE1000000AC1002A6 nicht in Verknüpfungstabellen TOA0x enthalten!
    PS 446B47D525F800ECE1000000AC1002A6 20060518 022425 S ->Dokument PS / 446B47D525F800ECE1000000AC1002A6 nicht in Verknüpfungstabellen TOA0x enthalten!
    PS 446BE021AFF000E2E1000000AC1002A6 20060518 021943 S ->Dokument PS / 446BE021AFF000E2E1000000AC1002A6 nicht in Verknüpfungstabellen TOA0x enthalten!
    PS 446BE028AFF000E2E1000000AC1002A6 20060518 021936 S ->Dokument PS / 446BE028AFF000E2E1000000AC1002A6 nicht in Verknüpfungstabellen TOA0x enthalten!
    PS 1527D469631F4D13802C603175DF3274 20060321 113139 B ->Dokument PS / 1527D469631F4D13802C603175DF3274 nicht in Verknüpfungstabellen TOA0x enthalten!
    PS B39D8780EDCB40AB88AC8452C88CF46F 20060321 113139 B ->Dokument PS / B39D8780EDCB40AB88AC8452C88CF46F nicht in Verknüpfungstabellen TOA0x enthalten!
    PS 1527D469631F4D13802C603175DF3274 20060321 113139 B ->Dokument PS / 1527D469631F4D13802C603175DF3274 nicht in Verknüpfungstabellen TOA0x enthalten!
    PS B39D8780EDCB40AB88AC8452C88CF46F 20060321 113139 B ->Dokument PS / B39D8780EDCB40AB88AC8452C88CF46F nicht in Verknüpfungstabellen TOA0x enthalten!
    PS 1527D469631F4D13802C603175DF3274 20060321 113139 B ->Dokument PS / 1527D469631F4D13802C603175DF3274 nicht in Verknüpfungstabellen TOA0x enthalten!
    PS B39D8780EDCB40AB88AC8452C88CF46F 20060321 113139 B ->Dokument PS / B39D8780EDCB40AB88AC8452C88CF46F nicht in Verknüpfungstabellen TOA0x enthalten!
    PS 03D1B0B475DD4F9FBF76766841951CB7 20060322 103653 B ->Dokument PS / 03D1B0B475DD4F9FBF76766841951CB7 nicht in Verknüpfungstabellen TOA0x enthalten!

    Der erste Teil jeder Zeile (PS 446A9445B3B20B3CE1000000AC1002A6 20060518)

    kann und kommt abundzu mehrmals vor manchmal nicht

    bei PS B39D8780EDCB40AB88AC8452C88CF46F 20060321 ist dies der Fall

    Ich will nun alle Eintraege die doppelt sind (z.B PS B39D8780EDCB40AB88AC8452C88CF46F 20060321 bis auf einen Eintrag weghaben)

    Sortieren ist unwichtig



  • Ok, du machst das so: Du liest Zeilenweise ein (mittels getline und string), dabei splittest du die Zeile an der besagten Stelle in zwei Teile (such am Besten nach dem dritten Leerzeichen, um die Abgrenzung herauszufinden).
    Den ersten Teilstring (z.B. PS B39D8780EDCB40AB88AC8452C88CF46F 20060321) verwendest du als Schlüssel für eine std::map, der zweite Teil ist der Wert zum Schlüssel (z.B. 113139 B ->Dokument PS / B39D8780EDCB40AB88AC8452C88CF46F nicht in Verknüpfungstabellen TOA0x enthalten!).

    Die map lässt nur eindeutige Schlüssel zu und sortiert von Haus aus.

    Bist du fertig mit Einlesen/Einfügen, schreibst du die map in eine Datei rein. Dann bist fertig.

    MfG

    GPC



  • Bin nohc nicht so der Pro. hast du Codebeispiele zum anschauen wie man ca. vorgeht. Es muss nicht die Loesung des Probs sein (will noch was lernen by doing) aber so die Verwendung von map etc.



  • Also auf www.cppreference.com findest du die Dokumentation zur STL.

    Ein Beispiel zu map:

    #include <map>
    
    map<int, double> m;  //Schlüssel ist ein int, der dazugehörige Wert ein double
    
    m.insert(make_pair(5 , 2.5));
    m.insert(make_pair(1 , 0.5));
    m.insert(make_pair(8 , 4.0));
    
    //So, der Schlüssel 5 existiert bereits in der map, daher wird das nicht eingefügt. 
    m.insert(make_pair(5 , 3.5));
    

    Über einen iterator kannst du das relativ einfach in den ofstream schreiben.

    MfG

    GPC



  • Wenn du mir jetzt noch sagst wie ich das in einen Iterator bringe und in ein File dann bin ich happy.



  • Meddten schrieb:

    Wenn du mir jetzt noch sagst wie ich das in einen Iterator bringe und in ein File dann bin ich happy.

    na dann:

    #include <iostream>
    #include <fstream>
    #include <map>
    
    using namespace std;
    
    typedef map<int, double> Cont;
    
    int main() {
      Cont m;  //Schlüssel ist ein int, der dazugehörige Wert ein double
    
      m.insert(make_pair(5 , 2.5));
      m.insert(make_pair(1 , 0.5));
      m.insert(make_pair(8 , 4.0));
    
      //So, der Schlüssel 5 existiert bereits in der map, daher wird das nicht eingefügt.
      m.insert(make_pair(5 , 3.5));
    
      ofstream ofs("output.txt");
      if (!ofs) 
        return 1;
    
      Cont::iterator it = m.begin();
      for ( ; it != m.end(); ++it)
        ofs<<it->first<<' '<<it->second<<'\n';
    
      ofs.close();
      return 0;
    };
    

    MfG

    GPC



  • Ok thx ein Prob gibts beim einlesen der quelldatei

    ifstream fs("d:/test.txt"); 
    	if (!fs) 
    		cout<<"failed"; return EXIT_FAILURE;
    
    	string testline;
    
    	getline(fs, testline, ' ');
    
    	cout<<testline<<endl;
    

    Obiges ist nur zum Test

    failed bekomm ich nicht oeffnen klappt also

    im test.txt steht in der ersten Zeile auch etwas

    PS 54654646546 usw

    das cout gibt nichts aus muesste aber doch theoretisch PS ausgeben oder?



  • Meddten schrieb:

    ifstream fs("d:/test.txt"); 
    	if (!fs) 
    		cout<<"failed"; return EXIT_FAILURE;
    

    Wenn man den Code mal ausschreibt und sauber formatiert, kommt das raus:

    ifstream fs("d:/test.txt");
    if (!fs)
      cout<<"failed";  //hier solltest du cerr statt cout verwenden
    return EXIT_FAILURE;
    

    Blub. Setz Klammern für die if-Anweisung. Momentan führt er die return Anweisung nämlich immer aus, egal ob fs in nem Fehlerzustand ist, oder nicht.

    MfG

    GPC



  • Ah jo lol thx

    Sorry noch eine Frage (Tut mir Leid ich lerne noch)

    geline gibt ja immer die letzte Zeile aus

    Wie kann ich dioe erste Zeile lesen, dann zur nächsten springen usw. so damit ich jede Zeile vorne und hinten beschneiden kann um sie in die map einzutragen?



  • Meddten schrieb:

    Ah jo lol thx

    Sorry noch eine Frage (Tut mir Leid ich lerne noch)

    geline gibt ja immer die letzte Zeile aus

    Wie kann ich dioe erste Zeile lesen, dann zur nächsten springen usw. so damit ich jede Zeile vorne und hinten beschneiden kann um sie in die map einzutragen?

    Immer eine Zeile komplett einlesen? Siehe hier:

    ifstream ifs("test.txt");
    if (!ifs)
      return 1;
    
    while (ifs.good()) {
      string s;
      getline(ifs, s);
      //Evtl. aufsplitten und...
      //in irgendeinen container einfügen
    };
    
    ifs.close();
    

    MfG

    GPC


Anmelden zum Antworten