wojownik266 Temat założony przez niniejszego użytkownika |
[C++] Usuwanie duplikatów z pliku tekstowego » 2013-04-13 10:36:13 Witam. Napisałem sobie taki program do usuwania duplikatów z pliku tekstowego, którego kod zamieszczam poniżej. Program w 95% działa zgodnie z moimi oczekiwaniami. Problemem jest to że gdy w pliku mam np: taki tekst "ala,ala,ala,ala" to algorytm usuwa tylko dwa pierwsze powtórzenia pozostawiając resztę bez zmian. Czy ktoś mógłby podpowiedzieć co zrobić aby program pozostawiał tylko jeno słowo a resztę usuwał? #include <fstream> #include <iostream> #include <vector> #include <algorithm> using namespace std;
void usun_znak( vector < string > * slowa, string filtr ) { vector < string >::iterator iter = slowa->begin(); vector < string >::iterator iter_koniec = slowa->end(); if( !filtr.size() ) filtr.insert( 0, "\".,:;!?)(\\/" ); while( iter != iter_koniec ) { string::size_type poz = 0; while(( poz =( * iter ).find_first_of( filtr, poz ) ) != string::npos ) ( * iter ).erase( poz, 1 ); iter++; } } int main() { string nazwaPliku, efilter; cout << "Podaj nazwe pliku do otwarcia: "; cin >> nazwaPliku; ifstream plikwe( nazwaPliku.c_str() ); if( !plikwe ) { cerr << "Blad otwarcia pliku\n"; return - 1; } string tmp; vector < string > tekst; while( plikwe >> tmp ) { tekst.push_back( tmp ); } cout << "Przed usunieciem duplikatow\n"; for( int i = 0; i < tekst.size(); ++i ) { cout << tekst[ i ] << "\n"; } sort( tekst.begin(), tekst.end() ); tekst.erase( unique( tekst.begin(), tekst.end() ), tekst.end() ); usun_znak( & tekst, efilter ); cout << "Po usunieciu duplikatow\n"; for( int i = 0; i < tekst.size(); ++i ) { cout << tekst[ i ] << "\n"; } cout << "Podaj nazwe pliku do ktorego zapisac\n"; cin >> nazwaPliku; ofstream plikwy( nazwaPliku.c_str() ); for( int i = 0; i < tekst.size(); ++i ) { plikwy << tekst[ i ] << "\n"; } cin.get(); return 0; }
|
|
DejaVu |
» 2013-04-13 12:33:34 Jeżeli dane sortujesz to wystarczy, że je wrzucisz do std::set<std::string>, a następnie wypiszesz zawartość tego kontenera. Duplikaty same zostaną usunięte. |
|
wojownik266 Temat założony przez niniejszego użytkownika |
» 2013-04-13 17:53:36 Wszystko jest tak jak mówisz tylko mam mały problem z tą funkcją: #include <iostream> #include <vector> #include <set> #include <algorithm> #include <fstream> using namespace std;
void usun_znak( set < string > * slowa, string filtr ) { set < string >::iterator iter = slowa->begin(); set < string >::iterator iter_koniec = slowa->end(); if( !filtr.size() ) filtr.insert( 0, "\".,:;!?)(\\/" ); while( iter != iter_koniec ) { string::size_type poz = 0; while(( poz = iter->find_first_of( filtr, poz ) ) != string::npos ) iter->erase(( slowa->begin(), slowa->end() ), poz ); iter++; } }
int main() { set < string > call; set < string >::iterator it; string efilter, plik; ifstream in( "plik.txt" ); ofstream out( "words.txt" ); while( in >> plik ) call.insert( plik ); usun_znak( & call, efilter ); for( it = call.begin(); it != call.end(); ++it ) { cout <<* it << endl; out <<* it << endl; } cin.get(); return 0; }
Jak sprawić aby usuwała znaki interpunkcyjne? |
|
DejaVu |
» 2013-04-13 19:42:17 To nie rola kontenera std::set. std::set przechowuje unikatowe wartości. Ty decydujesz 'czym' ten kontener 'karmisz'. |
|
wojownik266 Temat założony przez niniejszego użytkownika |
» 2013-04-13 20:30:19 Trochę tak pokracznie się wyraziłem. Chodzi mi o to że przy probie kompilacji powyższego programu otrzymuję komunikat, jak niżej z którym nie mogę sobie poradzić!? D:\CodeBlock\CodeBlock_Projekty\Usuwanie znakow przestankowych z tekstu\usowanie_znakow_przestankowych.cpp|17|error: passing 'const std::basic_string<char, std::char_traits<char>, std::allocator<char> >' as 'this' argument of 'std::basic_string<_CharT, _Traits, _Alloc>& std::basic_string<_CharT, _Traits, _Alloc>::erase(typename _Alloc::rebind<_CharT>::other::size_type, typename _Alloc::rebind<_CharT>::other::size_type) [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>]' discards qualifiers|
|
|
pekfos |
» 2013-04-13 21:16:00 z którym nie mogę sobie poradzić!? |
Też się dziwię, że nie możesz sobie poradzić. Nie można modyfikować elementów std::set. Chyba nawet nie próbowałeś zrozumieć komunikatu błędu. passing 'const [..] as 'this' argument of [..] erase [..] discards qualifiers|
|
|
wojownik266 Temat założony przez niniejszego użytkownika |
» 2013-04-14 11:27:49 No teraz to już wszystko jasne i proste. Gdyby nie Twoja podpowiedź to w dalszym ciągu wyważałbym otwarte drzwi. Zmodyfikowana i poprawiona wersja programu do usuwania znaków przestankowych i powtarzających się słów, ma się tak jak poniżej (gotowiec). Na zakończenie prosiłbym o rzuceniem okiem na ten program i powiedzenie mi czy jest dobrze napisany a jak nie to dlaczego i co by można jeszcze usprawnić? #include <iostream> #include <set> #include <vector> #include <string> #include <fstream> #include <algorithm> using namespace std;
void usun_znak( vector < string > * slowa, string filtr ) { vector < string >::iterator iter = slowa->begin(); vector < string >::iterator iter_koniec = slowa->end(); if( !filtr.size() ) filtr.insert( 0, "\".,:;!?0123456789)(\\/" ); while( iter != iter_koniec ) { string::size_type poz = 0; while(( poz =( * iter ).find_first_of( filtr, poz ) ) != string::npos ) ( * iter ).erase( poz, 1 ); iter++; } } int main() { string tmp, plik, efilter; ifstream in( "plik.txt" ); ofstream out( "word.txt" ); vector < string > zn; set < string > call; set < string >::iterator it; while( in >> tmp ) { zn.push_back( tmp ); usun_znak( & zn, efilter ); call.insert( zn.begin(), zn.end() ); } for( it = call.begin(); it != call.end(); ++it ) { cout <<* it << endl; out <<* it << endl; } cin.get(); return 0; }
|
|
« 1 » |