Fizikus C++ labor

1. hét: make és C ismétlés2. hét: pontosság és pontatlanság3. hét: azonos nevű függvények, referencia
4. hét: egyszerű osztályok5. hét: konstruktor és operator overloading6. hét: osztály dinamikus adattaggal
9. hét: >> és << használata I/O-ra, statikus tagok10. hét / 1: STL vector10. hét / 2: STL string, algorithm
11. hét: generikus algoritmusok és osztályok12. hét: öröklés13. hét: heterogén kollekció
14. hét: C++11 kitekintő15. hét: Nagyházi bemutatás

8. hét: STL vector

1. feladat

Készíts egy kezdőértékekkel feltöltött double elemű tömböt, majd inicializálj ezzel egy std::vectort (intervallum konstruktor)! Kérj be a felhasználótól egy szorzót és egy eltolást (scale, offset), és változtasd meg a vektor minden elemét elem = scale * (elem - offset) módon! Írd ki a megváltoztatott vektor elemeit! A kiíráshoz/beolvasáshoz az iostreamet használd!

2. feladat

Vegyük elő a 4. ill. 5. héten használt 2D vektor osztályt! Hozz létre két, ilyen vektorokat tároló std::vector objektumot: egyet a helynek, egyet a pillanatnyi sebességnek. (Pl. std::vector<vec2D> vv;) Mindkét tároló időegységenként tárolja a számított értékeket. Ferde hajítást (ágyúlövést) számolunk Euler integrálással.

- Kérd be a felhasználótól a kilövés szögét és a kezdősebességet, valamint az időegységet (dt)! (Feltételezheted, hogy mindhárom pozitív.)

- dt lépésközzel tárold el az ágyugolyó helyét és sebességét, míg az a földbe nem csapódik!

- egészítsd ki a 2D vektor osztályt ostreamre kiíró << operátorral!

- Írd ki, hogy

-- (a) mekkora volt a golyó sebessége és távolsága a becsapódás pillanatában, és ez melyik időpillanatban történt. (Az utolsó nemnegatív magasságértékhez tartozó sebesség.) A sebesség x-y koordinátáit és abszolútértékét valamint szögét is írd ki! (Milyen érdekességet veszel érsszre a becsapódási sebesség abszolút értékében és szögében? Mi ennek a fizikai magyarázata?)

-- (b) a golyó pályájának melyik volt a legmagasabb pontja: időpont, magasság, sebesség. (Ez az a pont, ahol a hely y értéke a legnagyobb.)

-- (c) a golyó hol volt akkor, amikor sebességének szöge -45° volt, ha volt ilyen szög. (Ha pl. -44.8° és -45,1° két szomszédos eltárolt érték esetén a szög, akkor a -45.1°-ot tekitnjük -45°-nak, mert az van hozzá a legközelebb, ebben az esetben tehát van -45° a pályáján. 45 °-nál kisebb szögben kilőtt golyó esetén nem lesz ilyen.)

Gyakorló feladat

Készíts programot mérési eredmények feldolgozására!

(a) A mérési eredmények valós számok, melyek feszültségértékeket reprezentálnak, Voltban. A mérési eredményeket std::vectorban tárold! Addig olvass be értékeket a szabványos bemenetről (std::cin), míg -1000000.0-nál kisebb érték nem érkezik, mint végjel (ez nem tárolandó)!

(b) A mért értékek között néhány hibás is található, amelyek arról ismerhetők fel, hogy abszolút értékük meghaladja az összes mért érték abszolút érték átlagának tízszeresét. Hozz létre egy másik std::vectort, és ebbe másold át a jó értékeket!

(c) A mért feszültség egy DC + egy AC komponenes összege. A DC-t a (jó) mért értékek átlaga adja. Számítsd ki a DC értéket! Told el úgy a (jó) mért értékeket, hogy a vektorban az AC komponensek maradjanak (azaz minden értékből vond le a DC-t)!

(d) Írd ki a DC értéket, valamint az AC értékek abszolút értékének átlagát!

Mintamegoldások

1. feladat
#include <iostream>
#include <vector>

int main(){
    double t[10] = { 3.1, 4.8, -5.1, 7.9, 5.0, 0.0, -2.2, 9.9, 5.0, -6.0 };
    std::vector<double> v(t,t+10);
    std::cout << v.size() << std::endl;
    double scale, offset;
    std::cout << "scale offset: "
    std::cin >> scale >> offset;
    for (int i = 0; i < v.size(); i++)
        v[i] = scale*(v[i] + offset);
    for (int i = 0; i < v.size(); i++)
        std::cout << v[i] << std::endl;
    return 0;
}

 

2. feladat
#include <iostream>
#include <vector>
#include <cmath>

class vec2D{
    double x, y;
public:
    vec2D(double x = 0, double y = 0) :x(x), y(y){}
    double getX()const{ return x; }
    double getY()const{ return y; }
    double getR()const{ return sqrt(x*x + y*y); }
    double getPhi()const{ return atan2(y, x); }
    void setXY(double x, double y){ this->x = x; this->y = y; }
    void setRPhi(double r, double phi){ x = r*cos(phi); y = r*sin(phi); }
    vec2D operator+(const vec2D &v)const
        { return vec2D(getX() + v.getX(), getY() + v.getY()); }
    const vec2D& operator+=(const vec2D &v)
        { setXY(getX() + v.getX(), getY() + v.getY()); return *this; }
    vec2D operator*(double d)const{ return vec2D(getX()*d, getY()*d); }
};

inline vec2D operator*(double d, const vec2D &v){
    return v*d;
}

std::ostream &operator<<(std::ostream &os, const vec2D &v){
    os << '(' << v.getX() << ", " << v.getY() << ')';
    return os;
}

int main(){
    std::vector<vec2D> pv, vv;
    vec2D a(0, -9.81), v, p;
    double r, phi, dt;
    const double pi = acos(0) * 2;

    // Adatok bekérése

    std::cout << "v0= "; 
    std::cin >> r;
    std::cout << "szog(fokban)= ";
    std::cin >> phi;
    phi *= pi / 180;
    std::cout << "dt= ";
    std::cin >> dt;

    // Euler integrálás
    
    v.setRPhi(r, phi);
    while (p.getY() >= 0){
        vv.push_back(v);
        pv.push_back(p);
        p = pv.back() + vv.back()*dt; // vagy p += v*dt;
        v = vv.back() + a*dt;         // vagy v += a*dt;
    }

    // Sebesség becsapódáskor (a)

    std::cout << "Sebesseg a becsapodaskor (t = " << vv.size()*dt
        << "):\n\t" << vv.back() << " absz: " << vv.back().getR() << " szog: " 
        << vv.back().getPhi()*180 / pi << ", helye: " << pv.back().getX() << std::endl;

    // A pálya legmagasabb pontja (b)

    int i;
    for (i = 1; i < pv.size() && pv[i].getY() >= pv[i - 1].getY(); i++)
        ;
    std::cout << "A palya legmagasabb pontja:\n\tt = " << (i - 1)*dt 
        << ", y = " << pv[i - 1].getY() << ", v = " << vv[i - 1] << std::endl;

    // -45° (c)

    const double minusznegyvenotfok = -45 * pi / 180;
    if (vv.back().getPhi() > minusznegyvenotfok)
        std::cout << "A sebessegvektor a palya egyetlen pontjan sem -45 fok" << std::endl;
    else{
        for (i = vv.size() - 1; i >= 0 && vv[i].getPhi() < minusznegyvenotfok; i--)
            ;
        if (i > 0){
            if (fabs(vv[i - 1].getPhi() - minusznegyvenotfok) 
                < fabs(vv[i].getPhi() - minusznegyvenotfok))
                i--;
            std::cout << "A golyo koordinatai, amikor -45 fok a sebessegenek a szoge:\n\t" 
                << pv[i] << std::endl;
        }
        else
            std::cout << "Hibas parameterek alapjan nem tudok szamolni." << std::endl;
    }
    return 0;
}