Személyes eszközök
Keresés

 

A InfoWiki wikiből

A lap korábbi változatát látod, amilyen WikiSysop (vita | szerkesztései) 2009. november 12., 10:22-kor történt szerkesztése után volt.
(eltér) ←Régebbi változat | Aktuális változat (eltér) | Újabb változat→ (eltér)


Felvezetés

Tudunk olyan programot írni, amely előre ismert mennyiségű adatot kér be. Például bekérhetünk 32 darab érdemjegyet, és megállapíthatjuk az osztály átlagát. Bekérhetünk egy háromszöghöz tartozó három oldal hosszát, és meghatározhatjuk a kerületet.

Ciklusok nélkül azonban nehéz (illetve lehetetlen) olyan programokat írni, amelyek előre (a program írásakor) nem ismert mennyiségű adattal is képesek dolgozni. Lehet az előbb ismertetett osztályátlag számoló programozási problémát úgy megoldani, hogy induláskor bekérjük hány fős az osztály, és megírunk mondjuk maximum 40 adatbekérést szekvenciában, elágazásokkal megoldva, hogy 40-nél kevesebb fő esetén bizonyos adatbekérések ne hajtódjanak végre. De a program szövegében véges sok adattal dolgozunk.

Ciklusok segítségével azonban ezek a korlátok ledönthetőek, tetszőlegesen sok adattal is tudunk dolgozni. Egyszerűbb esetben a program elején bekérhetjük hogy hány darab adatunk van - majd azokat sorban egyesével bekérhetjük. Nem sokkal bonyolultabb az a megoldás, amikor az elején nem kérjük be az adatok számát, de egy előre egyeztett végjel bevitelével jelzi a program kezelője, hogy nincs tovább adat. Ezen végjel kiválasztásnál ügyelni kell, hogy valami olyan érték legyen, amely közönséges esetben nem fordulhat elő az adatok között (pl. hőmérséklet-értékek beírásakor a -1000 érték lehet ilyen, mert a fizika jelen állása szerint ez a hőmérsékletérték nem fordulhat elő).

Később, ha a tömb és lista fogalmakat is megismertük, a sok adattal történő munkálkodást újra fogjuk tárgyalni. Ezek segítségével a beírt adatokat össze is tudjuk gyűjteni, és később tetszőleges sokszor egyesével újra és újra feldolgozni, elemezni. Jelen esetben az összegyűjtés nélkül kell tudnunk megoldani a felmerülő problémákat.

Két fontos, és egyszerűen kezelhető problémát kell tudnunk megoldani:

  • megszámlálás: meg kell számolni, a beírt adatok között hány adat volt. A jó adat a konkrét feladat

szövegében kerül ismertetésre: pl. a beírt hőmérséklet adatok közül hány volt a fagypont alatti. Ekkor a adat a negatív adat.

  • eldöntés: el kell dönteni, hogy a beírt adatok közül volt-e valamilyen, általunk keresett adat (pl. volt-e

negatív érték).

Az eldöntési kérdés megoldható a megszámlálás alkalmazásával is. Megszámolhatjuk hány negatív érték volt a beírt adatok között, majd a darabszám ismeretében választ adhatunk arra a kérdésre, hogy volt-e vagy sem keresett adat. Ugyanakkor megoldható célirányosabban is, ezért ezt tárgyaljuk külön is.

N darab adat bekérése

Amikor választható az a mód, hogy megkérdezhetjük a program kezelőjét, hogy az elején adja meg hány darab adattal kell dolgozni, akkor alkalmazhatjuk ezt a módszert.

Console.WriteLine("Hány adatról van szó?");
int n = int.Parse( Console.ReadLine() );
int i=1;
while (i<=n)
{
  Console.WriteLine("Kérem az {0}. adatot",i);
  int x = int.Parse( Console.ReadLine() );
  // ...
  // az x adat feldolgozása
  // ...
  i = i+1;
}


Min látjuk, első lépésben bekérjük az n változóba az adatok darabszámát. Segédváltozónkat, az i értékét induláskor 1-re állítjuk, és a ciklusmag minden végrehajtásában, a ciklus minden menetében növeljük 1-el. Amennyiben n értéke pl. 10, és i=1-ről indulunk, akkor a ciklus pontosan tízszer hajtódik majd végre, i=1,2,3,...,10 esetekre (ezt biztosítja az i<=n feltétel).

Az n és i értékei ezért csak azt vezérlik, hányszor hajtódjon végre a ciklusmag, a ciklus érdemi része. A komment jelek között jeleztük, hogy ide kerül az algoritmus változó része, ami attól függ, mi a konkrét feladat.

Végjelig bekérés

Amennyiben nem ismert előre az adatok mennyisége, más (bár hasonló) módszert kell alkalmazni a megoldáshoz. Tételezzük fel, hogy a végjel a korábban említett -1000 lesz. Kérjünk be addig adatokat, amíg ezzel a számmal nem találkozunk:

int x;
do
{
  Console.WriteLine("Kérem a következő adatot");
  x = int.Parse( Console.ReadLine() );
  if (x!=-1000)
  {
    // ...
    // az x adat feldolgozása
    // ...
  }
}
while (x!=-1000);

A megoldásban látszik, hogy a ciklusmagban a bekérést követően azonnal megvizsgáljuk, hogy végjelet írtak-e be, hogy az x adat feldolgozása csak akkor következzen be, ha nem végjelről van szó. A ciklus feltételét is ehhez kötjük, addig kell ismételni, amíg a beírt adat nem a végjel.

Azért tértünk át hátultesztelős ciklusra, mert

  • egyrészt egy adatot mindenképpen be kell kérni (még ha az rögtön a végjel is)
  • nem tudjuk az x értékét a ciklus fejében elől vizsgálni, ha az adatbekérés még

nem történt meg (első menet esetén)

Vegyük ezen felül észre, hogy az int x deklarációt kimozgattuk a cikluson kívülre. Ennek oka, hogy az x változóra korábban csak a ciklusmagon belül (hatáskörén belül) hivatkoztunk, de jelen esetben a ciklusmagon kívül, a ciklus vezérlő feltételében is tesszük ezt. Az x deklarációja amennyiben a ciklusmagon belül maradna, a ciklusmagot záró kapcsos zárójel jelentené a hatáskörének végét.


Összegzés N darab adatra

Amennyiben a konkrét feladat úgy szól, hogy kérjünk be N darab adatot, és számoljuk ki ezen adatok összegét, a hiányzó rész az algoritmusban kitölthető:

Console.WriteLine("Hány adatról van szó?");
int n = int.Parse( Console.ReadLine() );
int i=1;
int sum = 0;
while (i<=n)
{
  Console.WriteLine("Kérem az {0}. adatot",i);
  int x = int.Parse( Console.ReadLine() );
  sum = sum + x;
  i = i+1;
}
Console.WriteLine("A számok összege={0}",sum);

Ebben a megoldásban egy sum segédváltozót használunk, amelyet induláskor 0-val töltünk fel. Majd minden egyes bekért adatot ehhez a gyűjtőváltozó aktuális értékéhez adunk hozzá, így benne folyamatosan gyűlnek az addig beírt értékek összegei. Amikor a ciklus véget ér, az addig beírt számok összege van a sum változóban, ezt írjuk ki a képernyőre.


Összegzés végjelig

Amennyiben végjelig történik a bekérés, a megoldás akkor is ugyanezen az elven nyugszik:

int sum = 0;
int x;
do
{
  Console.WriteLine("Kérem a következő adatot");
  x = int.Parse( Console.ReadLine() );
  if (x!=-1000)
  {
    sum = sum + x;
  }
}
while (x!=-1000);
Console.WriteLine("A számok összege={0}",sum);

Eldöntés N darab adatra

A probléma: adott n darab adat, el kell dönteni hogy ezek között szerepel-e egy adott tulajdonsággal rendelkező adat. Példa: az osztály tanulói 32 fizika érdemjegye között szerepel-e 5-ös érdemjegy.

Console.WriteLine("Hány adatról van szó?");
int n = int.Parse( Console.ReadLine() );
int i=1;
bool szerepel=false;
while (i<=n)
{
  Console.WriteLine("Kérem az {0}. adatot",i);
  int x = int.Parse( Console.ReadLine() );
  if (x==5) szerepel=true;
  i = i+1;
}
if (szerepel) Console.WriteLine("szerepel");
else Console.WriteLine("nem szerepel");

A megoldásban egy logikai változót használtunk, melynek kezdő értékét hamis (false) értékre állítjuk be. Amennyiben nem találunk keresett elemet a bekért adatok között, úgy ez a kezdő érték nem változik meg, vagyis helyesen szerepel==false módon zárul a működés. Ha bármelyik (akár több) adat is megfelel a kívánalmaknak (egyenlő 5-el), akkor a szerepel változó értéke felveszi az igaz (true) értéket, és a továbbiakban marad is ebben az állapotában.


Eldöntés végjelig

A probléma ugyanaz, csak nem ismert előre az adatok mennyiség. A megoldás módja is ugyanaz.

bool szerepel=false;
do
{
  Console.WriteLine("Kérem a következő adatot");
  x = int.Parse( Console.ReadLine() );
  if (x!=-1000)
  {
	  if (x==5) szerepel=true;
  }
}
while (x!=-1000);
if (szerepel) Console.WriteLine("szerepel");
else Console.WriteLine("nem szerepel");
Hernyák Zoltán
A lap eredeti címe: „http://wiki.ektf.hu/wiki/Mp1/page310
Nézetek
nincs sb_3.145.119.199 cikk