home *** CD-ROM | disk | FTP | other *** search
/ Chip 2002 February / Chip_2002-02_cd1.bin / chplus / funktor / f24_pekny_podraz.cpp < prev    next >
C/C++ Source or Header  |  2002-01-02  |  5KB  |  141 lines

  1. //---------------------------------------------------------------------------
  2.  
  3. #include <iostream>
  4. #include <vector>
  5. #include <algorithm>
  6.  
  7. //---------------------------------------------------------------------------
  8. //  soubor:    f24_pekny_podraz.cpp
  9. //  autor:     Jaroslav Franek
  10. //  vytvoreno: 20011125
  11. //  copyright: (c) 2001 Jaroslav Franek
  12. //  umisteni:  Chip CD, rubrika Chip Plus, 02/02
  13. //  reference: Jak se na funktor vola... II. dil, Chip 02/02
  14. //  testovano v : Borland C++ Builder 5.0
  15. //
  16. //  komentar:  "pekny" podraz (viz clanek)
  17. //---------------------------------------------------------------------------
  18.  
  19. //---------------------------------------------------------------------------
  20. //
  21. //  funktor cTreti
  22. //  pri tretim volani vraci 1 (true), jinak vraci 0 (false)
  23. //
  24. //---------------------------------------------------------------------------
  25.  
  26. class cTreti
  27. {
  28. public:
  29.    cTreti() : pocet_(0) {}
  30.    bool operator ()(int)
  31.    {
  32.       return ++pocet_ == 3;
  33.    }
  34. private:
  35.    int pocet_;
  36. };
  37.  
  38. //---------------------------------------------------------------------------
  39. //
  40. //  dve konkurencni implementace metody remove_if
  41. //  komentar !! oznacuje mista, kde se vytvari kopie (kopie) predikatu
  42. //
  43. //---------------------------------------------------------------------------
  44.  
  45. // verze 1:
  46. template <class FWDITER, class PREDIKAT>
  47. FWDITER remove_if_1(FWDITER beg, FWDITER end, PREDIKAT op)
  48. {
  49.    beg = std::find_if(beg, end, op);  // !!
  50.    if ( beg == end )
  51.    {
  52.       return beg;
  53.    }
  54.    else
  55.    {
  56.       FWDITER next = beg;
  57.       return std::remove_copy_if(++next, end, beg, op); // !!
  58.    }
  59. }
  60.  
  61. // verze 2:
  62. template <class FWDITER, class PREDIKAT>
  63. FWDITER remove_if_2(FWDITER beg, FWDITER end, PREDIKAT op)
  64. {
  65.    while ( (beg != end) && !op(*beg) )
  66.    {
  67.       ++beg;
  68.    }
  69.    if ( beg == end )
  70.    {
  71.       return beg;
  72.    }
  73.    else
  74.    {
  75.       FWDITER next = beg;
  76.       return std::remove_copy_if(++next, end, beg, op);   // !!
  77.    }
  78. }
  79.  
  80. //---------------------------------------------------------------------------
  81. //
  82. //  a ted to pride...
  83. //
  84. //---------------------------------------------------------------------------
  85.  
  86. int main(int argc, char* argv[])
  87. {
  88.    // nejdrive si pripravime pole
  89.    const int N = 9;
  90.    int pole[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
  91.  
  92.    // a ted STL kontejner
  93.    std::vector<int> cisla1(pole, pole + N);   // N prvku, pole[i]
  94.    std::vector<int> cisla2(pole, pole + N);   // N prvku, pole[i]
  95.    std::vector<int> cisla3(pole, pole + N);   // N prvku, pole[i]
  96.  
  97.    // chceme vyhodit kazdy treti prvek za pomoci predikatu cKazdyTreti
  98.    // pouzijeme funkci 'remove_if', standard garantuje poradi
  99.    // 'remove_if' nezmeni pocet prvku v kontejneru, vraci ale
  100.    // iterator "one-past-end" na konec vysledneho rozsahu --
  101.    // ten pouzijeme v metode 'erase' a smazeme ten prebytecny cancour
  102.  
  103. //*******************************************************************
  104.    // remove_if, verze 1:
  105.    cisla1.erase(remove_if_1(cisla1.begin(), cisla1.end(), cTreti()), cisla1.end());
  106. //*******************************************************************
  107.  
  108. //*******************************************************************
  109.    // remove_if, verze 2:
  110.    cisla2.erase(remove_if_2(cisla2.begin(), cisla2.end(), cTreti()), cisla2.end());
  111. //*******************************************************************
  112.  
  113. //*******************************************************************
  114.    // remove_if, verze z STL, presneji z vasi implementace STL:
  115.    cisla3.erase(std::remove_if(cisla3.begin(), cisla3.end(), cTreti()), cisla3.end());
  116. //*******************************************************************
  117.  
  118.    // a ted si to vypiseme (uvidite, jak je na tom vase implementace STL...)
  119.    std::cout << "cisla  : ";
  120.    std::copy(pole, pole + N, std::ostream_iterator<int>(std::cout, "  "));
  121.    std::cout << "\n"
  122.                 "cisla1 : ";
  123.    std::copy(cisla1.begin(), cisla1.end(), std::ostream_iterator<int>(std::cout, "  "));
  124.    std::cout << "\n"
  125.                 "cisla2 : ";
  126.    std::copy(cisla2.begin(), cisla2.end(), std::ostream_iterator<int>(std::cout, "  "));
  127.    std::cout << "\n"
  128.                 "cisla3 : ";
  129.    std::copy(cisla3.begin(), cisla3.end(), std::ostream_iterator<int>(std::cout, "  "));
  130.    std::cout << std::endl;
  131.  
  132.    // Borland C++ Builder v5.0: implementace 'std::remove_if'
  133.    // odpovida verzi 'remove_if', takze vysledek neni to, co cekame
  134.  
  135.    // Microsoft Visual C++ .NET 7.0 (beta2): implementace 'std::remove_if'
  136.    // odpovida verzi
  137.  
  138.    return 0;
  139. }
  140. //---------------------------------------------------------------------------
  141.