Egymásba ágyazott struktúrák

Egymásba ágyazott struktúrák

Egy struktúra valamely adattagja lehet struktúra típusú is (amíg nincsenek önhivatkozások).

Pl. háromszögek tárolása, egy háromszög kerülete és területe

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <iostream>
#include <fstream>
#include <cmath>
using namespace std;

struct Pont
{
    double x, y;
};

struct Haromszog
{
    Pont a, b, c;
};

double tav(Pont p1, Pont p2)
{
    double dx = p1.x - p2.x;
    double dy = p1.y - p2.y;

    return sqrt(dx*dx + dy*dy);
}


double kerulet(Haromszog h)
{
    return tav(h.a, h.b)
        + tav(h.a, h.c)
        + tav(h.b, h.c);
}

double terulet(Haromszog h)
{
    double o1 = tav(h.a, h.b);
    double o2 = tav(h.a, h.c);
    double o3 = tav(h.b, h.c);
    double p = (o1+o2+o3)/2;

    return sqrt(p*(p-o1)*(p-o2)*(p-o3));
}


int main()
{
    Haromszog h { {1,2}, {3,7}, {-2, 0} };

    cout << kerulet(h) << endl;
    cout << terulet(h) << endl;

    return 0;
}

HF

Az alkalmazottas példában, legyen mindenkinek születési dátuma (év, hónap, nap). Kell beolvasás, kiírás, rendezés dátum szerint.

Példa-bemenet:

    3
    Setőfi Pándor  1823 01 01    10000
    Edy Andre      1877 02 13    2000
    Ristiano Chron 1985 12 31    99999
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#include <iostream>
#include <fstream>
using namespace std;

struct Datum
{
    int ev, ho, nap;
};

struct Alkalmazott
{
    char vezeteknev[30];
    char keresztnev[30];
    Datum szul_datum;
    int fizetes;
};

bool kisebb(Datum x, Datum y)
{
    /*
    if (x.ev < y.ev) return true;
    else if (x.ev > y.ev) return false;

    if (x.ho < y.ho) return true;
    else if (x.ho > y.ho) return false;

    return x.nap < y.nap;
    */

    return x.ev < y.ev
        || (x.ev == y.ev && x.ho < y.ho)
        || (x.ev == y.ev && x.ho == y.ho && x.nap < y.nap);

}


void rendez(int n, Alkalmazott t[])
{
    for (int i = 0; i < n; i++)
        for (int j = i+1; j < n; j++)
            if (kisebb(t[j].szul_datum,t[i].szul_datum)) {
                Alkalmazott seged;
                seged = t[i];
                t[i] = t[j];
                t[j] = seged;
            }
}



int main()
{
    ifstream fin("input.txt");
    int n;
    fin >> n;

    Alkalmazott t[100];

    for (int i = 0; i < n; i++)
    {
        fin >> t[i].vezeteknev
            >> t[i].keresztnev
            >> t[i].szul_datum.ev
            >> t[i].szul_datum.ho
            >> t[i].szul_datum.nap
            >> t[i].fizetes;
    }

    rendez(n, t);

    for (int i = 0; i < n; i++)
    {
        cout << t[i].vezeteknev << " "
            << t[i].keresztnev << " "
            << t[i].szul_datum.ev << " "
            << t[i].szul_datum.ho << " "
            << t[i].szul_datum.nap << " "
            << t[i].fizetes << endl;
    }

    return 0;
}

Gyakorlat

Tároljunk releváns adatokat egy labdáról, majd írjunk függvényt, amely eldönti, hogy két labda azonos színű-e!

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <iostream>
#include <fstream>
#include <cstring>
using namespace std;

struct Labda
{
    char szin[10];
    double ar;
    int sorszam;

};

bool azonosszinuek(Labda x,Labda y)
{
   /* if (strcmp(x.szin, y.szin)==0)
        return true;

    else
        return false;*/

    return strcmp(x.szin, y.szin) == 0;
}


int main()
{
    Labda x{"piros", 10, 1};
    Labda y{"zod", 20, 2};

    if(azonosszinuek (x, y))
        cout<<"azonos" << endl;
    else
        cout<<"nem azonos" << endl;

    // y.szin <- "sarga"
    strcpy(y.szin, "sarga");
    strcpy(x.szin, "sarga");

    if(azonosszinuek (x, y))
        cout<<"azonos" << endl;
    else
        cout<<"nem azonos" << endl;


    return 0;
}

Strúktúra definiálása egy másik struktúrában

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <iostream>
using namespace std;

struct Haromszog
{
    struct Pont  // el is lehet hagyni
    {            // a nevet, ekkor később
                 // nem vehetünk fel új pontokat
        double x, y;
    } A, B, C;

    char szin[50];
};

/* 
// ha elhagyjuk a belső struktúra nevét:

struct Haromszog
{
    struct 
    {
        double x, y;
    } A, B, C;

    char szin[50];
};
*/


int main()
{
    Haromszog h;
    h.A.y = 3;

    // Pont p; - error
    // Haromszog::Pont p; - ok

    return 0;
}

Gyakorlatok:

    s=0;
    for(i=0; i<15; i++){
        s+=t[i].nrLocuri*t[i].pret;
    }
    a[0].dp.anNastere = 2000;
    a[0].venit = 4000;
        struct epoca
        {
            int anFabricatie;
            struct
            {
                int zi;
                char luna[16];
            } expo;
        } m;

Feladat:

Szeretnénk tárolni információkat intervallumokról.

a) Írjunk megfelelő struktúrát és jelentsük be az x változót úgy, hogy az alábbi kifejezés az x intervallum hosszát adja meg:

    x.veg - x.kezd

Megoldás:

    struct Intervallum
    {
        double kezd, veg;
    } x;

b) írjunk függvényt, ami két intervallumról eldönti, hogy van-e közös elemük (minden intervallumot zártnak tekintünk)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
    bool vankozos(Intervallum a, Intervallum b)
    {
        // return ! (diszjunktak)

        return ! (
            (a.veg < b.kezd)
            || (b.veg < a.kezd)
        );

        /* vagy (ekvivalens átalakításokkal):
            !(a.veg < b.kezd) && !(b.veg < a.kezd)
            a.veg >= b.kezd && b.veg >= a.kezd
        */
    }

Feladat:

Tároljunk információkat egy egyenes álllású téglalapról (olyan téglalap, aminek oldalai párhuzamosak a koordinátatengelyekkel):

Észrevétel: akkor van átfedés, ha az oldalak által meghatározott x-intervallumok és y-intervallumok között is van átfedés egyidőben.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <iostream>
using namespace std;

struct Pont { double x, y; };

struct Intervallum { double kezd, veg; };

struct Teglalap
{
    Pont balfelso, jobbalso;
};

bool vankozos(Intervallum a, Intervallum b)
{
    return ! (
        (a.veg < b.kezd)
        || (b.veg < a.kezd)
    );
}

// Van-e átfedés a téglalapok között?
bool atfed(Teglalap t1, Teglalap t2)
{
    Intervallum t1x { t1.balfelso.x, t1.jobbalso.x };
    Intervallum t2x { t2.balfelso.x, t2.jobbalso.x };

    Intervallum t1y { t1.jobbalso.y, t1.balfelso.y };
    Intervallum t2y { t2.jobbalso.y, t2.balfelso.y };

    return vankozos(t1x, t2x) && vankozos(t1y, t2y);
}

int main() {

    return 0;
}

Átírás egyetlen feltétellé:

        vankozos(t1x, t2x) && vankozos(t1y, t2y)
    <=>
        ! (t1.jobbalso.x < t2.balfelso.x || t2.jobbalso.x < t1.balfelso.x)
        && ! (t1.balfelso.y < t2.jobbalso.y || t2.balfelso.y < t1.jobbalso.y)
    <=>
        t1.jobbalso.x >= t2.balfelso.x && t2.jobbalso.x >= t1.balfelso.x
        && t1.balfelso.y >= t2.jobbalso.y && t2.balfelso.y >= t1.jobbalso.y

A másik ötlet, amiről szó volt:

Szerkesszük meg t1-ben az átlók metszéspontját (jel. M). Ekkor

    M.x = (t1.balfelso.x + t1.jobbalso.x) / 2
    M.y = (t1.jobbalso.y + t1.balfelso.y) / 2

Növeljük meg a másik téglalapot úgy, hogy a szélességéhet adjuk hozzá az egyik téglalap szélességének a felét (mindkét oldalon), a magasságához pedig a magasságának felét (alul és felül is). Ekkor kapunk egy t3 téglalapot, melyre:

    t3.balfelso.x = t2.balfelso.x - (t1.jobbalso.x - t1.balfelso.x) / 2
    t3.jobbalso.x = t2.jobbalso.x + (t1.jobbalso.x - t1.balfelso.x) / 2
    
    t3.balfelso.y = t2.balfelso.y + (t1.balfelso.y - t1.jobbalso.y) / 2
    t3.jobbalso.y = t2.jobbalso.y - (t1.balfelso.y - t1.jobbalso.y) / 2

Megnézzük, hogy az M pont benne van-e az új téglalapban:

        t3.balfelso.x <= M.x <= t3.jobbalso.x 
        && t3.jobbalso.y <= M.y <= t3.balfelso.y

Behelyettesítve azt kapjuk, hogy:

        t3.balfelso.x <= (t1.balfelso.x + t1.jobbalso.x) / 2 <= t3.jobbalso.x
        && t3.jobbalso.y <= (t1.jobbalso.y + t1.balfelso.y) / 2 <= t3.balfelso.y
    <=>
        t2.balfelso.x - (t1.jobbalso.x - t1.balfelso.x) / 2 
            <= (t1.balfelso.x + t1.jobbalso.x) / 2 
            <= t2.jobbalso.x + (t1.jobbalso.x - t1.balfelso.x) / 2 
        && t2.jobbalso.y - (t1.balfelso.y - t1.jobbalso.y) / 2 
            <= (t1.jobbalso.y + t1.balfelso.y) / 2 
            <= t2.balfelso.y + (t1.balfelso.y - t1.jobbalso.y) / 2
    <=>
        t2.balfelso.x 
            <= (t1.balfelso.x+t1.jobbalso.x)/2 + (t1.jobbalso.x-t1.balfelso.x)/2
            <= t2.jobbalso.x + (t1.jobbalso.x - t1.balfelso.x)
        && t2.jobbalso.y
            <= (t1.jobbalso.y+t1.balfelso.y)/2 + (t1.balfelso.y-t1.jobbalso.y)/2
            <= t2.balfelso.y + (t1.balfelso.y - t1.jobbalso.y)
    <=>
        t2.balfelso.x 
            <= t1.jobbalso.x
            <= t2.jobbalso.x + (t1.jobbalso.x - t1.balfelso.x)
        && t2.jobbalso.y
            <= t1.balfelso.y
            <= t2.balfelso.y + (t1.balfelso.y - t1.jobbalso.y)
    <=>
        t2.balfelso.x <= t1.jobbalso.x
        && t1.jobbalso.x <= t2.jobbalso.x + (t1.jobbalso.x - t1.balfelso.x)
        && t2.jobbalso.y <= t1.balfelso.y
        && t1.balfelso.y <= t2.balfelso.y + (t1.balfelso.y - t1.jobbalso.y)
    <=>
        t2.balfelso.x <= t1.jobbalso.x
        && t1.balfelso.x <= t2.jobbalso.x
        && t2.jobbalso.y <= t1.balfelso.y
        && t1.jobbalso.y <= t2.balfelso.y

Ugyanahhoz a feltételhez jutottunk.

Feladat:

https://www.pbinfo.ro/probleme/3164/qclasa

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#include <iostream>
#include <fstream>
using namespace std;

ofstream kimenet("qclasa.out");

struct Elev
{
    int kod,atlag,hianyzas;
};

bool elorebb(Elev d1, Elev d2)
{
    /*
    if (d1.hianyzas > d2.hianyzas)
        return true;

    if (d1.hianyzas < d2.hianyzas)
        return false;

    return d1.kod < d2.kod;
    */

    return d1.hianyzas > d2.hianyzas
        || (d1.hianyzas == d2.hianyzas
            && d1.kod < d2.kod);
}


void kiir(Elev d)
{
    kimenet << d.kod << " " << d.atlag << " "
         << d.hianyzas << endl;
}


int main()
{
    ifstream be("qclasa.in");
    int n;
    be>>n;
    Elev t[40];
    for(int i=0; i<n; i++)
    {
        be>>t[i].kod
          >>t[i].atlag
          >>t[i].hianyzas;
    }
    int d=0;
    for(int i=0; i<n; i++)
    {
        if (t[i].atlag==10) d++;
    }
    kimenet<<d<<endl;
    int s=0;
    for(int i=0; i<n; i++)
    {
        s=s+t[i].atlag;
    }
    kimenet<<s/n<<endl;

    Elev max1 {-1,-1,-1}, max2 {-1,-1,-1};

    for(int i=0; i<n; i++)
    {
        if(elorebb(t[i], max1))
        {
            max2=max1;
            max1=t[i];
        }
        else if(elorebb(t[i],max2))
        {
            max2=t[i];
        }

    }

    kiir(max1);
    kiir(max2);

    return 0;
}