Objektum elvű alkalmazások fejlesztése Programozási tételek újrafelhasználása 1. Készítette: Gregorics Tibor
Hozzunk létre a programozási tételeket általánosan leíró kódkönyvtárat (osztály-sablon könyvtárat), amely felhasználásával a visszavezetéssel tervezett programjainkat minimális erőfeszítéssel implementálhatjuk. Egy feladat megoldása egy tevékenység objektum lesz. 1. Az objektum osztályát származtatással hozzuk létre, 2. miután annak ősosztályát a kódkönyvtárból példányosítottuk, 3. az objektumhoz pedig egy felsoroló objektumot rendelünk.
bool l = false; for (t.first();!t.end(); t.next()){ if(!cond(t.current())) continue; Value val = func(t.current()); if(l) if( opt < val ){ opt = val; optitem = t.current(); else{ l=true; opt = val; optitem = t.current(); bool l = false; for (t.first();!l &&!t.end(); t.next()){ l = cond(elem = t.current()); int db = 0; for (t.first();!t.end(); t.next()){ if( cond(t.current()) ) ++db; init(); for(t.first();!t.end() && whilecond(t.current()); t.next()){ body(t.current());
template <typename > void Procedure<>::run() { if(_enor==null) throw MISSING_ENUMERATOR; default: _enor->first() init(); for( first(); loopcond(); _enor->next()) { body(_enor->current()); felsorolt elemek típusa felsoroló objektumra mutató pointer!_enor->end() && whilecond(_enor->current()) default: true
template <typename > class Procedure { protected: Enumerator<> *_enor; felsorolt elemek típusa felsoroló objektumra mutató pointer Procedure():_enor(NULL){ felüldefiniálható metódusok virtual void init()= 0; virtual void body(const & current) = 0; virtual void first() {_enor->first(); virtual bool whilecond(const & current) const { return true; virtual bool loopcond() const { return!_enor->end()&& whilecond(_enor->current()); ősciklus public: enum Exceptions { MISSING_ENUMERATOR ; konkrét felsoroló void run(); objektum hozzáadása void addenumerator(enumerator<>* en) { _enor = en; virtual ~Procedure(){ ; procedure.hpp
template <typename > class Enumerator { public: virtual void first() = 0; virtual void next() = 0; virtual bool end() const = 0; virtual current() const = 0; virtual ~Enumerator(){ ; enumerator.hpp
Procedure -*enor Enumerator + run() : void + addenumerator() : void # init() : void # first() : void # body() : void # loopcond() : bool # whilecond() : bool +first() +next() +current() +end() : void : void : : bool ArrayEnumerator SeqInFileEnumerator - vect : array of - ind : int + first() : void + next() : void + current() : + end() : bool - f : file of - df : + first() : void + next() : void + current() : + end() : bool
template <typename > class ArrayEnumerator : public Enumerator<> { protected: std::vector<> *_vect; unsigned int _ind; public: ArrayEnumerator(std::vector<> *v):_vect(v){ ; void first() { _ind = 0; void next() { ++_ind; bool end() const { return _ind>=_vect->size(); current()const { return (*_vect)[_ind]; arrayenumerator.hpp
template <typename > class SeqInFileEnumerator : public Enumerator<>{ protected: std::ifstream _f; _df; public: enum Exceptions { OPEN_ERROR ; SeqInFileEnumerator(const std::string& str) ; _f.open(str.c_str()); if(_f.fail()) throw OPEN_ERROR; if(typeid()==typeid(char)) _f.unsetf(std::ios::skipws); ~SeqInFileEnumerator(){ _f.close(); void first() { next(); void next() { _f >> _df; bool end() const { return _f.fail(); current() const { return _df; #include <typeinfo> Az -re legyen értelmes az operator>> seqinfileenumerator.hpp
Procedure -*enor Enumerator +run() : void +addenumerator() : void # init() : void # first() : void # body() : void # loopcond() : bool # whilecond() : bool +first() +next() +current() +end() : void : void : : bool, MaxSearch, LinSearch, Summation Selection Counting
template <typename, typename Value =, typename Compare = Greater<Value> > class MaxSearch : public Procedure<> { protected: ; bool _l; _optelem; Value _opt; Compare _better; az típusú elemek Value típusú értékeit hasonlítjuk össze ősciklusban használt metódusok felüldefiniálása void init(){ _l = false; újabb felüldefiniálható void body(const & current); metódusok virtual Value func(const & e) const = 0; virtual bool cond(const & e) const { return true; public: bool found() const { return _l; eredmény lekérdezése Value opt() const { return _opt; optelem() const { return _optelem; maxsearch.hpp
template <typename, typename Value, typename Compare> void MaxSearch<,Value,Compare>::body(const & current) { Value val = func(current); if (!cond(current) ) return; if (_l){ if (_better(val,_opt)){ _opt = val; _optelem = current; else { _l = true; _opt = val; _optelem = current; a Compare típusú _better összehasonlító objektum mutatja meg, hogy val jobb-e, mint az _opt maxsearch.hpp
template <typename Value> class Greater{ public: bool operator()(const Value& l, const Value& r) { return l > r; Ha Compare a Greater<int>, akkor _better(2,5) azonos a 2>5 értékével. ; Ha Compare a Less<int>, akkor template <typename Value> _better(2,5) azonos a 2<5 értékével. class Less{ public: bool operator()(const Value& l, const Value& r) { return l < r; ; compare.hpp
Procedure -*enor Enumerator +run() : void +addenumerator() : void # init() : void # body() : void # first() : void # loopcond() : bool # whilecond() : bool +first() +next() +current() +end() : void : void : : bool, Value, Compare MaxSearch # init() : void # body() : void # func() : Value # cond() : bool + found() : bool + opt() : Value + optelem() : Greater +operator(, ) : bool Less +operator(, ) : bool Value Value
Adott egy egész számokat tartalmazó szöveges fájl, amelyben keressük a legnagyobb páratlan számot! Melyik a legnagyobb páratlan szám? A feladat visszavezethető a feltételes maximum keresésre 1. Vizsgált elemek típusa (): egész számok 2. Az Value függvény (func): identitás 3. Összehasonlítandó értékek típusa (Value): egész számok 4. Összehasonlítás (Compare): nagyobb reláció (Greater) 5. Feltétel (cond): a szám páratlan 6. Felsoroló: szöveges állomány egész számainak felsorolója
Procedure -enor* Enumerator +run() +addenumerator() : void : void, Value, Compare MaxSearch # init() : void # body() : void # func() : Value # cond() : bool + found() : bool + opt() : Value + optelem() : int int SeqInFileEnumerator Greater Value int, int, Greater<int> MyMaxSearch # func(int e) : int # cond(int e) : bool -enor* -better +operator(, ) : bool return e%2!=0 return e
class MyMaxSearch : public MaxSearch<int>{ protected: ; int main(){ int func(const int& e) const { return e; bool cond(const int& e) const { return e%2!=0; tevékenység objektum 12-5 23 44 130 56 3-120 felsoroló objektum MyMaxSearch pr; SeqInFileEnumerator<int> file_enum("input.txt"); pr.addenumerator(&file_enum); input.txt pr.run(); if (pr.found()) működés Hiányzik a kivételkezelés! cout << "A legnagyobb páratlan szám:" << pr.optelem(); else cout << "Nincs páratlan szám"; return 0; main.cpp
new addenumerator() run() found() optelem() : MyMaxSearch new first() next() end() current() : SeqInFileEnumerator
: MyMaxSearch : SeqInFileEnumerator new new addenumerator() run() found() optelem() first() next() end() current()
Egy forgalom számlálás során egy hónapon keresztül számolták, hogy az egyes órákban hány utas lép be egy adott metróállomás területére. (A méréseket hétfőn kezdték, de lehet, hogy nem minden nap és ne minden órában végeztek megfigyelést.) Az időt egy négyjegyű számmal kódolták, amelynek első két jegye a nap hónapbeli sorszámát, utolsó két jegye az órát mutatja. Egy szöveges fájlban időkód-létszám párok formájában rögzítették a méréseket. A hétvégi napok közül mikor (nap, óra) léptek be legkevesebben az állomás területére?
Mikor léptek be legkevesebben a hétvégi időpontok közül? A feladat visszavezethető a feltételes minimum keresésre 1. Vizsgált elemek (): mérések, azaz időkód-létszám (egész szám) párok 2. Az Value függvény (func): egy mérésből kiemeli a létszámot 3. Összehasonlítandó értékek (Value): létszám (egész számok) 4. Összehasonlítás (Compare): kisebb (Less) reláció 5. Feltétel (cond): a mérés hétvégére esik 6. Felsoroló: szöveges állomány méréseit sorolja fel
struct Pair{ int time; int number; int day() const { return time/100; int hour() const { return time%100; 0108 23 0112 44 0116 130 0207 120 input.txt ; friend ifstream& operator>>(ifstream&, Pair&); ifstream& operator>>(ifstream& f, Pair& df) { f >> df.time >> df.number; return f; Szekvenciális inputfájl Pair típusú elemeinek felsorolásához kell main.cpp
class MyMinSearch: public MaxSearch<Pair, int, Less<int> > { protected: int func(const Pair &e) const { return e.number; bool cond(const Pair &e) const { return (e.day()%7==6 e.day()%7==0; ; main.cpp
int main() { MyMinSearch pr; SeqInFileEnumerator<Pair> file_enum("input.txt"); pr.addenumerator(&file_enum); pr.run(); if (pr.found()){ Pair p = pr.optelem(); cout << "A " << p.day() << ". napon a " << p.hour() << "-kor lépett a legkevesebb, " << pr.opt() << " fő az állomásra" << endl; else cout << "Nincs hétvégi adat" << endl; return 0; main.cpp