Zapoctovy test 22. 1. 2007

Stevko

Zapoctovy test 22. 1. 2007

Příspěvek od Stevko »

Napíšte kontajner gpole<typename T, int dolny_index>, ktorý bude reprezentovať gumové pole indexované od dolny_index.
Požiadavky:
Aby to bol kontainer, musí mať v sebe typy
value_type, reference_type, const_reference_type, size_type, difference_type, iterator a const_iterator
a funkcie
gpole(), const_iterator begin() const, iteator begin(), const_iterator end() const, iterator end(), size_type size(), bool empty().
Ďalej to malo mať funkciu void push_back(const T&) a pôvodne aj funkcie T& at(int index) a const T& at(int index) const. Tie boli neskôr vymenené za T & write(int index) a T read(int index) const.
Celý kontainer sa mal dať vypísať do streamu a načítať zo streamu (gpole<int, 5> a; cin >> a; cout << a;).
Funkcie robia na našom kontajneri gpole to isté, čo na vektore.
read mala vyhadzovať výnimku, ak sme mimo poľa, write malo vyhodiť výnimku, ak sme pod dolným indexom, ináč (v prípade potreby) roztiahnúť pole a prvky "v strede" vyplniť prvkami T().

Typy v kontajneri gpole sa vyrieši rýchlo (to vlastne bolo povedané pri zadaní):

Kód: Vybrat vše

	typedef T value_type;

	typedef T& reference_type;

	typedef const T& const_reference_type;

	typedef int size_type;

	typedef int difference_type;
Ďalej bolo možné použiť STL, takže celé to bol vlastne len obalený vektor a iterátory by v tom prípade mali vyzerať (asi - ja som to urobil trochu ináč) takto:

Kód: Vybrat vše

typedef typename std::vector<T>::iterator iterator;
typedef typename std::vector<T>::const_iterator const_iterator;
Najčastejší problém bolo vynechanie typename (vysvetlí mi niekto, prečo to tam má byť?).
Funkcia bool empty() bola rovno predpísaná: {return size() == 0;}.
Na výpis do streamu bola požiadavka, že ak vypíšeme gpole do súboru, tak sa z neho musí dať načítať (čiž vo výpise nejak oddeľovať prvky, najlepšie medzerami). Výpis jedného prvku T p je cout << p; O implementáciu << pre T sa stará ten, čo používa našu šablónu.
Na výpis teda použijeme:

Kód: Vybrat vše

template <typename T, int n> std::ostream & operator<<(std::ostream & s, const gpole <T, n> & pole)
Na prejdenie testom bolo nutné, aby na vytvorenom gumovom poli správne prebehlo sort(pole.begin(), pole.end())
No a ešte môj program. Rozhodol som sa gumové pole si implementovať sám (nepoužiť vector). Pôvodne som myslel, že vyrobím aj rozumnú funkciu at() - pozri posledný slajd ku stringom v Bednárkovych slajdoch - ale nejak to nevyšlo. Je teda zakomentovaná (skúste to opraviť, zaujíma ma to). Tiež som mal problém s označením operátoru ako friend, takže je to trochu "prasácke" (verejné dátové položky), ale bolo to uznané.
Na začiatku je nejaká testovacia trieda - mali sme šablónu otestovať nie len na vstavaných typoch.
Takže program:

Kód: Vybrat vše

#include <iostream>

#include <stdexcept>

#include <algorithm>





class testovacia_trieda{

public:

	testovacia_trieda():a(0){}

	testovacia_trieda(int a_){

		a=a_;

	}



	bool operator<(const testovacia_trieda & b){

		return a < b.a;

	}

	int a;

};



std::ostream & operator<<(std::ostream & s, const testovacia_trieda & a){

	s << a.a;

	return s;

}



std::istream & operator>>(std::istream & s,  testovacia_trieda & a){

	s >> a.a;

	return s;

}



template <typename T, int dolny_index> class gpole{

public:

	typedef T value_type;

	typedef T& reference_type;

	typedef const T& const_reference_type;

	typedef int size_type;

	typedef int difference_type;

	typedef T * iterator;

	typedef const T * const_iterator;

	enum {DOLNY_INDEX = dolny_index, MINIM_ALOK = dolny_index>0?dolny_index+10:10};



	int pocet_prvkov;

	int alokovane;

	T * pole;

	

	int size(){

		return pocet_prvkov;

	}



	bool empty(){

		return pocet_prvkov == 0;

	}

	

	iterator begin(){

		return pole;

	}



	iterator end(){

		return pole+pocet_prvkov;

	}



	const_iterator begin() const{

		return pole;

	}



	const_iterator end() const{

		return pole+velkost;

	}



	gpole(){

		alokovane = MINIM_ALOK;

		pole = new T[MINIM_ALOK];

		pocet_prvkov = 0;

	}



	void push_back(const T & novy_prvok_){

		if (alokovane == pocet_prvkov+1){	//TODO: skontroluj podmienku!!

			T* pomocne_pole = 0;

			

			try{

				pomocne_pole = new T[alokovane * 2];

			}catch(...){	//TODO: Aku vynimku vracia new?

				std::cerr << "Malo pamate! Vynimka." << std::endl;

				return;

			}

			alokovane = alokovane * 2;

			for (int i = 0; i<pocet_prvkov; i++){

				pomocne_pole[i] = pole[i];

			}

			delete pole;

			pole = pomocne_pole;

		}

		pole[pocet_prvkov] = novy_prvok_;

		++pocet_prvkov;

	}



	T read(int pozicia) const{

		if ((pozicia < DOLNY_INDEX) || (pozicia >=pocet_prvkov+DOLNY_INDEX)){

			throw std::out_of_range("Mimo.");

			return T();

		}else{

			return pole[pozicia-DOLNY_INDEX];

		}

	}



/*	void write(int pozicia, const T& novy_prvok_){

		int skutocna_pozicia = pozicia - DOLNY_INDEX;

		if (skutocna_pozicia < 0){

			throw std::out_of_range("Mimo");

			return;

		}

		//Sme nad nulou.

		if (skutocna_pozicia < alokovane){

			//vsetky prvky medzi pocet_prvkov a alokovane su vytvorene konstruktorom T()

			//takze

			pole[skutocna_pozicia] = novy_prvok_;

			return;

		}

		//Ak sme za alokovanym miestom:

		T * pomocne_pole;

		try{

			pomocne_pole = new T[skutocna_pozicia+MINIM_ALOK];	//Pridame este nejaku rezervu za pole;

		}catch(...){	//TODO: Aku vynimku vracia new?

			cerr << "Malo pamate! Vynimka." << endl;

			return;

		}

		alokovane = skutocna_pozicia+MINIM_ALOK;

		for (int i = 0; i<pocet_prvkov; ++i){

			pomocne_pole[i] = pole[i];

		}

		delete pole;

		pole = pomocne_pole;

		pole[skutocna_pozicia] = novy_prvok_;

	}

*/	

	T& write (int pozicia){	//Takmer kopia kodu z write()

		//TODO: Odstranit dva krat ten isty kod!

		int skutocna_pozicia = pozicia - DOLNY_INDEX;

		if (skutocna_pozicia < 0){

			throw std::out_of_range("Mimo");

		

		}

		//Sme nad nulou.

		if (skutocna_pozicia < alokovane){

			//vsetky prvky medzi pocet_prvkov a alokovane su vytvorene konstruktorom T()

			//takze

			if(pocet_prvkov <= skutocna_pozicia){

				pocet_prvkov = skutocna_pozicia + 1;

			}

			return pole[skutocna_pozicia];

		}

		//Ak sme za alokovanym miestom:

		T * pomocne_pole;

		try{

			pomocne_pole = new T[skutocna_pozicia+MINIM_ALOK];	//Pridame este nejaku rezervu za pole;

		}catch(...){	//TODO: Aku vynimku vracia new?

			std::cerr << "Malo pamate! Vynimka." << std::endl;

		}

		alokovane = skutocna_pozicia+MINIM_ALOK;

		for (int i = 0; i<pocet_prvkov; ++i){

			pomocne_pole[i] = pole[i];

		}

		delete pole;

		pole = pomocne_pole;

		pocet_prvkov = skutocna_pozicia+1;

		return pole[skutocna_pozicia];

	}



	void clear(){

		delete pole;

		pocet_prvkov = 0;

		alokovane = MINIM_ALOK;

		pole = new T[MINIM_ALOK];

	}



/*	class vrat_pri_at{

	public:

		vrat_pri_at(gpole< T, dolny_index> * pole_, int pozicia_):pole(pole_), pozicia(pozicia_){}

		operator T() const{

			return pole->read(pozicia);

		}

		const vrat_pri_at & operator=(T  novy){

			t->write(pozicia, novy);

			return *this;

		}



	private:

		gpole < T, dolny_index> *pole;

		int pozicia;

	};



	T at(int pozicia_) const{

		return read(pozicia_);

	}



	vrat_pri_at & at(int pozicia){

		return vrat_pri_at(*this, pozicia_);

	}

*/

//	friend std::ostream & operator<<(std::ostream & s, gpole <T, dolny_index>);

//	friend std::istream & operator>>(std::istream & s, gpole <T, dolny_index>);



	

};



template <typename T, int n> std::ostream & operator<<(std::ostream & s, const gpole <T, n> & pole){

	for (int i = 0; i<pole.pocet_prvkov; i++){

		s << pole.pole[i] << " ";

	}

	return s;

}



template <typename T, int n> std::istream & operator>>(std::istream & s, gpole <T, n> & pole){

	pole.clear();

	T pomocny_prvok;

	s >> pomocny_prvok;

	do{

		pole.push_back(pomocny_prvok);

		s >> pomocny_prvok;

	}while (!s.fail());

	return s;

}



int main(){

	gpole <testovacia_trieda, -2> a;

	if(a.empty()){

		std::cout << "Prazdny." << std::endl;

	}

	a.begin();

	//a.at(1) = 2;

	



	//std::cout << a.read(5);

	a.write(6) = 3;

	a.write(-1) = 4;

	a.write(-2) = 6;

	a.write(0) = 12;

	std::cout << a;

//	std::cout << a.read(6);

	std::cin >> a;

	std::sort(a.begin(), a.end());

	std::cout << a;

	return 0;

}

Uživatelský avatar
cathack
Matfyz(ák|ačka) level I
Příspěvky: 31
Registrován: 31. 1. 2006 14:18
Typ studia: Informatika Bc.

Příspěvek od cathack »

nestačilo jen odvodit gpole od vectoru a dopsat požadované metody navíc?

Kód: Vybrat vše

template <typename T, int N> class gpole: public std::vector<T> {};
nebo bylo v požadavcích specifikováno, že se má low-level implementace udělat jen pomocí elementárních datových typů bez použití STL?
MIKI
Matfyz(ák|ačka) level III
Příspěvky: 186
Registrován: 10. 12. 2004 22:35
Typ studia: Informatika Bc.
Kontaktovat uživatele:

Příspěvek od MIKI »

cathack píše:nestačilo jen odvodit gpole od vectoru a dopsat požadované metody navíc?

Kód: Vybrat vše

template <typename T, int N> class gpole: public std::vector<T> {};
nebo bylo v požadavcích specifikováno, že se má low-level implementace udělat jen pomocí elementárních datových typů bez použití STL?
Praveze odvodenie bolo zakazane ale STL povolene.
Skratka nesmel si dedit nic od zidneho kontajneru. :roll:
MOTTO-1: Nieje dôležité vedieť ale pochopiť!!!
MOTTO-2: Neuč sa!!! Život ťa naučí. Mňa naučil, že sa mám učiť.
Uživatelský avatar
cathack
Matfyz(ák|ačka) level I
Příspěvky: 31
Registrován: 31. 1. 2006 14:18
Typ studia: Informatika Bc.

Příspěvek od cathack »

MIKI píše:Praveze odvodenie bolo zakazane ale STL povolene.
Skratka nesmel si dedit nic od zidneho kontajneru. :roll:
myslím si, že autorovi zadání chybí fantazie. oproti ostatním zde uvedeným je to vyloženě slabota. :) příliš "umělý" příklad.
MIKI
Matfyz(ák|ačka) level III
Příspěvky: 186
Registrován: 10. 12. 2004 22:35
Typ studia: Informatika Bc.
Kontaktovat uživatele:

Příspěvek od MIKI »

cathack píše:myslím si, že autorovi zadání chybí fantazie. oproti ostatním zde uvedeným je to vyloženě slabota. :) příliš "umělý" příklad.
Myslim, ze Panovi RNDr. Yaghobovi fantazia nechyba - vid interpret jazyka asembler z minuleho roku - za co mu touto cestou dakujem :twisted:
MOTTO-1: Nieje dôležité vedieť ale pochopiť!!!
MOTTO-2: Neuč sa!!! Život ťa naučí. Mňa naučil, že sa mám učiť.
Odpovědět

Zpět na „2006“