Fibonacci-sorozat

Fibonacci nap

Fibonacci napMa van (november 23.) a Fibonacci nap (újra). Fibonacci középkori matematikus volt, ő tette közismertté a Fibonacci-sorozat-ot. A (0), 1, 1, 2, 3, 5, 8, 13, 21, 34, sorozat igen népszerű azok közében is, akik programozást tanulnak. A sorozat első két eleme 1 és 1 (ha szükséges, akkor nulladik elemmel is dolgozhatunk), és minden további elem az előző két elem összege.

Korábban is blogoltak a kollégáim a témában:

Következzen most az én öt különböző megoldásom Java forráskódja, rövid magyarázattal. Mindegyik a Fibonacci-sorozat első tíz elemét állítja elő.

1. megoldás

Az első megoldás generikus listát épít. Az első két elemet elhelyezi a lista elején ( list.add(1)). Ezek a lista nulladik és első elemei lesznek. Ezután a metódus a maradék 8 elemmel 2-től n-1-ig fiktív indexként hivatkozva az előző két elem összegeként ( list.get(i-1)+list.get(i-2)) index nélkül bővíti a listát.

2. megoldás

A második megoldás a tipikusan nem hatékony rekurzív módszert implementálja. A rekurzív fib() függvény a sorozat egyetlen elemét adja vissza, amit (a függvényt) a ciklus sokszor meghív ahelyett, hogy a ciklus vagy a rekurzió „emlékezne” az előző elemekre.

3. megoldás

A harmadik megoldás funkcionális nyelvi elemeket (Stream API) használ. A folyamba kétdimenziós tömbre történő hivatkozással ( f-> new int[] ), közvetlen hozzárendeléssel/leképezéssel ( map()), kerülnek be a sorozat elemei.

4. megoldás

A negyedik megoldás a Fibonacci-számok zárt alakját használja. Másképpen ez a Binet-formula:

Ezzel a képlettel a sorozat elemei közvetlenül megadhatók, azaz nem szükséges más elemekre való hivatkozás. A ciklus adja meg, hogy a sorozat 1-10-ig indexelt elemei szükségesek.

5. megoldás

Az ötödik megoldás szintén Stream API-t használ. Először előállít egy sorozatot 1-10-ig, amiket a leképezésnél ( map()) inputként használ és alkalmazza rájuk a Binet-formulát. Hagyományos ciklus utasítás nem szükséges.

Eredmény

Mindegyik megoldás a konzolra írja szövegesen az eredményt, azaz a Fibonacci-sorozat első tíz elemét: 1, 1, 2, 3, 5, 8, 13, 21, 34, 55. Érdemes elemezni a hatékonyság klasszikus három szempontja (időigény/lépésszám, tárigény, bonyolultság) alapján a különböző megoldásokat. Ezek mérésével könnyen kiegészíthetők a fenti metódusok, vagy az azokat meghívó osztályban a vezérlés.

A bejegyzéshez tartozó teljes forráskódot ILIAS e-learning tananyagban tesszük elérhetővé tanfolyamaink résztvevői számára.

A feladat a Java SE szoftverfejlesztő tanfolyam szakmai moduljának 9-12. óra: Metódusok, rekurzió és 17-28. óra Objektumorientált programozás alkalmaihoz kötődik.

Tankocka – Rövid válasz: Java konstansok

Folytatjuk Tankockák blog bejegyzés sorozatunkat. A feladatban 12 db Java konstans értékét kell megadni, számként. Ez a témakör főként a Java SE szoftverfejlesztő tanfolyamunkhoz kötődik. Hasznos ismerni a JDK-beli konstansokat, mert alapvetően befolyásolják egy adatszerkezet, objektum működését, viselkedését akkor is, ha külön nem adjuk meg a létrehozó konstruktorok meghívásakor minden paramétert.

A konstansok hathatnak a memóriafoglalásra, a grafikus komponensek megjelenésre, Meghatározhatják a hálózati kommunikáció időzítését, paraméterezhetik a fájlkezelés működését. Egy-egy algoritmus (például: rendezés, keverés, véletlenszám-generálás) indítását, működését is befolyásolják a konstansok. Vajon hányat tudsz az alábbi konstansok közül? Hogyan, mire hatnak ezek?

Táblázatos komponens testreszabása

táblázat logo

táblázat logoA Java programozási nyelv egyik ismert GUI csomagja a swing. Ennek népszerű grafikus komponense az adatok táblázatos megjelenítését biztosító JTable komponens. A táblázatos megjelenítéshez több beállítás is szükséges. A JTable egy MVC komponens, így külön kezelendők a modell, nézet és a vezérlő funkcióihoz kötődő beállítások. A modell tárolja az adatokat például DefaultTableModel típusú objektumban, amiben szétválaszthatók a fejlécben és a többi cellákban található adatok. A nézethez tartozik a betűméret, a cellák színezése, az adatok igazítása, megjelenítése, a gördítősáv. A viselkedést, a felhasználói reakciót a vezérlő határozza meg, például rendezés, görgetés, fókusz, kijelölés, oszlopok sorrendjének cseréje.

Feladat

Készítsünk olyan Java swing-es kliensprogramot, amely tetszőleges adatforrásból (XML vagy JSON a hálózatról, JDBC adatbázis kapcsolatból, ORM leképzésből származó objektumokból) képes az átvett adatok grafikus felületen való táblázatos megjelenítésére JTable komponenssel! Építsünk arra, hogy az adatokon kívül metaadatok is rendelkezésünkre állnak! A megoldás legyen univerzális!

Képernyőképek

OracleHR képernyőkép

Modell

A táblázatos GUI komponenst kezdetben inicializálni kell, illetve a benne tárolt adatok is törölhetők, ha újrahasznosításra kerül a sor:

Ki kell nyerni a tároláshoz és a megjelenítéshez kötődő adatokat (1. lépés). A metaadatokból a for() ciklus előállítja az oszlopTomb-öt, és az oszlopTipusTomb-be kerülnek az Oracle adattípusból Java objektumtípusként megfeleltetett adatok. Előbbi a fejléc feliratainak szövegeit tartalmazza, és az utóbbi befolyásolja az egyes cellákban az igazítást, illetve hatással van adott oszlop rendezésére is:

Ki kell nyerni a tároláshoz és a megjelenítéshez kötődő adatokat (2. lépés). A while() ciklus végigjárja az eredménytábla sorait és Object típusú tömböt állít elő az összetartozó rekord mezőiből. Ezek először generikus listába kerülnek, majd onnan kétdimenziós Object típusú tömbbe:

Mi indokolja a tömbökből álló generikus lista ( adatLista) alkalmazását?

A while() ciklus végrehajtása előtt nem tudjuk lekérdezni, hogy mennyi rekordot kaptunk vissza, így nem tudjuk rögtön az adatTomb-be tenni az adatokat. A Java nyelvben a tömbök mérete fix, és a deklaráció során meg kell adni. Az eredménytábla metaadatai között megtalálható a mezők száma, ami felhasználható a kétdimenziós tömb oszlopszámaként. A generikus lista dinamikus, annyi elemből fog állni, ahány lépésben végrehajtódik a while() ciklus. Ezután a listától lekérdezhető az elemszáma ( adatLista.size()), és ezzel megvan a kétdimenziós tömb sorainak száma, ami eddig hiányzott. Persze használhatnánk Vector-t is a tömbökből álló generikus lista helyett (mert a DefaultTableModel-nek van olyan túlterhelt konstruktora, ami átvenné paraméterként), de ezt inkább nem tesszük, hiszen a Vector már régóta obsolete kollekció.

Előállítjuk a vizuális komponens mögötti adatmodellt. Öröklődéssel kiegészítjük két hasznos függvénnyel, így cellák rajzolása/renderelése és rendezése megkaphatja a szükséges adattípust ( getColumnClass()), valamint letiltható a cellák szerkeszthetősége ( isCellEditable()). Utóbbiak inkább a vezérléshez kötődnek, de modellen keresztül itt és így kell beállítani:

Végül a vizuális komponens mögötti adatmodellt kell átadni:

Nézet

Adott betűtípus, betűstílus és betűméret használható a táblázat fejlécében, celláiban, illetve a betűmérettől függhet a sorok magassága:

Hasznos ha JScrollPane típusú gördítősáv tartozik a táblázathoz, így dinamikusan megjeleníthető/elrejthető a függőleges/vízszintes gördítősáv:

Vezérlés

Az adatokhoz valahogyan hozzá kell jutni. Most JDBC kapcsolatot használunk és az Oracle HR sémából kérdezünk le adatokat, de a forráskód-részlet univerzális. A folyamat a következő:

  • Betöltjük a driver osztályt.
  • Autentikációval c kapcsolatot nyitunk az adatbázis-szerver felé.
  • Végrehajtjuk a lekérdező SQL parancsot.
  • Feldolgozzuk az eredményül kapott ResultSet típusú rs objektumot.
  • Végül lezárjuk a c hálózati kapcsolatot.

Ha engedélyezzük, akkor a megjelenő táblázat fejlécében az egyes oszlopok felirataira kattintva elérhetjük, hogy az adott oszlop típusának megfelelően növekvő vagy csökkenő sorrendbe átrendeződjenek az adatok:

A kivételkezelést nem részleteztük a fenti forráskódoknál, de természetesen kötelezően adott.

A bejegyzéshez tartozó teljes forráskódot ILIAS e-learning tananyagban tesszük elérhetővé tanfolyamaink résztvevői számára.

A feladat a Java SE szoftverfejlesztő tanfolyam 45-52. óra: Adatbázis-kezelés JDBC alapon, illetve Java adatbázis-kezelő tanfolyam 9-12. óra: Oracle HR séma elemzése, 33-36. óra: Grafikus kliensalkalmazás fejlesztése JDBC alapon, 2. rész alkalmaihoz kapcsolódik.

Tankocka – Egyszerű sorbarendezés: Java forráskód

Folytatjuk Tankockák blog bejegyzés sorozatunkat. A feladatban helyes sorrendbe kell állítani a Java forráskód sorait. Ez főként a Java SE szoftverfejlesztő tanfolyamunk tematikájához kötődik.

A Java program véletlenszerű ötöslottó szelvényt állít elő. Adatszerkezetként generikus listát használ. Amikor csak lehet, épít a kollekció beépített képességeire (eldöntés, sorozatszámítás, rendezés). A szakterületnek megfelelően az ötöslottó szelvényen tárolt számok „emelkedő számsorrendben” jelennek meg. A forráskódban nincs jelölve a csomag, importok, behúzás, tagolás, igazítás.

Egy matematika érettségi feladat megoldása programozással 2022

érettségi logó

érettségi logóA 2022-es középszintű matematika érettségi feladatsor eléggé egyszerű volt, de azért a 6. feladata inspirált arra, hogy a programozás eszköztárával oldjuk meg ezt a feladatot. Szükséges hozzá a megszámolás programozási tétel. Többféle megoldás/megközelítés (iteratív és rekurzív) is előkerül. Érdekes belegondolni, hogy mennyire más lehetne a problémamegoldás, ha programozhatnánk a matematika érettségi vizsgán. A teljes feladatsor a megoldásokkal együtt letölthető az oktatas.hu-ról.

6. feladat

Egy feleletválasztós teszt 5 kérdésből áll, minden kérdésnél négy válaszlehetőség van. Hányféleképpen lehet az 5 kérdésből álló tesztet kitölteni, ha minden kérdésnél egy választ kell megjelölni?

1. megoldás

Rögtön tudjuk, hogy ez kombinatorika, n elem k-ad osztályú ismétléses variációja, amelynek paraméterei: n=4, k=5. A hatványozás azonosságainak ismeretében fejből is tudjuk a megoldást: 45=210=1024. A Java forráskód elvégzi a hatványozást. A Math.pow() függvény általánosabb, mint amire most szükségünk van. Fogad double valós paramétereket és double típusú értékkel tér vissza. Ezért hasznos az (int) explicit típuskényszerítés.

Másképpen: négy elemű halmazból öt elemet kiválasztunk és ezeket sorba rendezzük (permutáljuk) és egy elemet egy csoportban akár ötször is felhasználhatunk. Számít a sorrend. A lehetséges variációk száma: 1024.

2. megoldás

Ha hasznos lenne egy általános metódus az ismétléses variáció kiszámítására, akkor ez egy tipikus megoldás lehet erre. Kiegészítendő még a két paraméter előjelének ellenőrzésével.

3. megoldás

Ha a megértést segíti, akkor a teljes leszámolás (brute force) módszerével, egymásba ágyazott ciklusokkal könnyen kiírathatjuk a konzolra az 1024 db különböző válaszlehetőséget. A k-val kezdődő sorszámozott ciklusváltozók jelölik az öt kérdést, azon belül az 'a'-tól 'd'-ig karakterek adják a válaszlehetőségeket. Eredményül ezt kapjuk (görgethető):

4. megoldás

Ha csak a végeredmény szükséges, akkor ez az iteratív megoldás a megszámolás programozási tétellel előállítja azt.

5. megoldás

Ez egy rekurzív megoldás. Ciklus helyett a metódus önmagát hívja meg, így valósul meg az ismételt utasításvégrehajtás. A válaszlehetőségek összefűzésével (konkatenáció) előállított válasz akkor megfelelő, ha annak hossza öt. Ez esetben kiíródik a válaszlehetőség a konzolra (mintegy mellékhatásként). Ugyanazt az eredményt kapjuk, mint a 3. megoldásnál.

6. megoldás

Szintén, ha csak a végeredmény szükséges, akkor ez a mellékhatással rendelkező rekurzív metódus előállítja azt. A mellékhatás most az, hogy a metódus eljárás és nem függvény és szükséges hozzá a db osztályváltozó (ami a metódushoz képest globálisnak is tekinthető).

7. megoldás

Ez a megoldás a válaszlehetőségeket megfelelteti n alapú számrendszerben k számjegyből álló számoknak. A kétdimenziós tömbben számokat tárol, így:

  • 1,…,1,1 → 0…0000
  • 1,…,1,2 → 0…0001
  • 1,…,1,n → 0…001(n1)
  • 1,…,2,n → 0…001(n1)
  • n,…,n,n → (n1)...(n1)

Végül a kiíró ciklus ezeket a számokat karakterekké alakítja ( 'a' ASCII kódja 97) és fordított sorrendben írja ki, hogy ugyanazt az eredményt kapjuk, mint a 3. megoldásnál.

Továbbfejlesztési lehetőségek

  • A 2. megoldáshoz: teszteljük le a lehetséges túlcsordulást és az int típus helyett szükség esetén használjunk long típust!
  • A 3. megoldáshoz: építsünk kétdimenziós tömb adatszerkezetet, amiből később az i-edik válaszlehetőség megadható!
  • Előzőhöz: állítsuk elő lexikografikus sorrendben az i-edik válaszlehetőséget adatszerkezet felépítése nélkül!
  • A 6. megoldáshoz: valósítsuk meg a rekurzív gondolatmenetet mellékhatás nélkül!
  • Teszteljünk: mennyi idő alatt hajtódik végre a 4. és a 6. megoldás? Mekkora paraméterekkel érzékelhető, hogy a rekurzió jóval lassabban fut?
  • A 7. megoldáshoz: cseréljük le az egésztömb adatszerkezetet karaktertömbre!

A bejegyzéshez tartozó teljes forráskódot ILIAS e-learning tananyagban tesszük elérhetővé tanfolyamaink résztvevői számára.

Ajánljuk matematika érettségi feladat címkénket, mert a témában évről-évre blogolunk.

A feladat a Java SE szoftverfejlesztő tanfolyam szakmai moduljának 5-8. óra: Vezérlési szerkezetek, valamint 21-24. óra: Objektumorientált programozás 1. rész alkalmaihoz kötődik.