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

  1. //---------------------------------------------------------------------------
  2.  
  3. #include <iostream>
  4. #include <vector>
  5. #include <algorithm>
  6. #include <functional>
  7. #include <numeric>           // std::accumulate
  8.  
  9. //---------------------------------------------------------------------------
  10. //  soubor:    f19_piseme_funktor.cpp
  11. //  autor:     Jaroslav Franek
  12. //  vytvoreno: 20011124
  13. //  copyright: (c) 2001 Jaroslav Franek
  14. //  umisteni:  Chip CD, rubrika Chip Plus, 02/02
  15. //  reference: Jak se na funktor vola... II. dil, Chip 02/02
  16. //  testovano v : Borland C++ Builder 5.0
  17. //                Microsoft Visual C++ .NET 7.0 (beta2)
  18. //
  19. //  komentar:  piseme vlastni funktor
  20. //---------------------------------------------------------------------------
  21.  
  22. //---------------------------------------------------------------------------
  23. //
  24. //  class cOdchylkaNeadapt
  25. //  (splnuje pozadavky Assignable, rozmyslete si sami, proc)
  26. //  neadaptabilni verze
  27. //
  28. //---------------------------------------------------------------------------
  29.  
  30. class cOdchylkaNeadapt
  31. {
  32. public:
  33.    cOdchylkaNeadapt(double odceho, int mocnina)
  34.       : od_ceho_(odceho),
  35.         mocnina_(mocnina)
  36.       {
  37.       }
  38.    double operator ()(double x);
  39. private:
  40.    double od_ceho_;
  41.    int mocnina_;   // predpokladame, ze mocnina_ > 0
  42. };
  43.  
  44. double cOdchylkaNeadapt::operator ()(double x)
  45. {
  46.    double absdiff = (x < od_ceho_) ? (od_ceho_ - x) : (x - od_ceho_);
  47.    if ( mocnina_ == 1 )
  48.    {
  49.       return absdiff;
  50.    }
  51.    else
  52.    {
  53.       double result = absdiff;
  54.       for ( int i = 1; i < mocnina_; ++i )
  55.       {
  56.          result *= absdiff;
  57.       }
  58.       return result;
  59.    }
  60. }
  61.  
  62. //---------------------------------------------------------------------------
  63. //
  64. //  class cOdchylkaAdapt
  65. //  (splnuje pozadavky Assignable, rozmyslete si sami, proc)
  66. //  adaptabilni verze
  67. //
  68. //---------------------------------------------------------------------------
  69.  
  70. class cOdchylkaAdapt
  71. {
  72. public:
  73.    typedef double argument_type;    // musi se jmenovat stejne jako ty u tridy
  74.    typedef double result_type;      // std::unary_function<double, double>
  75.                                     // tj. "kampatibilita" s STL
  76.    cOdchylkaAdapt(double odceho, int mocnina)
  77.       : od_ceho_(odceho),
  78.         mocnina_(mocnina)
  79.       {
  80.       }
  81.    double operator ()(double x);
  82. private:
  83.    double od_ceho_;
  84.    int mocnina_;   // predpokladame, ze mocnina_ > 0
  85. };
  86.  
  87. // uplne stejne jako predtim
  88. double cOdchylkaAdapt::operator ()(double x)
  89. {
  90.    double absdiff = (x < od_ceho_) ? (od_ceho_ - x) : (x - od_ceho_);
  91.    if ( mocnina_ == 1 )
  92.    {
  93.       return absdiff;
  94.    }
  95.    else
  96.    {
  97.       double result = absdiff;
  98.       for ( int i = 1; i < mocnina_; ++i )
  99.       {
  100.          result *= absdiff;
  101.       }
  102.       return result;
  103.    }
  104. }
  105.  
  106. //---------------------------------------------------------------------------
  107. //
  108. //  class cOdchylkaAdaptSTL
  109. //  (splnuje pozadavky Assignable, rozmyslete si sami, proc)
  110. //  adaptabilni verze odvozena od std::unary_function
  111. //
  112. //---------------------------------------------------------------------------
  113.  
  114. class cOdchylkaAdaptSTL : public std::unary_function<double, double>
  115. {
  116. public:
  117.    cOdchylkaAdaptSTL(double odceho, int mocnina)
  118.       : od_ceho_(odceho),
  119.         mocnina_(mocnina)
  120.       {
  121.       }
  122.    double operator ()(double x);
  123. private:
  124.    double od_ceho_;
  125.    int mocnina_;   // predpokladame, ze mocnina_ > 0
  126. };
  127.  
  128. // uplne stejne jako predtim
  129. double cOdchylkaAdaptSTL::operator ()(double x)
  130. {
  131.    double absdiff = (x < od_ceho_) ? (od_ceho_ - x) : (x - od_ceho_);
  132.    if ( mocnina_ == 1 )
  133.    {
  134.       return absdiff;
  135.    }
  136.    else
  137.    {
  138.       double result = absdiff;
  139.       for ( int i = 1; i < mocnina_; ++i )
  140.       {
  141.          result *= absdiff;
  142.       }
  143.       return result;
  144.    }
  145. }
  146.  
  147. //---------------------------------------------------------------------------
  148. //
  149. //  pomocny funktor,
  150. //  pomuze nam spocitat aritmeticky prumer bez napsani smycky
  151. //
  152. //---------------------------------------------------------------------------
  153.  
  154. class cAddDividedBySize
  155. {
  156. public:
  157.    cAddDividedBySize(double size)
  158.       : size_(size)
  159.       {
  160.       }
  161.    double operator ()(double sum, double x)
  162.       {
  163.          return (sum + x / size_);
  164.       }
  165. private:
  166.    double size_;
  167. };
  168.  
  169. //---------------------------------------------------------------------------
  170. //
  171. //  jak to funguje v praxi
  172. //
  173. //---------------------------------------------------------------------------
  174.  
  175. int main()
  176. {
  177.    // nejdrive si pripravime pole
  178.    const int N = 9;
  179.    int pole[] = { -1, -2, 3, -4, 0, -6, 0, -8, 9 };
  180.  
  181.    // a ted STL kontejner
  182.    std::vector<double> cisla(pole, pole + N);   // N prvku, pole[i]
  183.    std::vector<double> odchylky(N);             // N prvku
  184.  
  185.    // vypiseme vektor
  186.    std::cout << "cisla    : ";
  187.    std::copy(cisla.begin(), cisla.end(), std::ostream_iterator<double>(std::cout, "  "));
  188.    std::cout << "\n"
  189.                 "odchylky : ";
  190.    std::copy(odchylky.begin(), odchylky.end(), std::ostream_iterator<double>(std::cout, "  "));
  191.    std::cout << std::endl;
  192.  
  193. //*******************************************************************
  194.    // spocitame aritmeticky prumer
  195.    double aritmeticky_prumer = std::accumulate(cisla.begin(), cisla.end(),
  196.                                                0.0, cAddDividedBySize(cisla.size()));
  197. //*******************************************************************
  198.  
  199.    // vypiseme
  200.    std::cout << "aritmeticky prumer je " << aritmeticky_prumer << std::endl;
  201.  
  202.    std::cout << "neadaptivni funktor\n";
  203.  
  204. //*******************************************************************
  205.    // spocitame kvadraticke odchylky a ulozime je do vektoru 'odchylky'
  206.    // neadaptivni funktor
  207.    std::transform(cisla.begin(), cisla.end(), odchylky.begin(),
  208.                   cOdchylkaNeadapt(aritmeticky_prumer, 2));
  209. //*******************************************************************
  210.  
  211.    // vypiseme odchylky
  212.    std::cout << "odchylky : ";
  213.    std::copy(odchylky.begin(), odchylky.end(), std::ostream_iterator<double>(std::cout, "  "));
  214.    std::cout << std::endl;
  215.  
  216.    std::cout << "adaptivni funktor\n";
  217.  
  218. //*******************************************************************
  219.    // spocitame kvadraticke odchylky a ulozime je do vektoru 'odchylky'
  220.    // neadaptivni funktor
  221.    std::transform(cisla.begin(), cisla.end(), odchylky.begin(),
  222.                   cOdchylkaAdapt(aritmeticky_prumer, 2));
  223. //*******************************************************************
  224.  
  225.    // vypiseme odchylky
  226.    std::cout << "odchylky : ";
  227.    std::copy(odchylky.begin(), odchylky.end(), std::ostream_iterator<double>(std::cout, "  "));
  228.    std::cout << std::endl;
  229.  
  230.    std::cout << "adaptivni funktor odvozeny od unary_function\n";
  231.  
  232. //*******************************************************************
  233.    // spocitame kvadraticke odchylky a ulozime je do vektoru 'odchylky'
  234.    // neadaptivni funktor
  235.    std::transform(cisla.begin(), cisla.end(), odchylky.begin(),
  236.                   cOdchylkaAdaptSTL(aritmeticky_prumer, 2));
  237. //*******************************************************************
  238.  
  239.    // vypiseme odchylky
  240.    std::cout << "odchylky : ";
  241.    std::copy(odchylky.begin(), odchylky.end(), std::ostream_iterator<double>(std::cout, "  "));
  242.    std::cout << std::endl;
  243.  
  244.    // vsechny tri radky by mely byt stejne
  245.    // o spravnosti vysledku se jiste dokazete presvedcit sami
  246.  
  247.    return 0;
  248. }
  249. //---------------------------------------------------------------------------
  250.  
  251.