Informatică, întrebare adresată de DC2002, 8 ani în urmă

Este săptămâna formelor geometrice la grădiniţă. Astăzi copiii au învăţat să deseneze pătrate, dreptunghiuri şi cercuri. Bineînţeles că apare competiţia: cine poate desena cea mai mare formă geometrică? Doamna educatoare este arbitrul şi trebuie să stabilească cine este câştigătorul. O puteţi ajuta?

Cerințe pentru punctaj maxim
Să se creeze o clasă cu numele Shape cu următoarele specificații:
- clasa trebuie să conțină 2 atribute protected numite mShape și mArea, primul de tip string, iar al doilea număr fracționar pe simplă precizie;
- clasa trebuie să fie abstractă. Abstractizarea se va face prin crearea a 2 metode publice pur virtual numite print și calculateArea. Aceste metode nu vor returna nimic și nu primesc niciun parametru;
- clasa trebuie să conțină o metodă publică fără niciun parametru numite getArea. Aceasta trebuie să întoarcă valoarea atributului mArea. Tipul de dată returnat al metodei trebuie să îl deduceți voi.

Să se creeze o clasă cu numele Square cu următoarele specificații:
- clasa trebuie să fie moștenită din clasa Shape;
- clasa trebuie să conțină un atribut private numit mLength, de tip fracționar pe simplă precizie;
- clasa trebuie să conțină un constructor public cu un singur parametru care să inițializeze atributul mLength cu valoarea specificată. De asemena, se va seta valoarea atributul mShape cu textul "patrat";
- clasa trebuie să implementeze metodele pur virtuale din clasa de bază. Astfel, metoda print va afișa datele în conformitate cu spusele din cerință, iar metoda calculateArea va calcula aria figurii, iar rezultatul se va stoca în atributul mArea.

Să se creeze o clasă cu numele Rectangle cu următoarele specificații:
- clasa trebuie să fie moștenită din clasa Shape;
- clasa trebuie să conțină 2 atribute private numite mLength și mWidth, ambele de tip fracționar pe simplă precizie;
- clasa trebuie să conțină un constructor public cu 2 parametrii care să inițializeze atributele mLength și mWidth cu valoarea specificată. De asemena, se va seta valoarea atributul mShape cu textul "dreptunghi";
- clasa trebuie să implementeze metodele pur virtuale din clasa de bază. Astfel, metoda print va afișa datele în conformitate cu spusele din cerință, iar metoda calculateArea va calcula aria figurii, iar rezultatul se va stoca în atributul mArea.

Să se creeze o clasă cu numele Circle cu următoarele specificații:
- clasa trebuie să fie moștenită din clasa Shape;
- clasa trebuie să conțină un atribut private numit mRadius, de tip fracționar pe simplă precizie;
- clasa trebuie să conțină un constructor public cu un singur parametru care să inițializeze atributul mRadius cu valoarea specificată. De asemena, se va seta valoarea atributul mShape cu textul "cerc";
- clasa trebuie să implementeze metodele pur virtuale din clasa de bază. Astfel, metoda print va afișa datele în conformitate cu spusele din cerință, iar metoda calculateArea va calcula aria figurii, iar rezultatul se va stoca în atributul mArea. Se foloseste "M_PI" din biblioteca "cmath".

ATENȚIE! Cele 3 clase trebuie să aibă definite și un constructor cu 0 parametrii care să inițializeze toate atributele cu valoarea 0, iar atributul mShape cu textul "nedefinit".


Cerinţă
Stabiliţi ierarhia formelor geometrice, ordonându-le după suprafață, de la cea mai mare la cea mai mică.

Date de intrare
Se vor citi de la tastatură (fluxul stdin) următoarele date:
o valoare întreagă N reprezentând numărul de forme geometrice intrate în competiţie, urmată de caracterul newline (tasta Enter);
N linii, fiecare linie conţinând numele formei geometrice („patrat”, „dreptunghi”, „cerc”) şi informaţiile despre aceasta (lungimea laturii pentru pătrate, lungimile laturilor pentru dreptunghiuri, raza cercului pentru cercuri), în următorul format:
patrat
cerc
dreptunghi
Entităţile componente ale liniilor sunt separate printr-un spaţiu, ca în exemplul dat în final. Fiecare dintre cele N linii reprezentând rezultate este urmată de caracterul newline (tasta Enter).

Date de ieşire
Programul va afişa pe ecran (stream-ul standard de ieşire) informaţiile despre forme, în acelaşi format în care au fost introduse şi datele de intrare ordonate după arie, de la cea mai mare la cea mai mică.

Restricţii şi precizări
Numărul de forme geometrice, N, este un număr întreg între 1 şi 100.
Denumirea formelor geometrice va fi („patrat”, „dreptunghi” sau „cerc”).
Lungimile laturilor şi razele sunt numere reale, între 0 şi 1000, cu exact 2 zecimale.
Suprafaţa formelor geometrice este: Sp atrat =L2,S dreptu nghi =L1⋅L2, Scerc =πR2 Spatrat=L2,Sdreptunghi=L1⋅L2,Scerc=πR2
Exemplu
Intrare

6
patrat 2.10
dreptunghi 1.20 7.90
cerc 3.11
patrat 4.40
dreptunghi 9.10 0.40
patrat 1.50
Ieșire

cerc 3.11
patrat 4.40
dreptunghi 1.20 7.90
patrat 2.10
dreptunghi 9.10 0.40
patrat 1.50

Răspunsuri la întrebare

Răspuns de andrei750238
3

#include <iostream>

#include <iomanip>

#include <string>

#include <vector>

#include <algorithm>

using namespace std;

class Shape {

protected:

std::string mShape;

float mArea;

public:

virtual void print() = 0;

virtual void calculateArea() = 0;

float getArea() {

 return mArea;

}

};

class Square :public Shape {

private:

float mLength;

public:

Square() {

 mShape = "nedefinit";

 mLength = 0;

 mArea = 0;

}

Square(float _mLenght) {

 mShape = "patrat";

 mLength = _mLenght;

 calculateArea();

}

void calculateArea() {

 mArea = mLength * mLength;

}

void print() {

 std::cout << std::fixed << std::setprecision(2) << mShape << " " << mLength << std::endl;

}

};

class Rectangle :public Shape {

private:

float mLength, mWidth;

public:

Rectangle() {

 mShape = "nedefinit";

 mLength = 0;

 mWidth = 0;

 mArea = 0;

}

Rectangle(float _mLen, float _mWid) {

 mLength = _mLen;

 mWidth = _mWid;

 mShape = "dreptunghi";

 calculateArea();

}

void calculateArea() {

 mArea = mLength * mWidth;

}

void print() {

 std::cout << std::fixed << std::setprecision(2) << mShape << " " << mLength << " " << mWidth << std::endl;

}

};

class Circle :public Shape {

private:

float mRadius;

public:

Circle() {

 mShape = "nedefinit";

 mRadius = 0;

 mArea = 0;

}

Circle(float _mRad) {

 mShape = "cerc";

 mRadius = _mRad;

 calculateArea();

}

void print() {

 std::cout << std::fixed << std::setprecision(2) << mShape << " " << mRadius << std::endl;

}

void calculateArea() {

 mArea = 3.14159265358979323846 * mRadius * mRadius;

}

};

//Clasa comparator

class comp_shape {

public:

inline bool operator()(Shape* a, Shape* b) {

 return a->getArea() > b->getArea();

}

};

int main() {

int n;

std::vector<Shape*> v;

std::string nume;

float p1, p2;

std::cin >> n;

v.resize(n);

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

 std::cin >> nume;

 if (nume == "patrat") {

  std::cin >> p1;

  v[i] = new Square(p1);

 }

 else if (nume == "dreptunghi") {

  std::cin >> p1 >> p2;

  v[i] = new Rectangle(p1, p2);

 }

 else {

  std::cin >> p1;

  v[i] = new Circle(p1);

 }

}

//Sortare dupa arie

std::sort(v.begin(), v.end(), comp_shape());

//Afisare solutie

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

 v[i]->print();

}

//Dealocare memorie

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

 delete v[i];

}

}

Anexe:
Răspuns de Apollyon
3

Shape.h

#pragma once

#include <string>

using std::string;

class Shape

{

protected:

   string _mShape;

   float _mArea;

public:

   virtual void print() = 0;

   virtual void calculateArea() = 0;

   Shape(string mShape);

   float getArea() const;

};

Shape.cpp

#include "Shape.h"

Shape::Shape(string mShape)

   : _mShape(mShape) {}

float Shape::getArea() const

{

   return this->_mArea;

}

------------------------------------------------------------------------------------

Square.h
#pragma once

#include "Shape.h"

class Square : public Shape

{

private:

   float _mLength;

public:

   Square();

   Square(float);

   void print();

   void calculateArea();

};

Square.cpp

#include <iostream>

#include "Square.h"

using std::string, std::cout, std::endl;

Square::Square()

   : Shape("nedefinit"), _mLength(0) {}

Square::Square(float mLength)

   : Shape("patrat"), _mLength(mLength) {}

void Square::calculateArea()

{

   this->_mArea = this->_mLength * this->_mLength;

}

void Square::print()

{

   cout << this->_mShape << " " << this->_mLength << endl;

}

------------------------------------------------------------------------------------

Rectangle.h

#pragma once

#include "Shape.h"

class Rectangle : public Shape

{

private:

   float _mLength, _mWidth;

public:

   Rectangle();

   Rectangle(float, float);

   void print();

   void calculateArea();

};

Rectangle.cpp

#include <iostream>

#include "Rectangle.h"

using std::cout, std::endl;

Rectangle::Rectangle()

   : Shape("nedefinit"), _mLength(0), _mWidth(0) {}

Rectangle::Rectangle(float mLength, float mWidth)

   : Shape("dreptunghi"), _mLength(mLength), _mWidth(mWidth) {}

void Rectangle::calculateArea()

{

   this->_mArea = this->_mLength * this->_mWidth;

}

void Rectangle::print()

{

   cout << this->_mShape << " " << this->_mLength << " " << this->_mWidth << endl;

}

------------------------------------------------------------------------------------

Circle.h

#pragma once

#include "Shape.h"

class Circle : public Shape

{

private:

   float _mRadius;

public:

   Circle();

   Circle(float);

   void print();

   void calculateArea();

};

Circle.cpp

#include <iostream>

#define _USE_MATH_DEFINES

#include <cmath>

#include "Circle.h"

using std::cout, std::endl;

Circle::Circle()

   : Shape("nedefinit"), _mRadius(0) {}

Circle::Circle(float mRadius)

   : Shape("cerc"), _mRadius(mRadius) {}

void Circle::calculateArea()

{

   this->_mArea = M_PI * (this->_mRadius * this->_mRadius);

}

void Circle::print()

{

   cout << this->_mShape << " " << this->_mRadius << endl;

}

------------------------------------------------------------------------------------

Main.cpp

#include <iostream>

#include <memory>

#include <vector>

#include <algorithm>

#include "Square.h"

#include "Rectangle.h"

#include "Circle.h"

using std::cout, std::cin, std::endl, std::vector, std::unique_ptr;

static void creareVector(vector<unique_ptr<Shape>> &vectorForme, const int &numarForme)

{

   string tipForma;

   for (int i = 0; i < numarForme; i++)

   {

       cout << "Introdu tipul formei >> ";

       cin >> tipForma;

       if (tipForma == "patrat")

       {

           float lungimeSquare;

           cout << "Introdu lungimea >> ";

           cin >> lungimeSquare;

           vectorForme.push_back(unique_ptr<Square>(new Square(lungimeSquare)));

       }

       if (tipForma == "dreptunghi")

       {

           float lungimeDreptunghi, latimeDreptunghi;

           cout << "Introdu lungimea si latimea >> ";

           cin >> lungimeDreptunghi >> latimeDreptunghi;

           vectorForme.push_back(unique_ptr<Rectangle>(new Rectangle(lungimeDreptunghi, latimeDreptunghi)));

       }

       if (tipForma == "cerc")

       {

           float razaCerc;

           cout << "Introdu raza cercului >> ";

           cin >> razaCerc;

           vectorForme.push_back(unique_ptr<Circle>(new Circle(razaCerc)));

       }

   }

}

int main()

{

   int numarForme;

   vector<unique_ptr<Shape>> vectorForme;

   cout << "Cate forme vrei sa creezi ? >> ";

   cin >> numarForme;

   creareVector(vectorForme, numarForme);

   vectorForme[0]->print();

   for (auto &figura : vectorForme)

       figura->calculateArea();

   std::sort(vectorForme.begin(), vectorForme.end(), [](const unique_ptr<Shape> &figura1, const unique_ptr<Shape> &figura2)

             { return figura1->getArea() > figura2->getArea(); });

   cout << endl;

   for (auto &figura : vectorForme)

       figura->print();

   return 0;

}

Alte întrebări interesante