Blog správneho IŤáka.
C++: Elegantný výpis iterovateľného
Po dlhšom čase opäť prichádzam s malým, ale užitočným kusom kódu, tentokrát v C++.
Tí, čo programujú v C++ iste už použili dvojicu copy a ostream_iterator z STL, kombináciou ktorých jednoducho dokážeme vypísať všetko, čo sa dá prejsť iterátorom.
Tento spôsob ale prináša jednu nevýhodu – oddeľovač sa vypíše aj po poslednom prvku, čo je estetická chyba, ktorá nám môže vadiť. Čítajte ďalej.
Napríklad:
int a[] = {1,2,3,4,5};
vector<int> b(a, a+5);
copy(b.begin(), b.end(), ostream_iterator<int>(cout, ","));
cout << endl;
Vypíše:
1,2,3,4,5,
Riešenie
Pre tých, ktorým formát výstupu nie je ľahostajný, som pripravil jednoduchú funkciu.
template<class T>
void print_range(T begin, T end, string delimiter = ",", ostream& os = cout)
{
T it = begin;
while(it != end)
{
cout << *it;
if(++it != end)
os << delimiter;
}
}
Funkcia nám jednoducho prejde iterátorom (parameter šablóny T) po nejakých dátach, vypíše ich a okrem posledného prvku za každým dá oddeľovač.
Príklad použitia:
int a[] = {1,2,3,4,5};
vector<int> b(a, a+5);
print_range(b.begin(), b.end());
cout << endl;
Vypíše:
1,2,3,4,5
Všimnime si, že kompilátor nám implicitne doplní parameter šablóny, a týmpádom sa nemusíme starať v podstate o nič :).
| Vytisknout | Tento příspěvek napsal Tomáš Srna, 10. Apríl 2010 v 09:41 do rubriky C++, Programovanie. Můžete sledovat komentáře na tento článek pomocí RSS 2.0. Můžete taktéž zanechat komentář nebo odkázat z Vašeho vlastního webu. |
1 rok zpět
Neslo by to este optimalizovat? Napriklad preco kontrolovat podmienku oddelovaca v kazdej iteracii (riadok c. 06). Nedalo by sa to nahadzat do nejakeho bufferu, a na konci umazat posledny delimiter?
1 rok zpět
Dajme tomu, ze vypisujeme milion prvkov, z ktorych kazdy ma aspon 100 znakov. To je 95 MB pamate pre buffer. A to este neratam, ze ak by sa nebodaj kopiroval dalsi string – bez posledneho oddelovaca, bolo by to dvakrat tolko. A to len kvoli tomu, ze chceme odmazat posledny delimiter.
Oproti tomu volanie metody operator!= na objekte iteratora vacsinou len porovnava pointer vo vnutri struktury iteratora, co sa da prezit casovo aj milionkrat, pretoze tato operacia je konstantna.