5241


LAB_9 Wprowadzenie w STL

Na przykładzie klasy kontenera vector rozważymy kilka elementarnych zadań.

1. Wprowadzimy klasę danych

współrzędne punktu na płaszczyźnie

class coord

{

double *cr; //wpółrzędne punktu na płaszczyźnie cr[0] = x; cr[1] = y

public:

coord() : cr(NULL) {}

coord(double x, double y);

~coord() { if(cr) delete [] cr;}

void set(double x, double y);

double * get() { return cr;}

private:

void alloc();

};

void coord::alloc()

{

try

{

cr = new double [2];

memset((void *)cr, 0, 2*sizeof(double));

}

catch(bad_alloc xx)

{

}

}

coord::coord(double x, double y)

{

alloc();

cr[0] = x;

cr[1] = y;

}

void coord::set(double x, double y)

{

cr[0] = x;

cr[1] = y;

}

2. Stworzymy tablicę dynamiczną vector

int _tmain(int argc, _TCHAR* argv[])

{

//numb - ilość punktów

size_t numb = 20, ind, it;

const double PI = 3.14159236;

double x, y, ro, fi, dfi = 2.0*PI/numb;

coord tmp(0, 0); //obiekt pomocniczy

vector<coord> vec; //tablica dynamiczna dla typu danych coord

vector<coord>::iterator It_end; //wprowadzamy iterator do klasy kontenera

//vector , typ danych - coord

//przygotowanie tablicy obiektów coord

for(it=0; it<numb; it++)

{

//promień zmieniamy w sposób losowy

ind = rand()%5;

fi = dfi*it;

ro = static_cast<double>(ind+1);

x = ro*cos(fi);

y = ro*sin(fi);

//tworzymy obiekt typu coord ze współrzędnymi x, y

tmp.set(x, y);

//umieszczamy w koniec tablicy vec

vec.push_back(tmp);

}

//wyświetlamy zbiór punktów na monitorze za pomocą funkcji-szablonu disp

disp(vec, "initial vec");

//sortowanie tablicy obiektow coord

//w porządku malejacym (dlugosc wektora)

// ob.ro[i] > ob.ro[i+1]

//algorytm sort, funkcje-predykat SortDescending

sort(vec.begin(), vec.end(), SortDescending);

disp(vec, "sorted in descending order vec");

//usunięcie wektorów z taką samą długością

//algorytm unique, funkcja-predykat CoordCompare)

It_end = unique(vec.begin(), vec.end(), CoordCompare);

//obcinamy vec po unique

vec.erase(It_end, vec.end());

disp(vec, "after unique vec");

vec.clear();

system("pause");

return 0;

}

3. Funkcja szablon disp()

template<class T>

void disp(vector<T> &v, char *str)

{

vector<T>::iterator It;

cout << str << endl;

//przeglądamy tablicę dynamiczną za pomocą iteratorów

for(It=v.begin(); It!=v.end(); It++)

{

cout << *(It); //pobieramy wartość obiektu przez iterator

}

cout << "-------------------\n";

}

4. Dla wykonania sformułowanego powyżej zadania trzeba przygotować klasę danych:

Dla poprawnego działania algorytmów sort, unique trzeba wprowadzić funkcje-predykat SortDescending i funkcje porównawczą CoordCompare.

bool SortDescending(coord elem1, coord elem2)

//funkcja-predykat SortDescending jest predykatem binarnym:

//zwraca bool i ma dwa argumenty

//dla sortowania w porządku malejacym według dlugości wektora funkcja //SortDescending powinna zwrócić true, jeśli długość ro1 elementu elem1 jest //większy od długości ro2 elementu elem2, gdzie elem1 i elem2 to dwa kolejne //elementy tablicy dynamicznej, reprezentowanej klasą-kontenerem vector

{

double ro1 = elem1, ro2 = elem2;

//Wyrażenie double ro1 = elem1 ma sens tylko wtedy, kiedy wprowadzimy funkcje konwertującą operator double() { return (liczymy dlugość wektora))

return ro1 > ro2;

}

Funkcja konwertująca w klasie danych:

dołożyć prototyp tej funkcji w deklaracji klasy (public)

operator double();

Definicja:

coord::operator double ()

{

double ro = cr[0]*cr[0]+cr[1]*cr[1];

return sqrt(ro);

}

Porównywanie == typów danych double może powodować problemy. Ten kod jest niepoprawny.

bool CoordCompare(coord elem1, coord elem2)

{

double ro1 = elem1, ro2 = elem2;

return(ro1 == ro2);

}

W skutek błędów zaokrąglenia pewne elementy tablicy mogą być potraktowane jako != .

Na przykład: 2.0000000000000 i 2. 0000000000001 .

Oto jest poprawny wariant kodu:

bool CoordCompare(coord elem1, coord elem2)

{

double ro1 = elem1, ro2 = elem2;

double dif = fabs(ro1-ro2);

if(dif < 1.0e-8)

return true;

else

return false;

}

Spróbuj użyć pierwszy wariant kodu i przeanalizuj wyniki. Później zmień na poprawny wariant kodu.

Funkcja-predykat SortDescending i funkcja porównawcza CoordCompare nie są metodami klasy coord.

Żeby kompilator był w stanie rozpoznać prototypy kontenera vector i algorytmów sort, unique,

trzeba dołożyć nagłówki

#include<vector>

#include<algorithm>

Dla rozpoznania prototypów sqrt, fabs, sin, cos - dołożyć nagłówek

#include<cmath>



Wyszukiwarka

Podobne podstrony:
5241
5241
5241
5241
5241
(5241) dl2 liczby zespolone wer do druku
5241
Projekt 2 Michal Sochon 5241 Z405 (2)

więcej podobnych podstron