home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 2002 February
/
Chip_2002-02_cd1.bin
/
chplus
/
funktor
/
f19_piseme_funktor.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
2002-01-02
|
8KB
|
251 lines
//---------------------------------------------------------------------------
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
#include <numeric> // std::accumulate
//---------------------------------------------------------------------------
// soubor: f19_piseme_funktor.cpp
// autor: Jaroslav Franek
// vytvoreno: 20011124
// 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
// Microsoft Visual C++ .NET 7.0 (beta2)
//
// komentar: piseme vlastni funktor
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//
// class cOdchylkaNeadapt
// (splnuje pozadavky Assignable, rozmyslete si sami, proc)
// neadaptabilni verze
//
//---------------------------------------------------------------------------
class cOdchylkaNeadapt
{
public:
cOdchylkaNeadapt(double odceho, int mocnina)
: od_ceho_(odceho),
mocnina_(mocnina)
{
}
double operator ()(double x);
private:
double od_ceho_;
int mocnina_; // predpokladame, ze mocnina_ > 0
};
double cOdchylkaNeadapt::operator ()(double x)
{
double absdiff = (x < od_ceho_) ? (od_ceho_ - x) : (x - od_ceho_);
if ( mocnina_ == 1 )
{
return absdiff;
}
else
{
double result = absdiff;
for ( int i = 1; i < mocnina_; ++i )
{
result *= absdiff;
}
return result;
}
}
//---------------------------------------------------------------------------
//
// class cOdchylkaAdapt
// (splnuje pozadavky Assignable, rozmyslete si sami, proc)
// adaptabilni verze
//
//---------------------------------------------------------------------------
class cOdchylkaAdapt
{
public:
typedef double argument_type; // musi se jmenovat stejne jako ty u tridy
typedef double result_type; // std::unary_function<double, double>
// tj. "kampatibilita" s STL
cOdchylkaAdapt(double odceho, int mocnina)
: od_ceho_(odceho),
mocnina_(mocnina)
{
}
double operator ()(double x);
private:
double od_ceho_;
int mocnina_; // predpokladame, ze mocnina_ > 0
};
// uplne stejne jako predtim
double cOdchylkaAdapt::operator ()(double x)
{
double absdiff = (x < od_ceho_) ? (od_ceho_ - x) : (x - od_ceho_);
if ( mocnina_ == 1 )
{
return absdiff;
}
else
{
double result = absdiff;
for ( int i = 1; i < mocnina_; ++i )
{
result *= absdiff;
}
return result;
}
}
//---------------------------------------------------------------------------
//
// class cOdchylkaAdaptSTL
// (splnuje pozadavky Assignable, rozmyslete si sami, proc)
// adaptabilni verze odvozena od std::unary_function
//
//---------------------------------------------------------------------------
class cOdchylkaAdaptSTL : public std::unary_function<double, double>
{
public:
cOdchylkaAdaptSTL(double odceho, int mocnina)
: od_ceho_(odceho),
mocnina_(mocnina)
{
}
double operator ()(double x);
private:
double od_ceho_;
int mocnina_; // predpokladame, ze mocnina_ > 0
};
// uplne stejne jako predtim
double cOdchylkaAdaptSTL::operator ()(double x)
{
double absdiff = (x < od_ceho_) ? (od_ceho_ - x) : (x - od_ceho_);
if ( mocnina_ == 1 )
{
return absdiff;
}
else
{
double result = absdiff;
for ( int i = 1; i < mocnina_; ++i )
{
result *= absdiff;
}
return result;
}
}
//---------------------------------------------------------------------------
//
// pomocny funktor,
// pomuze nam spocitat aritmeticky prumer bez napsani smycky
//
//---------------------------------------------------------------------------
class cAddDividedBySize
{
public:
cAddDividedBySize(double size)
: size_(size)
{
}
double operator ()(double sum, double x)
{
return (sum + x / size_);
}
private:
double size_;
};
//---------------------------------------------------------------------------
//
// jak to funguje v praxi
//
//---------------------------------------------------------------------------
int main()
{
// nejdrive si pripravime pole
const int N = 9;
int pole[] = { -1, -2, 3, -4, 0, -6, 0, -8, 9 };
// a ted STL kontejner
std::vector<double> cisla(pole, pole + N); // N prvku, pole[i]
std::vector<double> odchylky(N); // N prvku
// vypiseme vektor
std::cout << "cisla : ";
std::copy(cisla.begin(), cisla.end(), std::ostream_iterator<double>(std::cout, " "));
std::cout << "\n"
"odchylky : ";
std::copy(odchylky.begin(), odchylky.end(), std::ostream_iterator<double>(std::cout, " "));
std::cout << std::endl;
//*******************************************************************
// spocitame aritmeticky prumer
double aritmeticky_prumer = std::accumulate(cisla.begin(), cisla.end(),
0.0, cAddDividedBySize(cisla.size()));
//*******************************************************************
// vypiseme
std::cout << "aritmeticky prumer je " << aritmeticky_prumer << std::endl;
std::cout << "neadaptivni funktor\n";
//*******************************************************************
// spocitame kvadraticke odchylky a ulozime je do vektoru 'odchylky'
// neadaptivni funktor
std::transform(cisla.begin(), cisla.end(), odchylky.begin(),
cOdchylkaNeadapt(aritmeticky_prumer, 2));
//*******************************************************************
// vypiseme odchylky
std::cout << "odchylky : ";
std::copy(odchylky.begin(), odchylky.end(), std::ostream_iterator<double>(std::cout, " "));
std::cout << std::endl;
std::cout << "adaptivni funktor\n";
//*******************************************************************
// spocitame kvadraticke odchylky a ulozime je do vektoru 'odchylky'
// neadaptivni funktor
std::transform(cisla.begin(), cisla.end(), odchylky.begin(),
cOdchylkaAdapt(aritmeticky_prumer, 2));
//*******************************************************************
// vypiseme odchylky
std::cout << "odchylky : ";
std::copy(odchylky.begin(), odchylky.end(), std::ostream_iterator<double>(std::cout, " "));
std::cout << std::endl;
std::cout << "adaptivni funktor odvozeny od unary_function\n";
//*******************************************************************
// spocitame kvadraticke odchylky a ulozime je do vektoru 'odchylky'
// neadaptivni funktor
std::transform(cisla.begin(), cisla.end(), odchylky.begin(),
cOdchylkaAdaptSTL(aritmeticky_prumer, 2));
//*******************************************************************
// vypiseme odchylky
std::cout << "odchylky : ";
std::copy(odchylky.begin(), odchylky.end(), std::ostream_iterator<double>(std::cout, " "));
std::cout << std::endl;
// vsechny tri radky by mely byt stejne
// o spravnosti vysledku se jiste dokazete presvedcit sami
return 0;
}
//---------------------------------------------------------------------------