home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 2002 February
/
Chip_2002-02_cd1.bin
/
chplus
/
funktor
/
f24_pekny_podraz.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
2002-01-02
|
5KB
|
141 lines
//---------------------------------------------------------------------------
#include <iostream>
#include <vector>
#include <algorithm>
//---------------------------------------------------------------------------
// soubor: f24_pekny_podraz.cpp
// autor: Jaroslav Franek
// vytvoreno: 20011125
// copyright: (c) 2001 Jaroslav Franek
// umisteni: Chip CD, rubrika Chip Plus, 02/02
// reference: Jak se na funktor vola... II. dil, Chip 02/02
// testovano v : Borland C++ Builder 5.0
//
// komentar: "pekny" podraz (viz clanek)
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//
// funktor cTreti
// pri tretim volani vraci 1 (true), jinak vraci 0 (false)
//
//---------------------------------------------------------------------------
class cTreti
{
public:
cTreti() : pocet_(0) {}
bool operator ()(int)
{
return ++pocet_ == 3;
}
private:
int pocet_;
};
//---------------------------------------------------------------------------
//
// dve konkurencni implementace metody remove_if
// komentar !! oznacuje mista, kde se vytvari kopie (kopie) predikatu
//
//---------------------------------------------------------------------------
// verze 1:
template <class FWDITER, class PREDIKAT>
FWDITER remove_if_1(FWDITER beg, FWDITER end, PREDIKAT op)
{
beg = std::find_if(beg, end, op); // !!
if ( beg == end )
{
return beg;
}
else
{
FWDITER next = beg;
return std::remove_copy_if(++next, end, beg, op); // !!
}
}
// verze 2:
template <class FWDITER, class PREDIKAT>
FWDITER remove_if_2(FWDITER beg, FWDITER end, PREDIKAT op)
{
while ( (beg != end) && !op(*beg) )
{
++beg;
}
if ( beg == end )
{
return beg;
}
else
{
FWDITER next = beg;
return std::remove_copy_if(++next, end, beg, op); // !!
}
}
//---------------------------------------------------------------------------
//
// a ted to pride...
//
//---------------------------------------------------------------------------
int main(int argc, char* argv[])
{
// nejdrive si pripravime pole
const int N = 9;
int pole[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
// a ted STL kontejner
std::vector<int> cisla1(pole, pole + N); // N prvku, pole[i]
std::vector<int> cisla2(pole, pole + N); // N prvku, pole[i]
std::vector<int> cisla3(pole, pole + N); // N prvku, pole[i]
// chceme vyhodit kazdy treti prvek za pomoci predikatu cKazdyTreti
// pouzijeme funkci 'remove_if', standard garantuje poradi
// 'remove_if' nezmeni pocet prvku v kontejneru, vraci ale
// iterator "one-past-end" na konec vysledneho rozsahu --
// ten pouzijeme v metode 'erase' a smazeme ten prebytecny cancour
//*******************************************************************
// remove_if, verze 1:
cisla1.erase(remove_if_1(cisla1.begin(), cisla1.end(), cTreti()), cisla1.end());
//*******************************************************************
//*******************************************************************
// remove_if, verze 2:
cisla2.erase(remove_if_2(cisla2.begin(), cisla2.end(), cTreti()), cisla2.end());
//*******************************************************************
//*******************************************************************
// remove_if, verze z STL, presneji z vasi implementace STL:
cisla3.erase(std::remove_if(cisla3.begin(), cisla3.end(), cTreti()), cisla3.end());
//*******************************************************************
// a ted si to vypiseme (uvidite, jak je na tom vase implementace STL...)
std::cout << "cisla : ";
std::copy(pole, pole + N, std::ostream_iterator<int>(std::cout, " "));
std::cout << "\n"
"cisla1 : ";
std::copy(cisla1.begin(), cisla1.end(), std::ostream_iterator<int>(std::cout, " "));
std::cout << "\n"
"cisla2 : ";
std::copy(cisla2.begin(), cisla2.end(), std::ostream_iterator<int>(std::cout, " "));
std::cout << "\n"
"cisla3 : ";
std::copy(cisla3.begin(), cisla3.end(), std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
// Borland C++ Builder v5.0: implementace 'std::remove_if'
// odpovida verzi 'remove_if', takze vysledek neni to, co cekame
// Microsoft Visual C++ .NET 7.0 (beta2): implementace 'std::remove_if'
// odpovida verzi
return 0;
}
//---------------------------------------------------------------------------