Upload failed. Maybe wrong permissions?

User Tools

Site Tools



11. Tömbök

11-0.jpg
  

27:41
1985. március 27.
MTV 2. csatorna, 19:30

Bevezető

11-1.jpgPinkert László Commodore 64
  0:36 Eddigi adásaink során számos feladatot megoldottunk már, vagyis számos programot készítettünk. Ilyen programok voltak a lóerő–kilowatt átszámítás, átlaghőmérséklet-számítás, rajzoltunk szalagnaptárt a képernyőre, illetve házikót vonalakból. Ezek a programok meglehetősen egyszerűek voltak – például három szám átlagának a számításához nincs szükség feltétlenül számítógépre –, azonban a célunk az volt, hogy megismerjük a BASIC nyelv utasításkészletét. Most egy igazi számítógépes feladat következik. Egy sportversenyre látogatunk el, ahol száz versenyző áll rajthoz, és a feladat az, hogy tartsuk nyilván számítógéppel a versenyzők nevét, illetve eredményeit. Az eredményeket a verseny során tetszőleges sorrendben lehessen beírni a programba. A program a verseny végén készítsen egy listát, amely az eredmények sorrendjében megállapítja a helyezéseket. Ezt a feladatot a valóságban is számítógéppel oldják meg, ismerhetjük a televízió sportközvetítéseiből, hogy egy-egy versenyen épp csak földet ér a gerely vagy a súlygolyó, és a számítógép máris képernyőre írja a pillanatnyi sorrendet.
  11-2.jpgTehát egy olyan eredményt szeretnénk kapni, ami itt a képernyőn látható: helyezés, név és pontszám feltüntetése. Természetesen a pontszámok csökkenő sorrendjében.
  A program nemcsak azért bonyolult, mert száz nevet és száz eredményt kell tárolni, hanem azért is, mert a számítógépnek kell tudnia, hogy például ahhoz a változóhoz, hogy Kiss József – ugye ez egy egyszerű szöveges változó –, ehhez az a szám tartozik, hogy 380. Vagyis a változókat valamilyen sorrendben kell a memóriában elhelyezni, hogy később könnyű legyen hivatkozni rájuk.

Tömbök

11-3.jpgKiss Donát Spectrum
  2:36 Ilyen és ehhez hasonló feladatok megoldására agyalták ki a BASIC-ben a tömböket. Tulajdonképpen a tömbök azonos nevű változókból állnak. Hogy mégis meg tudjuk őket különböztetni, ezért rájuk különböző indexek segítségével, számok segítségével hivatkozunk. Egy egydimenziós tömb esetében egy számmal, kétdimenziós tömb esetében két számmal és így tovább. Nézzünk talán először példát az egydimenziós, legegyszerűbb tömbökre. Mik alkothatnak egy ilyen egydimenziós tömböt? Hát például a különböző hónapok napjainak a száma. Ez nem más, mint egy jó kis, tizenkét elemből álló tömb, egydimenziós tömb, melyben az első tömbelem 31, mivelhogy január harmincegy napból áll, a második 28 ugye, többnyire, majd 31, 30, és így tovább. Mondjuk ez lesz a H tömb, és ily módon mondjuk a június napjainak a számára úgy hivatkozhatunk, hogy a H(6)-os elemet kérdezzük le vagy szorozzuk be vagy íratjuk ki vagy teszünk vele, amit akarunk. Ugyanis a tömbelemeket pontosan ugyanúgy kezelhetjük, mint a változókat. Olyannyira, hogy a szöveges változóknak megfelelően szöveges tömbök is léteznek. Például egy egydimenziós szöveges tömb – amelyet hasonlóképpen a változókhoz a dollárjellel különböztetünk meg a numerikus tömböktől – például lehetnek a hét napjainak a nevei egy hételemű szöveges tömb (elemei – L. A. D.), melyben ugye az első elem az, hogy hétfő, maga ez a betűkombináció, második az, hogy kedd, és így tovább.
  11-4.jpgA kétdimenziós tömbökhöz nyúljunk vissza a sublótunkhoz. Nézzük meg ismét ezt a sublótot. Ugye azt mondottuk a változóknál, hogy a sublótban fiókok vannak, és egy-egy fiók egy-egy változónak felel meg, vagyis hogyha kihúzzuk a fiókját és abba valamilyen értéket teszünk, akkor a későbbiekben arra hivatkozhatunk. Most tekintsünk egy-egy ilyen fiókot oly módon, hogy rekeszekkel felbontottuk mondjuk sorokra és oszlopokra. Vagyis felülnézetből egy kétdimenziós, 5·5-ös tömb a következőképpen néz ki.
  

11-5.jpg11-6.jpg

  
11-7.jpg11-8.jpg

  Hát hogy mégis mik ezek a sorok és oszlopok… mondjuk a sorok azok tanulók, mivel az osztályból öten készülnek felvételizni, ily módon az oszlopok pedig a felvételi tárgyak, hogyha öt van. Amit itt látunk, az a következő. A gép rajzolt nekünk öt sort és öt oszlopot, és minden elem helyére tett egy nullát. Azt is látjuk, hogy a végrehajtott utasítás ebben az esetben az a bizonyos DIM f(5,5) volt. Ez azt jelenti, hogy dimenzionáltuk a tömböt, illetve definiáltuk a tömböt evvel a dimenzionáló utasítással. Ezt minden olyan program elején meg kell tenni, amelyben tömböket óhajtunk használni: meg kell adjuk, hogy hány sorból és hány oszlopból álljon ez a tömb, s ennek hatására a program helyet foglal a gép memóriájában ennek számára, és mindegyik helyre beír egy nullát. Na most ennyire azért nem tanulnak rosszul a gyerekek, úgyhogy mondjuk a kettes sorba – ami Kovács Gézának feleljen meg –, a hármas oszlopba – ami mondjuk a biológia jegye – hát adjunk egy négyest neki biológiából, ez így történik.
  
11-9.jpg11-10.jpg

  
11-11.jpg11-12.jpg

  Azt is látjuk, hogy ebben az esetben a végrehajtott utasítás az, hogy LET f második sor harmadik eleme – ez a bizonyos két index – egyenlő 4. Ez ugye azt jelenti, hogy pontosan ugyanazt az értékadó utasítást használtuk itt, mint az egyszerű változóknál. Vagyis valóban igaz az az állítás, hogy a tömbelemeket ugyanúgy használhatjuk, mint a változókat: műveletekbe ágyazhatjuk őket, kifejezésekben felhasználhatjuk, beszorozhatjuk, kiírathatjuk… elronthatjuk. Tehát mindent megtehetünk vele, amit általában a változókkal.
  6:53 Na most ha visszatérünk még egy pillanatra a sublóthoz, akkor a sublót még tulajdonképpen képes érzékeltetni a háromdimenziós tömböket. Ugyanis ha azt képzeljük el, hogy mindegyik fiók pontosan ugyanígy néz ki, akkor tulajdonképpen a harmadik dimenzió az az, hogy éppen melyik fiókot húzom ki. A zoknisat, az alsóneműset, a harisnyásat. Vagyis ez egy harmadik index. Nos, a négydimenziós tömbök érzékeltetésére már semmiképpen sem vállalkoznék, ezt ugyanis már elég nehéz elképzelni, azonban a BASIC nyelvben – és általában minden BASIC-ben – korlátozás nélkül lehet használni a dimenziókat, tehát definiálhatunk akár százdimenziós tömböt is, erre azonban általában bonyolult tudományos számításokat végző programoknál kerül csak sor. (A tömbök méretének azonban határt szab a memória mérete és a programsorok hosszúsági korlátja; a legtöbb gépen egy programsor hosszabb lehet, mint amennyi a képernyő egy sorába kifér, de nem bármilyen hosszú. – L. A. D.)

Áttekintés

11-13.jpgHerneczki Katalin Primo
  7:47 Ha egy igazi programot írunk, természetesen nem gondolhatunk mindig a sublótra, illetve annak fiókjaira. Ezért most összefoglaljuk röviden, hogy mit tudunk a tömbökről, hogyan és hol kell ezeket definiálni a programban. Célszerű mindjárt a program elején definiálni a tömböket, de feltétlenül a felhasználást megelőzően. Egy tömb definiálására a DIM utasítás szolgál. Ez egyébként az angol dimension szó rövidítése, amely kiterjedést, méretet jelent. Nézzünk egy példát rá. DIM, tehát a helyfoglalás kulcsszava, ezt követi a tömb neve… ez most legyen A, majd egy zárójel következik, és a zárójelben pedig egész számokat sorolunk fel.
  11-14.jpgA tömbünk annyi dimenziós, ahány egész számot felsoroltunk, tehát ebben a példában háromdimenziós. Az egyes számok jelentése pedig a tömb mérete az adott dimenzióban. Ebben az esetben egy 2·3·5-ös tömbről van szó, ez azt jelenti, hogy a tömb harmincelemű. (Primón a tömbök indexelése 0-val kezdődik és a megadott számnál eggyel kisebb indexig tart, vagyis az itt megadott tömb első eleme (0, 0, 0), az utolsó pedig (1, 2, 4). – L. A. D.) Egyébként ezek a számok azt is megmutatják, hogy mi az a maximális, tehát legnagyobb index, amelyet használhatunk a tömbre való hivatkozásnál. Meg is nézzük, hogy valóban így van-e ez, egy PRINT utasítással. Tehát PRINT A, és kipróbáljuk mondjuk a 3, 4, 6-tal.
  11-15.jpg
  Hibajelzést kaptunk, tehát valóban igaz volt az, amit az előbb említettünk.
  Nos, a DIM utasítással tömböt definiálunk, de nemcsak olyan tömböt definiálhatunk, amely számértékeket tartalmaz, hanem olyat is definiálhatunk, amelynek elemei szövegek, szöveges változók. Ilyen esetben, teljesen hasonlóan a változók definíciójához, egy dollárjelet kell írni a tömb neve után. Ezt is megmutatjuk: tehát DIM, mondjuk B a tömb neve, dollár, mert szöveges változókról van szó, és aztán a definíció többi része az teljesen hasonló a nem szöveges tömbökhöz.
  11-16.jpg
  Megengedett az is, hogy egy DIM utasítással több tömböt definiáljunk. Erre is mutatunk egy példát. DIM, mondjuk C a tömb neve, 2·3-as a tömb. A definíciókat egymástól vesszővel kell elválasztani, tehát vessző karakter, D tömb, zárójel és X, Y.
  11-17.jpg
  Nos, itt álljunk meg egy pillanatra, hiszen ilyet még nem láttunk. Nem számérték van, hanem egy X és egy Y változónév a tömb definíciójánál. Ez is megengedett, természetesen ez a változó a programban valahol majd értéket kell hogy kapjon. És befejezzük a sort mondjuk egy szöveges változóval, legyen ez az E$, zárójel, 2·5-ös mondjuk a tömb.
  11-18.jpg

A nyilvántartó eleje

11-19.jpgPinkert László Commodore 64
  11:11 Miután megismerkedtünk a tömbökkel, hozzákezdhetünk az eredmény-nyilvántartó program elkészítéséhez. Nézzük meg röviden, hogy milyen programrészletek megírására lesz szükség. Először, amint láttuk, helyet kell foglalni az adatok számára. Másodszor egy előkészítő részt kell, hogy írjunk, amelyben a verseny előtt beírjuk a gép memóriájába a versenyzők neveit. A verseny közben már csak az eredményeket fogjuk beírni; itt a nevek helyett a versenyzők azonosítására rajtszámot használunk majd. Ezek után következik a rendezés a verseny végén: az eredmények csökkenő sorrendjében kell a neveket és az eredményeket sorba rendezni és kiírni a képernyőre. Nézzük meg most az ennek megfelelő programrészletet.
  Tehát adunk egy címet a programnak: Eredmény-nyilvántartás. Ezek után következik egy utasítás, amellyel megkérdezzük azt, hogy hány versenyző indul, vagyis mennyi a résztvevők száma, hogy csak annyi helyet foglaljunk a programban, amennyi szükséges. Egy V változóban helyezzük el. Ezt a V változót használjuk aztán a DIM utasításban. Az N$ tömb fogja tárolni a versenyzők neveit, az E tömb pedig számokat: az eredményeket. Ezek után át is térhetünk a következő részre, az előkészítésre. Névbeírás – kiírjuk a képernyő felső sarkába –, és következik egy ciklus, amely annyiszor fut le, ahány versenyző van. Mindannyiszor – egy üres sor kihagyása után – kiírjuk az aktuális rajtszámot, vagyis az R-et, és megkérjük, hogy írja be a gép kezelője az ehhez tartozó nevet. A névbeírás után ismét visszaugrunk a ciklus elejére. Megfigyelhetjük itt a 60-as sorban, hogy a név már az R-rel jelzett tömbelembe kerül. Vagyis amely a versenyző rajtszáma.
  Ezek után következik a verseny. Az eredményeket kell beírni. Ezt ki is írjuk a képernyő fölső sorába majd kihagyva egy üres sort következik egy beviteli utasítás, ahol megkérdezzük az eredményt, de nemcsak az eredményt, hanem a rajtszámot is, hiszen tudni kell, hogy az eredményt az eredménytömbnek melyik elemébe helyezzük el. Ezt fogja azonosítani a rajtszám. Tehát rajtszámot és eredményt várunk, a rajtszám az R változóba kerül, majd mindjárt utána az eredmény az E-nek az R-edik elemébe. Ezt a lépést annyiszor kell ismételni, ahányszor a verseny során az eredmények felújítására szükség van; mivel azonban szeretnénk a géppel valamilyen módon közölni, hogy a versenynek vége, kérjük az eredményt, ezt itt a legegyszerűbben úgy tehetjük meg, hogy az R változóba, vagyis rajtszámként nullát adunk meg. Tehát egy olyan feltétellel fogjuk a programot folytatni, hogy csak akkor ugorjon vissza a 120-as sorra, akkor várjon újabb eredményeket, amennyiben az R nem volt nulla. Ha az R nulla volt, akkor következik az eredmények sorbarendezése. A sorbarendezés azonban nem egy egyszerű programrészlet, ehhez már szükség van a megfelelő matematikai algoritmus ismeretére és megértésére.

A tornasor rendezése

11-20.jpgHerneczki Katalin Commodore 64
  15:04 Nézzük most meg a rendezés egyik igen gyakran használt s egyben legegyszerűbb módját egy köznapi példán. Az iskolában az év eleji tornaórák többnyire azzal kezdődnek, hogy a tornatanár nagyság szerinti sorba állítja a gyerekeket. A tavalyi tornasor általában már nem megfelelő, hiszen a nyáron a gyerekek megnőttek és nem egyforma mértékben. Mit lehet ilyenkor tenni? Felállítja a régi tornasort, aztán az első gyereket összehasonlítja a másodikkal. Ha az első nagyobb, mint a második, a helyén marad. Ha viszont a második a nagyobb, akkor a gyerekek helyet cserélnek. Aztán a második és a harmadik gyereket hasonlítja össze. Ha a harmadik nagyobb, akkor egy hellyel előrébb kerül, a második pedig egy hellyel hátrább. És ez egészen így folytatódik, amíg a sor végére nem érnek. Ez persze nem azt jelenti, hogy most már mindenki a megfelelő helyre került. Hiszen lehet, hogy az utolsó gyerek magasabb, mint az utolsó előtti, tehát egy hellyel előrébb került, de ez nem azt jelenti, hogy ő nem magasabb a tornasorban korábbi helyen álló gyerekeknél. Tehát lehet, hogy jóval előrébb kellene kerülnie a sorban.
  

11-21.jpg11-22.jpg

  
11-23.jpg11-24.jpg

  
11-25.jpg11-26.jpg

  
11-27.jpg11-28.jpg

  
11-29.jpg11-30.jpg

  Ezért újból folytatjuk ezt az eljárást elölről. Aztán ezt egészen addig kell folytatni, amíg mindenki a megfelelő helyre kerül. Tornaórán természetesen ez ránézéssel megállapítható, hogy mikor van vége a rendezésnek, látszik a soron, hogy mindenki a helyén van-e. Programozásban ez nem ennyire egyszerű, hiszen valami módon jelölnünk kell azt, hogy történt-e csere (ti. a sor legutóbbi végignézése során – L. A. D.) vagy nem. Hiszen akkor van vége a rendezésnek, amikor már egyetlenegy csere sem történt.

Rendezés

11-31.jpgPinkert László Commodore 64
  16:42 Nézzük meg most, hogy a megismert algoritmust hogyan lehet használni az eredmény-nyilvántartó programban. A programnak a rendezés részével foglalkozunk tehát, amely egy értékadással kezdődik, ennek a céljára majd a későbbiekben visszatérünk. A programrészlet lényege ez a ciklusutasítás, 220-tól a 280. sorig. A ciklusváltozó, I kettőtől V-ig változik. Nem egytől tehát, nem annyiszor fut le a ciklus, ahány versenyző van, hanem eggyel kevesebbszer, hiszen ha V versenyző indul, akkor V eredmény van, és V eredményt ha összehasonlítunk, akkor azt csak V–1-szer lehet megtenni. Vagy ha ez túl bonyolultan hangzott, akkor nézzük meg az első utasítást. Ebben szerepel az, hogy hasonlítsuk össze az I–1. eredményt az I. eredménnyel. Ebből is látszik, hogy nem lehet egytől indítani a ciklust, hiszen akkor nem lehetne az I–1. eredményről beszélni. Röviden tehát: a 230-as sorban összehasonlítunk két, a tömbben egymás mellett helyet foglaló eredményt. Amennyiben az előrébb álló – ez az I–1. – nagyobb, mint az őt követő, akkor nem csinálunk semmi egyebet, mint elugrunk a ciklus végére, a 280-as utasításra. Ha azonban ez a reláció nem igaz, akkor a két eredményt föl kell cserélni. Ezt láthatjuk a következő három sorban a bal oldali utasításokon. Először is az I. eredményt elmentjük egy M munkaváltozóba, majd a helyére betöltjük az I–1. eredményt. Végül az I–1-re visszatöltjük az M-ben eltárolt értéket. Ugyanezt meg kell tenni a nevekkel is, hiszen amennyiben az eredményeket összecserélgettük, akkor már nem lesz igaz az, hogy ahányadik a tömbelem a sorban, annyiadik rajtszámú versenyzőhöz tartozik. Tehát a neveket is fölcserélgetjük, teljesen hasonló módon, csak vigyázni kell arra, hogy itt a munkaváltozó természetesen szöveges változó legyen. Következik ennek a rendezési algoritmusnak a leglényegesebb lépése, az, hogy amennyiben cserére volt szükség, vagyis találtunk két olyan elemet, amelyek nem álltak rendezetten, akkor a C-be egyet írunk. Amennyiben ez a ciklus egyszer lefutott és végigcserélgette vagy nem cserélgette az egymás mellett álló elemeket, megnézzük, hogy ez a C változó milyen értéket képvisel. Amennyiben nulla, ez azt jelenti, hogy végignéztük az elempárokat és egyetlenegyszer sem volt szükség rendezésre, ez tehát azt jelenti, hogy a rendezés elkészült, minden elem a megfelelő helyre került. Amennyiben a C-nek egyes értéke van, akkor pedig azt jelenti, hogy szükség volt rendezésre, és ezért tovább folytatjuk, még egyszer megismételjük a rendezést, vagyis ez a sor visszaugrat oda, hogy a C-t nullázzuk – tehát ezért volt szükség erre a sorra – és megismételjük a ciklust. Térjünk vissza tehát a 290-es sorra: ha a C-ben nullát találunk, akkor továbblépünk. Következik a kiírás.
  20:26 A kiírás a képernyő törlésével kezdődik és egy fejléccel. Három oszlopot fogunk a képernyőre írni: a helyezéseket – ezek számok lesznek nyilván –, a nevet és a pontszámot, eredményt. A kiírást természetesen ciklus végzi, ahol az R, vagyis a helyezések száma egytől V-ig változik. Sorközöket hagyunk ki a versenyzők eredményei között, és egy hosszú PRINT utasítást használunk egy sornak a kiírására, amelyben egyrészt szerepel az R, vagyis a helyezési szám, aztán egy tabulátor, hogy rendezett legyen a képernyőn a megjelenítés. Következik az R. név, ismét egy tabulátor, és az R. eredmény. A ciklust egy megfelelő cikluszáró utasítással zártuk le.
  Nézzük meg most a program működését.
  11-32.jpg
  A résztvevők számát kell megadni. Kevés versenyzőnk van, öt.
  11-33.jpg
  Már írhatjuk is a neveket. Az egyszerűség kedvéért most csak keresztneveket fogok írni. Természetesen hölgyversenyzők is vannak.
  

11-34.jpg11-35.jpg

  Készen vagyunk, kezdődhet az eredmények beírása. Az első versenyző mondjuk 120 pontot szerzett, a második 230-at, és így tovább, a harmadiknak 100 pontja van, a negyediknek 80, az ötödiknek legyen mondjuk 300.
  11-36.jpg
  Látható, hogy az ötödik után még újabb eredményeket vár a program, hiszen úgy írtuk meg, hogy tetszés szerint lehessen folytatni az eredmények beírását, vagyis ha valamelyik versenyző javított az eredményén, akkor ez felülírja az előzőt. Tehát például a négyes kijavította gyenge 80 pontos eredményét, mondjuk 250-re. Ha ezek után a versenynek vége van és szeretnénk az eredményeket látni, akkor 0 rajtszámot kell begépelni, azonban be kell gépelni a másik nullát is, hiszen az INPUT utasítás csak akkor működik megfelelően, hogyha annyi számot adunk meg, ahányat vár.
  11-37.jpg
  Nézzük meg most, máris a képernyőn van az eredménylista, az eredmények megfelelő sorrendben. Most persze emlékezni kellene arra, hogy melyik névhez milyen eredményt írtam be, de azt hiszem, elhihetjük, hogy a program helyesen működik.
  11-38.jpg

Torpedó

11-39.jpgHerneczki Katalin Commodore 64
  23:43 Az előbbi feladatunkban ismertetett rendezési módszer jól működött, de meglehetősen lassú. Nagyszámú adat esetén bizony ez nem elég hatékony módszer. Ezért javasoljuk, hogy szorgalmi feladatként gondolják át, hogyan lehetne számokat sorbarendezni ennél gyorsabb, hatékonyabb módszerrel.
  Gondolom, mindnyájan szeretnek játszani. És talán az iskolában a pad alatt vagy a jobbak az óraközi szünetben biztosan játszottak már torpedójátékot. Ezt úgy kellett játszani, hogy egy tízszer tízes táblázatot rajzoltunk és ebbe valahol el kellett helyezni egy alakzatot. Mi egy ötelemű alakzatot rajzoltunk. Aztán célozni kellett az alakzat egyes elemeire, és ez addig tartott, amíg mindent eltaláltunk, vagyis amíg a torpedó elsüllyedt. Nos, erre írtunk egy programot is, amit most meg fogunk nézni. Következő adásunkban egyébként a játékprogramokkal fogunk foglalkozni, és ott részletesen ismertetjük a feladatot, s utána játszunk is vele. Most csak azt nézzük meg, hogy hogyan kell ezt a táblázatot előállítani.
  11-40.jpg
  A feladat neve Torpedó, első része pedig a táblakészítés. Először is egy 10·10-es tömböt kell itt definiálnunk, mégpedig egy szöveges tömböt, hiszen pontokat szeretnénk a tömbben elhelyezni. (Ez a tömb valójában 11·11-es, mert Commodore-on a nullás indexek is léteznek, de a program nem fogja használni őket. – L. A. D.) Aztán következik egy képernyőtörlés, és utána pedig a tömbben el kell helyezni a pontokat. Ezt két ciklussal tudjuk elérni, mégpedig két egymásba ágyazott ciklussal. Ha jól megnézzük, akkor ez a 100-tól a 140-ikig tartó sorokban történik. A külső ciklusban az I változó 1-ről indul, a belső ciklusban pedig egy J változót találunk. Ez a két ciklus úgy működik, hogy először az I értéke 1, közben pedig a J értéke 1-től 10-ig tart. A következő utasítás a ciklus magja, amely tulajdonképpen elhelyezi a pontokat. (Vagyis „ . ” írásjeleket – L. A. D.)
  Vagyis először az első sor első tíz elemébe helyezi el a pontokat. Ezután az I értéke kettőre változik, aztán a J értéke megint 1-től 10-ig szalad. És így tovább, ez addig tart, amíg mind a száz elembe a pont belekerül. Ne felejtsük el azt, hogy ez egy nagyon fontos utasítás, hiszen minden esetben kétdimenziós tömböket ilyen jellegű utasítással lehet feltölteni.
  Következő adásunkban elhelyezzük az alakzatot, és utána pedig játszani fogunk a torpedójátékkal. Viszontlátásra.
  26:41