13. fejezet: Tömbök gyakorlati használata példákkal

Már láttunk gyakorlatban vektorokat és mátrixokat (avagy tömböket). Némi ismétlésként tekintsük át őket!

Deklaráció: típus név [elemszám];

Minta: int akarmi [5];  // Ez egy 5-elemű, 1-dimenziójú tömböt deklarál, melynek minden eleme egész (int) lesz.

Az elemeket akár a deklaráció alkalmával is feltölthetjük. Például:

int akarmi [] = { 16, 2, 77, 40, 12071 };

Nem szabad elfelejteni, hogy az egyes elemekre hivatkozni a következőképpen lehet:

akarmi[0] // Ez lesz 16

akarmi[1] // Ez lesz 2...

 

Gyakorlati példában vegyünk fel két tömböt! Az egyikbe rakjuk bele az első 5 Árpád-házi király nevét, majd a másodikba az uralkodásuk idejét (től-ig).

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

// Árpád-házi királyok

#include <iostream>

using namespace std;

#define ELVALASZT " ----- "

int main ()

{

  // Deklarációs rész - értékadással

  string kiraly [5] = {"Szent Istvan", "Orseolo Peter", "Aba Samuel", "Orseolo Peter", "I. Andras"};

  int uralk[6][1];

  uralk[0][0]=1000;

  uralk[0][1]=1038;

  uralk[1][0]=1038;

  uralk[1][1]=1041;

  uralk[2][0]=1041;

  uralk[2][1]=1044;

  uralk[3][0]=1044;

  uralk[3][1]=1046;

  uralk[4][0]=1046;

  uralk[4][1]=1060;

  // Kiiratási rész

  cout <<"Elso 5 Arpad-hazi kiralyunk\n";

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

      {

      cout << kiraly[i] <<ELVALASZT;   //Király nevének kiírása

      cout << uralk[i][0] <<" - " <<uralk[i][1] <<"\n"; //Uralkodási évének kiírása

      }

  return 0;

}

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

 

Egyes C++ nyelvjárásokban megengedett a többszörös értékadás, tehát két változónak is ugyanazt az értéket adhatjuk, de ez sajnos itt nem lehetséges!

Ettől függetlenül érdemes megnézni a többszörös értékadás ötletét, mivel így megkíméltük magunkat attól, hogy több ugyanolyan értéket egymás után többször is be kelljen gépelnünk.

 

Kicsi kitérőként tanuljunk meg képernyőt törölni! Ehhez egy új beépülő kell, majd jöhet maga a parancs is:

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

#include <iostream>

#include <cstdlib>          // Ez lesz az új beépülő modul.

using namespace std;

int main ()

{

     system("cls");          //Ez pedig maga a képernyőtörlés.

}

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

 

Most ezt a királyos programot bővítsük annyival, hogy minden uralkodó után írassuk ki, hogy hány évig uralkodott. Ez persze csak a kiíratási részt érinti. Most csak a kiíratási részt másolom ide:

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

 // Kiíratási rész

  cout <<"Elso 5 Arpad-hazi kiralyunk\n";

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

      {

      cout << kiraly[i] <<ELVALASZT;   //Király nevének kiírása

      cout << uralk[i][0] <<" - " <<uralk[i][1] <<"\n"; //Uralkodási évének kiírása

      cout <<ELVALASZT <<"Uralkodas hossza: " <<uralk[i][1]-uralk[i][0] <<" ev.\n\n";

      }

  return 0;

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

 

Még egy csavart tegyünk bele! Ugyanis kellene az is, hogy ki uralkodott a leghosszabb ideig. Ehhez be kell vezetni még pár változót, hogy munkánkat megkönnyebbítsük. Íme az (egyik lehetséges) eredmény:

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

// Árpád-házi királyok

#include <iostream>

#include <cstdlib>

using namespace std;

#define ELVALASZT " ----- "

int main ()

{

  // Deklarációs rész - értékadással

  string kiraly [5] = {"Szent Istvan", "Orseolo Peter", "Aba Samuel", "Orseolo Peter", "I. Andras"};

  int uralk[6][1];

  int hossz[6];

  uralk[0][0]=1000;

  uralk[0][1]=1038;

  uralk[1][0]=1038;

  uralk[1][1]=1041;

  uralk[2][0]=1041;

  uralk[2][1]=1044;

  uralk[3][0]=1044;

  uralk[3][1]=1046;

  uralk[4][0]=1046;

  uralk[4][1]=1060;

 

  // Kiiratási rész

  system("cls");

  cout <<"Elso 5 Arpad-hazi kiralyunk\n";

  int legtobb;                                                // Ez legyen a leghosszabb ideig uralkodó indexe

  int leghosszabb = 0;                                        // Ennyi ideig uralkodott

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

      {

      cout << kiraly[i] <<ELVALASZT;   //Király nevének kiírása

      cout << uralk[i][0] <<" - " <<uralk[i][1] <<"\n\n"; //Uralkodási évének kiírása

      hossz[i] = uralk[i][1]-uralk[i][0];            //Uralkodás hosszának kiszámítása

      cout <<ELVALASZT <<"Uralkodas hossza: " <<hossz[i] <<" ev.\n";

      if (hossz[i]>leghosszabb)

               {

//               cout <<"\n Ez hosszabb lesz!";           //Csak a tesztelés miatt maradt benne!

               legtobb = i;

               leghosszabb = hossz[i];

               }

      }

      cout <<"\n\n Legtovabb uralkodott: " <<kiraly[legtobb];

      cout <<"\n Uralkodas hossza: " <<leghosszabb;

  return 0;

}

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

 

Ami még a vektorokhoz tartozik, azok a karakteres vektorok. Lássunk erre is egy példát!

Deklaráljuk a következő tömböt: char jenny [20];

Ez ugye egy 20-elemű vektor, melynek minden egyes tagja 1-1 karakter.

Fel lehet tölteni például a következővel:

Hello\0, ahol az egyes elemek értéke a következő lesz:

jenny[0]="H"

jenny[1]="e"

jenny[2]="l"

jenny[3]="l"

jenny[4]="o"

jenny[5]="\0"

Ez utóbbi lesz a szöveget lezáró jel, ami a rendszernek fontos. Lényeges, hogy bár mi "\0"-át látunk, ami látszólag 2 db karakternyi helyet foglal, de a rendszer ezt egyetlennek érzi!

Az előző deklarációt így is meg lehet oldani: char jenny[] = { 'H', 'e', 'l', 'l', 'o', '\0' };

Viszont ez esetben a tömb vége a \0 mutatójánál lesz, azaz 5-nél, nem pedig 20-nál.

Tudom, hogy ez egy meglehetősen bonyolult, de lesz még egyszerűbb is! Íme:

char jenny [] = "Hello";

 

Lássunk egy gyakorlati példát is! Kérjük be a felhasználó családnevét, majd egy sima üdvözlet után írjuk vissza:

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

// Karakteres tömbök használata

#include <iostream>

#include <cstdlib>

using namespace std;

int main ()

{

  char kerdes[] = "Kerem a csaladi nevet: ";

  char udv[] = "Hello, ";

  char nev [80];

  cout << kerdes;

  cin >> nev;

  system("cls");

  cout << udv << nev << "!";

  return 0;

}
---------------------------------------------

 

Vegyük észre, hogy a kiírásnál, illetve a cin-nel történő bekérésnél nem kell a zárójeleket használni!Érdemes észrevenni, hogy a rendszer igen gördülékenyen működik, ha valakinek csak egy családi neve van, mint általában. De mi van, ha a teljes nevét kérjük, ami több, mint egy tagú. Ilyenkor sajnos csak a családnevet kapjuk vissza. A probléma onnan ered, hogy a cout és (nekünk most főleg) a cin automatikusan minden egyes szó mögé tesz egy "\0" jelet, amivel lezárja az aktuális szót. Ezzel a kiírásunkat, sajnos agyoncsapja. Helyette egy apró trükköt kell alkalmazni, mégpedig egy új beépülőt is be kell vetni, ami egy új bekérési lehetőséget ad.

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

// Karakteres tömbök használata 2.

#include <iostream>

#include <cstdlib>                // Ez a képernyőtörlés miatt kell

#include <string>                 // Ez az új beépülő

 

using namespace std;

 

int main ()

{

  char kerdes[] = "Ke'rem a teljes neve't: ";

  char udvozlet[] = "Hello, ";

  string teljesnev;               // Immár szöveget kérünk, nem karaktereket

  cout << kerdes;

  getline(cin,teljesnev);         // Ez az új szöveg-bekérési eljárás

  system("cls");

  cout << udvozlet << teljesnev << "!";

  return 0;

}

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

 

 

14. fejezet: További gyakorló feladatok

Ezt a részt azoknak szántam, akik még nem biztosak a tudásukban és szeretnének még gyakorolni. Tanári tapasztalataim azt mutatják, hogy eddig a pontig viszonylag könnyű eljutni egy közepes képességű csoporttal, esetleg egy gyengével is. A csoportnak itt viszont nagyon erősen javasolt pár tudásukat megerősítő feladatot feladni. Ezek jönnek most! (Megjegyzés: a feladatok többsége némi matematikai tudást is igényel.)

 

14.1. Kérje be egy háromszög három oldalát. Jelezze, ha az adatokból nem szerkeszthető háromszög. Ha szerkeszthető, akkor számolja ki a kerületét és a területét!

Itt először is be kell kérni a három oldalt. Ez már nem okozhat gondot! (Azért ne feledkezzünk meg a megfelelő kiírásról sem.)

 

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

#include <iostream>

#include <cstdlib>                // Ez a képernyőtörlés miatt kell

#include <math.h>                 // Ez a gyökvonáshoz kell

 

using namespace std;

#define VESSZO ","

 

int main ()

{

  system("cls");

  double a,b,c;

  // Adatbekérés

  cout << "Feladat: Egy haromszog 3 oldalat bekerve dontse el, hogy szerkesztheto-e, majd ha igen, akkor szamolja ki a haromszog teruletet es keruletet!\n\n";

  cout << "Kerem az 1. oldalt! ";

  cin  >> a;

  cout << "\nKerem a 2. oldalt! ";

  cin >> b;

  cout << "\nKerem a 3. oldalt! ";

  cin >> c;

  cout << " A haromszog oldalai: " << a << VESSZO << b << VESSZO << c <<"\n";

 

  // Szerkeszthetőség bekérése

  bool szerkhet = false;   // Ez azt jelzi, hogy szerkeszthető-e a háromszög

  if ((a+b>c) and (a+c>b) and (b+c>a))

        {

             szerkhet = true;

        }

  if (szerkhet==false)

    {

        cout << "\nA haromszog nem szerkesztheto!";

    }

  else

    {

        cout << "\nA haromszog szerkesztheto!";

    }

 

  // Kerület és terület kiszámítása

  double ker, s, szamit, ter;

  ker = a+b+c;

  cout << "\nA haromszog kerulete: " << ker;

  s = ker / 2;

  szamit = s*(s-a)*(s-b)*(s-c);

  ter = sqrt(szamit);

  cout <<"\nA haromszog terulete: " << ter;

  return 0;

}

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

 

14.2. Egy kis cégnek 10 dolgozója van. Kérje be ezek havi bruttó fizetését. Számolja ki az átlagát, majd minden egyes fizetésről döntse el, hogy átlag alatti vagy feletti, esetleg megegyezik vele.

 

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

#include <iostream>

#include <cstdlib>                // Ez a képernyőtörlés miatt kell

 

using namespace std;

#define VESSZO ","

 

int main ()

{

  system("cls");

  int fizu [10];

  // Adatbekérés

  cout << "Feladat: 2.) Egy kis cégnek 10 dolgozója van. Kérje be ezek havi bruttó fizetését. Számolja ki az átlagát, majd minden egyes fizetésről döntse el, hogy átlag alatti vagy feletti, esetleg megegyezik vele.\n\n";

  for (int i=1; i<11; i++)

    {

        cout <<"\nKerem a(z) " <<i <<". dolgozo fizeteset:";

        cin >> fizu[i];

    }

  cout <<"\n\nTehat a fizetesek: ";

  for (int i=1; i<11; i++)

    {

        cout <<fizu[i] << VESSZO;

    }

 

  //Számítások

  int osszeg = 0;

  for (int i=1;i<11;i++)

    {

        osszeg = osszeg + fizu[i];

    }

  double atlag;

  atlag = osszeg / 10;

  cout <<"\nFizetesek atlaga: " <<atlag;

  for (int i=1;i<11;i++)

    {

        cout <<"\n" <<i <<". fizetes: " << fizu[i] <<"     ";

        if (fizu[i]<atlag) cout << " alacsony";

        if (fizu[i]>atlag) cout <<" magas";

        if (fizu[i]==atlag) cout <<" atlagos";

    }

  return 0;

}

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

A fenti megoldásban egyetlen kivetnivaló akad: a végén, amikor a fizetéseket összehasonlítjuk az átlaggal, akkor azt lehetne egyetlen feltétellel is megoldani...

 

14.3. A program olvasson be pozitív egész számokat addig, amíg 0-t nem kap. Írja ki a beolvasott értékek mennyiségét, átlagát és az átlagtól való eltérések átlagát!

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

#include <iostream>

#include <cstdlib>                // Ez a képernyőtörlés miatt kell

 

using namespace std;

#define VESSZO ","

#define maxx 200  // Maximum ennyi számot tárolunk.

 

int main ()

{

  system("cls");

  int beker, szamol;

  int tomb[maxx];

 

  // Adatbekérés

  cout << "Feladat: 3.) A program olvasson be pozitív egész számokat addig, amíg 0-t nem kap. Írja ki a beolvasott értékek mennyiségét, átlagát és az átlagtól való eltérések átlagát!\n\n";

  szamol = 0;

  do

    {

        szamol++;

        cout <<"Kerem a kovetkezo szamot! ";

        cin >> beker;

        tomb[szamol]=beker;

    }

  while (beker != 0);

 

  // Adatok visszaírása

  cout <<"\nA bevitt szamok: \n";

  for (int i=1; i<szamol;i++)

    {

        cout <<tomb[i] << VESSZO;

    }

 

  // Adatok feldolgozása

  double atlag, osszeg = 0;

  for (int i=1;i<szamol;i++)

    {

        osszeg = osszeg + tomb[i];

    }

  atlag = osszeg / szamol;

  cout <<"\nA bevitt szamok atlaga: " <<atlag;

  return 0;

}

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

A megoldásban egyetlen egy „trehányságot” sikerült elkövetni: van a kiírásnál egy felesleges vessző. Nos, ezt a problémát az olvasóra bízom!

 

14.4. Írja ki a program az első 20 olyan számot, amely nem osztható sem 2-vel, sem 3-mal, sem 5-tel!

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

#include <iostream>

#include <cstdlib>                // Ez a képernyőtörlés miatt kell

 

 

using namespace std;

#define VESSZO ","

 

int main ()

{

  system("cls");

  cout <<"Feladat: 4.) Írja ki a program az első 20 olyan számot, amely nem osztható sem 2-vel, sem 3-mal, sem 5-tel!";

 

  //Számolási rész

  int sz[20], szamol = 1;

  int szam = 6;  //Ezzel a számmal fogok próbálkozni, hogy megfelel-e.

  do

    {

    if ((szam % 2 == 0) or (szam % 3 == 0) or (szam % 5 == 0))

            {

             //   cout <<"\n" <<szam <<"Ez rossz!";  // Csak a tesztverzióban kellett!

            }

        else

            {

             //   cout <<"\n" <<szam <<"Ez viszont megfelel!"; //Csak a tesztverzióban kellett!

                sz[szamol] = szam;      // Itt elraktározom a következő számot

                szamol++;               // Az indexet is növelem eggyel

            }

    szam++;         // Veszem a következő számot

    }

  while (szamol<20);

 

  //Kiírási rész

  cout <<"\nA megtalalt szamok:\n";

  for (int i=1; i<20;i++)

  {

      cout <<sz[i];

      if (i<19) cout << VESSZO;     //Ezzel a megoldással sikerül elkerülni az utolsó vessző okozta problémát!

  }

  return 0;

}

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

Érdemes észrevenni, hogy ebben a verzióban maradt némi „felesleges” kiírás még a teszt-verzióból.  Ezt érdemes megszokni, mivel így a program a későbbiekben is jól érthető lesz és könnyebb felfogni a működését...

 

14.5. Egy sorozat képzési szabálya a következő: a soron következő elem legyen az előző kettő összegénél eggyel nagyobb. Írassa ki a sorozat első 20 elemét, ha az első két elem egyaránt 1.

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

#include <iostream>

#include <cstdlib>

 

 

using namespace std;

#define VESSZO ","

 

int main ()

{

  system("cls");

  cout <<"Feladat: 5.) Egy sorozat képzési szabálya a következő: a soron következő elem legyen az előző kettő összegénél eggyel nagyobb. Írassa ki a sorozat első 20 elemét, ha az első két elem egyaránt 1.";

  int sor[20];

 

  //Számolási rész

  sor[1] = 1;

  sor[2] = 1;

  for (int i=3; i<21; i++)

    {

        sor[i]= sor[i-1]+sor[i-2]+1;

    }

 

  //Kiíratás

  cout <<"\nA sorozat elemei: \n";

  for (int i=1; i<21; i++)

    {

        cout <<sor [i];

        if (i != 20) cout << VESSZO;

    }

  return 0;

}

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

 

14.6. Kérjen be egy pozitív számot. Írassa ki a szám négyzetét, négyzetgyökét, szinuszát és 10 alapú logaritmusát!

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

#include <iostream>

#include <cstdlib>

#include <math.h>           // Ez a matematikai függvények miatt kell

 

using namespace std;

#define VESSZO ","

 

int main ()

{

  system("cls");

 

  // Bekérés

  double szam;

  cout <<"Feladat: 6.) Kérjen be egy pozitív számot. Írassa ki a szám négyzetét, négyzetgyökét, szinuszát  és 10 alapú logaritmusát!";

  do

  {

        cout <<"\nKerek egy pozitiv szamot!";

        cin >> szam;

        if (szam<=0) cout <<"\nHibas szamot adott meg! Kerem ujra!\n";

  }

  while (szam<=0);

 

  //Kiíratások és számolások

  cout <<"\n\nA beadott szam: " <<szam;

  cout <<"\nNegyzete   : " <<szam*szam;

  cout <<"\nGyoke      : " <<sqrt(szam);

  cout <<"\nSzinusza   : " <<sin(szam);

  cout <<"\nLogaritmusa: " <<log10(szam);

 

  return 0;

}

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

 

14.7. Kérje be egy gömb sugarát, majd írassa ki a gömb térfogatát és felszínét!

Ez egy egyszerű matematikai művelet lesz!

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

#include <iostream>

#include <cstdlib>

#include <math.h>           // Ez a matematikai függvények miatt kell

 

using namespace std;

#define VESSZO ","

#define PI 3.1415

 

int main ()

{

  system("cls");

 

  // Bekérés

  double r;     //Ez a gömb sugara

  cout <<"Feladat: 7.) Kérje be egy gömb sugarát, majd írassa ki a gömb térfogatát és felszínét!";

  do

  {

        cout <<"\nKerek egy pozitiv szamot!";

        cin >> r;

        if (r<=0) cout <<"\nHibas szamot adott meg! Kerem ujra!\n";

  }

  while (r<=0);

 

  //Kiíratások és számolások

  cout <<"\n\nA beadott szam: " <<r;

  cout <<"\nA gomb terfogata: " <<4*r*r*r*PI/3;

  cout <<"\nA gomb felszine : " <<4*r*r*PI;

 

  return 0;

}

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

 

14.8.) Kérje be egy kocka oldalát, majd írassa ki a felszínét, térfogatát, a köré és a beleírt gömb sugarait!

Az előzőhöz hasonlóan ez is csak egy matematikai műveletsor lesz.

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

#include <iostream>

#include <cstdlib>

#include <math.h>           // Ez a matematikai függvények miatt kell

 

using namespace std;

#define VESSZO ","

 

int main ()

{

  system("cls");

 

  // Bekérés

  double a;     //Ez a kocka oldala

  cout <<"Feladat: 8.) Kérje be egy kocka oldalát, majd írassa ki a felszínét, térfogatát, a köré és a beleírt gömb sugarait!";

  do

  {

        cout <<"\nKerek egy pozitiv szamot!";

        cin >> a;

        if (a<=0) cout <<"\nHibas szamot adott meg! Kerem ujra!\n";

  }

  while (a<=0);

 

  //Kiíratások és számolások

  cout <<"\nA beadott szam       : " <<a;

  cout <<"\nA kocka terfogata    : " <<a*a*a;

  cout <<"\nA kocka felszine     : " <<6*a*a;

  cout <<"\nA beirt gomb sugara  : " <<a/2;

  cout <<"\nA koreirt gomb sugara: " <<sqrt(3)*a/2;

 

  return 0;

}

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

 

14.9.) Kérjen be két különböző pozitív egész számot, majd írassa ki a köztük lévő egészeket, azok összegét és szorzatát!

Itt egy külső eljárást is használunk cserére, ha az szükséges.

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

#include <iostream>

#include <cstdlib>

 

using namespace std;

#define VESSZO ","

 

void csere(int& x, int& y)    //Egyszerű csere

{

    double z;

    z = x;

    x = y;

    y = z;

}

 

int main ()

{

  system("cls");

 

  // Bekérés

  int a,b;     //Ez a két szám

  cout <<"Feladat: 9.) Kérjen be két különböző pozitív egész számot, majd írassa ki a köztük lévő egészeket, azok összegét és szorzatát!";

  do

  {

        cout <<"\nKerek egy pozitiv egesz szamot!";

        cin >> a;

        if (a<=0) cout <<"\nHibas szamot adott meg! Kerem ujra!\n";

  }

  while (a<=0);

  do

  {

        cout <<"\nKerek egy pozitiv egesz szamot!";

        cin >> b;

        if (b<=0) cout <<"\nHibas szamot adott meg! Kerem ujra!\n";

  }

  while ((b<=0) and (a!=b));

 

  //Kiíratások és számolások

  if (b<a) csere(a,b);          // A csere rutint előre meg kell írni!

  cout <<"\nKisebb : " <<a;

  cout <<"\nNagyobb: " <<b;

  cout <<"\nKoztuk levo egeszek: ";

  int osszeg = 0, szorzat = 1;

  for (int i=a+1; i<b;i++)

    {

        cout <<i;

        if (i<b-1) cout <<VESSZO;

        osszeg = osszeg + i;

        szorzat = szorzat * i;

    }

  cout <<"\nOsszeguk : " <<osszeg;

  cout <<"\nSzorzatuk: " <<szorzat;

  return 0;

}

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