Programozási tételek újrafelhasználása
Cél Adott egy a programozási tételeket általánosan leíró kódkönyvtár (osztálysablon könyvtár), 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. Ezen objektum osztályát származtatással hozzuk létre, 2. miután felparamétereztük a kódkönyvtárbeli ősosztályát, 3. az objektumhoz pedig egy megfelelő felsoroló objektumot csatolunk. Gregorics Tibor: Objektumelvű alkalmazások fejlesztése 2
Ötlet bool l = false; for (enor.first();!enor.end(); enor.next()){ if(!cond(enor.current())) continue; Value val = func(enor.current()); if(!l){ l=true; opt = val; optitem = enor.current(); else{ if( opt < val ){ opt = val; optitem = enor.current(); { int db = 0; for (enor.first();!enor.end(); enor.next()){ if( cond(enor.current()) ) ++db; bool l = false; for (enor.first();!l &&!enor.end(); enor.next()){ l = cond(elem = enor.current()); init(); for(enor.first();!enor.end() && whilecond(enor.current()); enor.next()){ body(enor.current()); Gregorics Tibor: Objektumelvű alkalmazások fejlesztése 3
Vázlat Procedure + run() : void # init() : void {virtual # body(e:) : void {virtual # whilecond() : bool {virtual init() enor.first() while enor.end() whilecond() do body( enor.current() ) enor.next() od return true Counting # c : int # init() : void {override # body(e:): void {override # cond() : bool {virtual + result() : int {query if cond(e) then c := c + 1 fi c := 0 LinearSearch # l : bool # elem : # init() : void {override # body(e:): void {override # whilecond() : bool {override # cond() : bool {virtual + found() : bool {query + elem() : {query l := false l := cond(e) elem := e return l Gregorics Tibor: Objektumelvű alkalmazások fejlesztése 4
Programozási tételek ősciklusa felsorolt elemek típusa template <typename > void Procedure<>::run() final { if(_enor==null) throw MISSING_ENUMERATOR; default: _enor->first() init(); for( first(); loopcond(); _enor->next()) { body(_enor->current()); felsoroló objektumra mutató pointer default:!_enor->end() && whilecond(_enor->current()) default: true Gregorics Tibor: Objektumelvű alkalmazások fejlesztése 5
Programozási tételek ősosztálya felsorolt elemek típusa template <typename > class Procedure { protected: Enumerator<> *_enor; felsoroló objektumra mutató pointer ; Procedure():_enor(nullptr){ 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 ; virtual void run() final; void addenumerator(enumerator<>* en) final { _enor = en; virtual ~Procedure(){ konkrét felsoroló objektum hozzáadása procedure.hpp Gregorics Tibor: Objektumelvű alkalmazások fejlesztése 6
Felsorolás Procedure -*enor <<interface>> Enumerator +run() : void {final +addenumerator() : void # init() : void {virtual # first() : void {virtual # body() : void {virtual # loopcond() : bool {virtual # whilecond() : bool {virtual ArrayEnumerator +first() : void +next() : void +current() : +end() : bool SeqInFileEnumerator - vect : array of - ind : int + first() : void {override + next() : void {override + current() : {override + end() : bool {override - f : file of - df : + first() : void {override + next() : void {override + current() : {override + end() : bool {override Gregorics Tibor: Objektumelvű alkalmazások fejlesztése 7
Felsorolók ősosztálya 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 Gregorics Tibor: Objektumelvű alkalmazások fejlesztése 8
Tömb felsorolója template <typename > class ArrayEnumerator : public Enumerator<> { protected: std::vector<> *_vect; unsigned int _ind; public: ArrayEnumerator(std::vector<> *v):_vect(v){ ; void first() override { _ind = 0; void next() override { ++_ind; bool end() const override { return _ind>=_vect->size(); current()const override { return (*_vect)[_ind]; arrayenumerator.hpp Gregorics Tibor: Objektumelvű alkalmazások fejlesztése 9
Szekvenciális inputfájl felsorolója 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(); Az -re legyen értelmes az operator>> #include <typeinfo> void first() override { next(); void next() override { _f >> _df; bool end() const override { return _f.fail(); current() const override { return _df; seqinfileenumerator.hpp Gregorics Tibor: Objektumelvű alkalmazások fejlesztése 10
Általános maximum keresés Procedure -*enor <<interface>> Enumerator +run() : void {final +addenumerator() : void # init() : void {virtual # first() : void {virtual # body() : void {virtual # loopcond() : bool {virtual # whilecond() : bool {virtual +first() : void +next() : void +current() : +end() : bool MaxSearch, Value, Compare # init() : void {final # body() : void {final # func() : Value {virtual # cond() : bool {virtual + found() : bool {queryl + opt() : Value {queryl + optelem() : {queryl Gregorics Tibor: Objektumelvű alkalmazások fejlesztése 11
Általános maximum keresés osztálya 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() override final{ _l = false; void body(const & current) override final; virtual Value func(const & e) const = 0; virtual bool cond(const & e) const { return true; public: bool found() const { return _l; újabb felüldefiniálható metódusok Value opt() const { return _opt; optelem()const { return _optelem; eredmény lekérdezése maxsearch.hpp Gregorics Tibor: Objektumelvű alkalmazások fejlesztése 12
Általános maximum keresés tevékenysége template <typename, typename Value, typename Compare> void MaxSearch<,Value,Compare>::body(const & e) override final { if (!cond(e) ) return; Value val = func(e); if (_l){ if (_better(val,_opt)){ _opt = val; _optelem = current; else { _l = true; _opt = val; _optelem = current; a Compare típus-sablonú _better objektum mutatja meg, hogy a val jobb-e, mint az _opt. maxsearch.hpp Gregorics Tibor: Objektumelvű alkalmazások fejlesztése 13
Összehasonlító osztályok 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. ; template <typename Value> Ha Compare a Less<int>, akkor class Less{ _better(2,5) azonos a 2<5 értékével. public: bool operator()(const Value& l, const Value& r) { return l < r; ; maxsearch.hpp Gregorics Tibor: Objektumelvű alkalmazások fejlesztése 14
1. Feladat Adott egy egész számokat tartalmazó szöveges állomány. Keressük meg ebben 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 Gregorics Tibor: Objektumelvű alkalmazások fejlesztése 15
Megoldás terve Procedure -*enor Enumerator, Value, Compare MaxSearch -*enor SeqInFileEnumerator # func() : Value {virtual # cond() : bool {virtual int -better Greater Value MyMaxSearch int, int, Greater<int> int +operator(, ) : bool # func(e:int) : int {override # cond(e:int) : bool {override return e mod 2!=0 return e Gregorics Tibor: Objektumelvű alkalmazások fejlesztése 16
A megvalósításhoz készített kód class MyMaxSearch : public MaxSearch<int>{ protected: int func(const int& e) const override { return e; bool cond(const int& e) const override { return e%2!=0; ; tevékenység objektum int main(){ MyMaxSearch pr; SeqInFileEnumerator<int> file_enum("input.txt"); // kivételkezelés pr.addenumerator(&file_enum); felsoroló objektum 12-5 23 44 130 56 3-120 input.txt pr.run(); működés if (pr.found()) cout << "A legnagyobb páratlan szám:" << pr.optelem(); else cout << "Nincs páratlan szám"; return 0; main.cpp Gregorics Tibor: Objektumelvű alkalmazások fejlesztése 17
2. Feladat Egy forgalom számlálás során egy hónapon keresztül számolták, hogy óránként 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 nem minden órában végeztek megfigyelést.) Az időt négyjegyű számmal kódolták, amelynek első két jegye a mérés napjának a megfigyelés elkezdése óta számolt sorszámát, utolsó két jegye a mérésnek az adott napbeli óráját mutatja. A méréseket egy szöveges állományban rögzítették időkód-létszám párok formájában. A hétvégi napok közül mikor (melyik nap melyik órájában) léptek be az állomás területére legkevesebben? Gregorics Tibor: Objektumelvű alkalmazások fejlesztése 18
Megoldás vázlata Mikor léptek be legkevesebben a hétvégi időpontok közül? A feladat visszavezethető a feltételes minimum keresésre speciális 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 reláció (Less) 5. Feltétel (cond): a mérés hétvégére esik 6. Felsoroló: szöveges állomány méréseit sorolja fel Gregorics Tibor: Objektumelvű alkalmazások fejlesztése 19
Megoldás terve Procedure -*enor Enumerator, Value, Compare MaxSearch -*enor SeqInFileEnumerator # func() : Value {virtual # cond() : bool {virtual Pair -better Less Value MyMinSearch Pair, int, Less<int> int +operator(, ) : bool # func(e:int) : int {override # cond(e:int) : bool {override return e.number return e.day()%7==6 e.day()%7==0; Gregorics Tibor: Objektumelvű alkalmazások fejlesztése 20
Elemi típus () 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 Gregorics Tibor: Objektumelvű alkalmazások fejlesztése 21
A feladatot megoldó feltételes minimumkeresés osztálya minimum keresés class MyMinSearch: public MaxSearch<Pair, int, Less<int> > { protected: létszámok szerint int func(const Pair &e) const override { return e.number; bool cond(const Pair &e) const override feltétellel { return { e.day()%7==6 e.day()%7==0; ; main.cpp Gregorics Tibor: Objektumelvű alkalmazások fejlesztése 22
Főprogram 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 Gregorics Tibor: Objektumelvű alkalmazások fejlesztése 23
3. Feladat Adott egy szöveges állománybeli szöveg, ahol a szavakat szóközök, tabulátor-jelek, sorvége-jelek, illetve a fájlvége-jel határolja. Melyik az a leghosszabb szó, amelyik legnagyobb kódú karaktere a w betű? Melyik a leghosszabb adott tulajdonságú szó? A feladat visszavezethető a feltételes maximum keresésre 1. Vizsgált elemek (): szavak (string) 2. Az Value függvény (func): előállítja egy szó hosszát (size) 3. Összehasonlítandó értékek (Value): szavak hossza (int) 4. Összehasonlítás (Compare): nagyobb reláció (Greater) 5. Feltétel (cond): a szó legnagyobb kódú karaktere a w 6. Felsoroló: szöveges állomány szavainak felsorolója részfeladat Gregorics Tibor: Objektumelvű alkalmazások fejlesztése 24
Megoldás terve Procedure -*enor Enumerator, Value, Compare MaxSearch -*enor SeqInFileEnumerator # func() : Value {virtual # cond() : bool {virtual string -better Greater Value MyMaxSearch string, int, Greater<int> # func(e:int) : int {override # cond(e:int) : bool {override int return maxchar(e) == w +operator(, ) : bool részfeladat return e.size() Gregorics Tibor: Objektumelvű alkalmazások fejlesztése 25
Megvalósítás class MyMaxSearch : public MaxSearch<string, int>{ protected: int func(const string& e) const override { return e.size(); bool cond(const string& e) const override; ; részfeladat int main() { MyMaxSearch pr; SeqInFileEnumerator<string> word_enor("text.txt"); pr.addenumerator(&word_enor); pr.run(); if (pr.found()) cout << "A keresett szó " << pr.optelem() << endl; else cout << "Nincs keresett tulajdonságú szó\n"; return 0; main.cpp Gregorics Tibor: Objektumelvű alkalmazások fejlesztése 26
Részfeladat Mi egy szó (nem üres sztring) legnagyobb kódú karaktere? A feladat visszavezethető a maximum kiválasztásra 1. Vizsgált elemek (): karakterek (char) 2. Az Value függvény (func): identitás 3. Összehasonlítandó értékek (Value): karakterek (char) 4. Összehasonlítás (Compare): nagyobb reláció (Greater) 5. Feltétel (cond): igaz 6. Felsoroló: egy sztring karaktereinek felsorolója új felsoroló Gregorics Tibor: Objektumelvű alkalmazások fejlesztése 27
Megoldás terve Procedure -*enor Enumerator, Value, Compare MaxSearch -*enor StringEnumerator # func() : Value {virtual # cond() : bool {virtual char -better Greater Value char, int, Greater<int> InnerMaxSearch # func(char e) : int {override int +operator(, ) : bool return code(e) Gregorics Tibor: Objektumelvű alkalmazások fejlesztése 28
Megvalósítás class StringEnumerator : public Enumerator<char> { protected: string _str; unsigned int _ind; public: StringEnumerator(const string& s): _str(s){ void first() override { _ind = 0; void next() override { ++_ind; bool end() const override { return _ind>=_str.size(); char current() const override { return _str[_ind]; ; class InnerMaxSearch : public MaxSearch<char, int>{ protected: int func(const char& e) const override { return e; ; bool MyMaxSearch::cond(const string& e) const override { InnerMaxSearch pr; StringEnumerator enor(e); pr.addenumerator(&enor); pr.run(); return 'w'==pr.optelem(); ; main.cpp Gregorics Tibor: Objektumelvű alkalmazások fejlesztése 29
4. Feladat Egy szöveges állományban neveket soroltak fel ábécé szerint rendezve. Keressük meg az első olyan nevet amelyik legalább ötször szerepel az állományban! Melyik az első legalább ötször szereplő név? A feladat visszavezethető egy lineáris keresésre 1. Vizsgált elemek (): név-darabszám párok 2. Feltétel (cond): a vizsgált pár darabszáma legalább 5 újabb programozási tétel speciális részfeladat 3. Felsoroló: név-darabszám párok felsorolása, amely a szöveges állománybeli egymás után álló azonos nevek felsorolására épül Gregorics Tibor: Objektumelvű alkalmazások fejlesztése 30
Megoldás terve Procedure -*enor Enumerator LinSearch Pesszimista vagy optimista, bool SeqInFileEnumerator # init() : void {final # body() : void {final # cond() : bool {virtual # whilecond() : bool {final + found() : bool + elem() : Pair, false MyLinSearch # cond(e:pair) : bool {override Pair - *enor string *f PairEnumerator # current : Pair # end : bool +first() : void +next() : void +current() : char +end() : bool *f Gregorics Tibor: Objektumelvű alkalmazások fejlesztése 31
Lineáris keresés osztálya template < typename, bool optimist = false> class LinSearch : public Procedure<> { protected: bool _l; _elem; void init() override final { _l = optimist; void body(const & e) override final { _l = cond(_elem = e); bool whilecond(const & e) const override final { return optimist?_l:!_l; virtual bool cond(const & e) const = 0; public: bool found() const { return _l; elem() const { return _elem; ; linsearch.hpp Gregorics Tibor: Objektumelvű alkalmazások fejlesztése 32
Kitérő: Kiválasztás osztálya template < typename > class Selection : public Procedure<> { protected: void init() override final { void body(const & e) override final { bool loopcond() const override final { return!cond(procedure<>::_enor->current()); virtual bool cond(const & e) const = 0; public: result() { return Procedure<>::_enor->current(); ; selection.hpp Gregorics Tibor: Objektumelvű alkalmazások fejlesztése 33
Megvalósítás struct Pair{ string name; int count; ; class MyLinSearch : public LinSearch<Pair>{ public: bool cond(const Pair &e) const override { return e.count>=5; ; int main() { MyLinSearch pr; PairEnumerator t("text.txt"); pr.addenumerator(&t); pr.run(); if (pr.found()) cout << "A " << pr.elem().name << " az első"; else cout << "Nincs"; cout << " olyan név, amelyet legalább öten viselnek.\n"; return 0; main.cpp Gregorics Tibor: Objektumelvű alkalmazások fejlesztése 34
Név-darabszám felsoroló class PairEnumerator : public Enumerator<Pair> { protected: SeqInFileEnumerator<string> *_f; Pair _current; bool _end; public: PairEnumerator(const string& str) { _f = new SeqInFileEnumerator<string>(str); ~PairEnumerator(){ delete _f; void first() override { _f->first(); next(); void next() override; bool end() const override { return _end; Pair current() const override { return _current; ; részfeladat, amely támaszkodhat a szöveges állomány f felsorolójára main.cpp Gregorics Tibor: Objektumelvű alkalmazások fejlesztése 35
Név-darabszám felsoroló next() művelete Kiszámolja, hogy a neveket tartalmazó szekvenciális inputfájlból legutoljára beolvasott név hányszor szerepel még a fájlban közvetlenül egymás után? Hányszor szerepel az aktuális név a fájlban? Ez a részfeladat visszavezethető a számlálásra (ami egy speciális összegzés), amelyhez a szekvenciális inputfájlbeli szavakat kell felsorolni, de nem az összeset, hanem csak a legutoljára beolvasott névvel megegyező egymás után álló neveket. Vegyük tehát figyelembe, hogy - a számlálás kezdetén már rendelkezünk egy beolvasott névvel: nincs szükség a programozási tételben előreolvasásra ( first() ) - a számlálásnak hamarabb le kell állni, mint a fájl vége, akkor, amikor olyan nevet olvasunk, amelyik eltér az aktuálisan vizsgált névtől: módosul a számlálás ciklus feltétele ( whilecond() ) Gregorics Tibor: Objektumelvű alkalmazások fejlesztése 36
Megoldás terve Procedure -*enor Enumerator # init() : void Summation, ResultType SeqInFileEnumerator # body() : void {final # add() : void {virtual # cond() : bool {virtual + result() : ResultType -*f string Counting, int # init() : void {final # add() : void {final string NameCounting # name : string # first() : void {override # whilecond(string) : bool {override Gregorics Tibor: Objektumelvű alkalmazások fejlesztése 37
Összegzés osztálya template < typename, typename ResultType = > class Summation : public Procedure<> { protected: ResultType *_result; bool _inref; Kétféle eredményváltozója lehet: 1. Kívülről kapja 2. Sajátot készít, amely értéke lekérdezhető Summation(){ _result = new ResultType; _inref = true; Summation(ResultType *r) :_result(r) { _inref = false; void body(const & e) override final { if(cond(e)) add(e); összeadás esetén: *_result := *_result + f(e) virtual void add(const & e) = 0; virtual bool cond(const & e) const { return true; public: feltételes összegzés feltétele ResultType result() { return *_result; ~Summation() { if(_inref) delete _result; ; summation.hpp Gregorics Tibor: Objektumelvű alkalmazások fejlesztése 38
Számlálás osztálya template < typename > class Counting : public Summation<, int> { public: Counting():Summation<,int>(){ ; protected: void init() override final { *Summation<,int>::_result = 0; void add(const & e) override final { ++*Summation<,int>::_result; counting.hpp Gregorics Tibor: Objektumelvű alkalmazások fejlesztése 39
Név-darabszám felsoroló next() művelete még egyszer Hányszor szerepel a soron következő név az állományban? A feladat visszavezethető egy feltétel nélküli számlálásra 1. Vizsgált elemek (): nevek (string) 2. Feltétel (cond): igaz 3. Felsoroló: szöveges állománybeli szavak felsorolása 4. Extra indulás (first): üres (nem szabad újraindítani a felsorolást, birtokunkban van a legutoljára beolvasott név) 5. Extra ciklus feltétel (whilecond): amíg az éppen felsorolt név azonos Gregorics Tibor: Objektumelvű alkalmazások fejlesztése 40
A next() művelet class NameCounting : public Counting<string> { nem kell előreolvasás protected: string _name; amíg az aktuális név nem változik void first() override { bool whilecond(const string& e) const override { return e == _name; public: az aktuális név NameCounting(const string &str): Counting<string>(), _name(str){ ; void PairEnumerator::next(){ if((_end = _f->end())) return; _current.name = _f->current(); NameCounting pr(_current.name); pr.addenumerator(_f); pr.run(); _current.count = pr.result(); main.cpp Gregorics Tibor: Objektumelvű alkalmazások fejlesztése 41
5. Feladat Adott két szöveges állomány, bennük egész számok szigorúan növekedően rendezve. Gyűjtsük ki az összes számot, de mindegyiket csak egyszer egy harmadik szöveges állományba! Futtassuk össze a két állományt (unió)! A feladat visszavezethető az összegzésre 1. Vizsgált elemek (): egész számok 2. Eredmény(ResultType): egész számok sorozata adatstream-en 3. Tevékenység (add): egész szám adatstream-be írása 4. Felsoroló: két szekvenciális inputfájl számainak összefuttatása Gregorics Tibor: Objektumelvű alkalmazások fejlesztése 42
Megoldás terve Procedure -*enor Enumerator Summation, ResultType SeqInFileEnumerator # body() : void {final # add() : void {virtual # cond() : bool {virtual + result() : ResultType int *x, *y int int, outstream Copying # init() : void {override # add() : void {override -*enor CombineEnumerator # name : string # first() : void # whilecond(string) : bool Gregorics Tibor: Objektumelvű alkalmazások fejlesztése 43
Felsorolt számok kiírása class Copying : public Summation<int, ofstream> { public: Copying(ofstream *u):summation<int, ofstream >(u){ protected: void init() override { u void add(const int& e) override { *Summation<int, ofstream>::_result << e << endl; ; int main() { ofstream u("uj.txt"); if(u.fail()) exit(2); Copying pr(&u); CombineEnumerator comb_enor("1.txt","2.txt"); pr.addenumerator(&comb_enor); pr.run(); return 0; main.cpp Gregorics Tibor: Objektumelvű alkalmazások fejlesztése 44
Összefuttató felsoroló class CombineEnumerator : public Enumerator<int> { protected: SeqInFileEnumerator<int> *_x; SeqInFileEnumerator<int> *_y; int _current; bool _end; public: CombineEnumerator(const std::string& str1, const std::string& str2){ _x = new SeqInFileEnumerator<int>(str1); _y = new SeqInFileEnumerator<int>(str2); ~CombineEnumerator(){ delete _x; delete _y; ; void first() override { _x->first(); _y->first(); next(); void next() override; bool end() const override { return _end; int current()const override { return _current; main.cpp Gregorics Tibor: Objektumelvű alkalmazások fejlesztése 45
Összefuttató felsoroló next() művelete void CombineEnumerator::next() override { if( (_end = _x->end() && _y->end()) ) return; if( _y->end() (!_x->end() && _x->current() < _y->current()) ){ _current = _x->current(); _x->next(); else if( _x->end() (!_y->end() && _x->current() > _y->current()) ){ _current = _y->current(); _y->next(); else if(!_x->end() &&!_y->end() && _x->current() == _y->current() ){ _current = _x->current(); _x->next(); _y->next(); main.cpp Gregorics Tibor: Objektumelvű alkalmazások fejlesztése 46
Kitérő: next() művelet csak a közös elemek felsorolásához void CombineEnumerator::next() override { if( (_end = _x->end() _y->end()) ) return; if( _x->current() < _y->current() ){ _x->next(); else if( _x->current() > _y->current() ){ _y->next(); else if( _x->current() == _y->current() ){ _current = _x->current(); _x->next(); _y->next(); main.cpp A next() műveletnek minden alkalommal a felsorolás egy újabb elemét kell előállítania. Gregorics Tibor: Objektumelvű alkalmazások fejlesztése 47
Kitérő: next() művelet csak a közös elemek felsorolásához void CombineEnumerator::next() override { bool l = false; while(!l &&!(_end = _x->end() _y->end()) ) if( _x->current() < _y->current() ){ _x->next(); else if( _x->current() > _y->current() ){ _y->next(); else if( _x->current() == _y->current() ){ _current = _x->current(); l = true; _x->next(); _y->next(); main.cpp Ciklust írni most tilos! Gregorics Tibor: Objektumelvű alkalmazások fejlesztése 48
Kitérő: next() művelet csak a közös elemek felsorolásához void CombineEnumerator::next() override { if( (_end = _x->end() _y->end()) ) return; if( _x->current() < _y->current() ){ _x->next(); next(); else if( _x->current() > _y->current() ){ _y->next(); next(); else if( _x->current() == _y->current() ){ _current = _x->current(); _x->next(); _y->next(); main.cpp De a rekurzió is tilos! Gregorics Tibor: Objektumelvű alkalmazások fejlesztése 49
Összefuttatás next() művelete Minden elemet felsorolunk, és felsoroláson kívül döntjük majd el, hogy egy elemmel kell-e egyáltalán valamit csinálni akarjuk feldolgozni. struct{element data; void CombineEnumerator::next() override string sign; { if( (_end = _x->end() && _y->end()) ) return; if( _y->end() (!_x->end() && _x->current().data < _y->current().data) ){ _current.data = _x->current(); _current.sign = x ; _x->next(); else if( _x->end() (!_y->end() && _x->current().data > _y->current().data) ){ _current.data = _y->current(); _current.sign = y ; _y->next(); else if(!_x->end() &&!_y->end() && _x->current().data == _y->current().data ){ _current.data = _x->current(); _current.sign = xy ; _x->next(); _y->next(); main.cpp Gregorics Tibor: Objektumelvű alkalmazások fejlesztése 50