Egy ismeretlen Feladat megoldása

Ebben a témában: C Programozas, Java Programozas

Szeretném nektek megmutatni, hogyan érdemes nekiállni egy ismeretlen feladatnak. A legfontosabb, hogy nem szabad megijedni a feladat elolvasása után, mert általában ezeknek a leírásoknak nagyobb a füstje mint a lángja, azaz könnyebb őket megoldani mint gondolnánk. Általában egy vizsga vagy egy állásinterjú során nincs idő hosszabb programok készítésére, ezért ha már több mint 10-15 sort írtál és még messze a vége, akkor érdemes lehet elgondolkoznod, hogy nincs-e egy rövidebb megoldás.

 

 

A Feladat

Keresse meg a legkisebb közös többszörösét a 81 és 12-nek.

 

Ezt a feladatot az oktatásom során is fel szoktam adni, mikor már vettünk minden olyan részt, amivel meg lehet oldani. A kezdeti sokk után azonban csak kevés embernek sikerül egy jó megoldást készítenie. Nézzük meg tehát most lépésről-lépésre hogyan érdemes nekiállni ennek a feladatnak.

 

 

  1. Az első lépés, mi a feladat?

 

A feladat, hogy megtaláljuk két szám legkisebb közös többszörösét (LKKT), jelen esetben a 81-nek és a 12-nek. Mivel azonban mi egy jó programot akarunk csinálni, ezért egy olyan megoldást készítünk, ami minden számra működni fog!

 

 

  1. Mi az a legkisebb közös többszörös?

 

Általában a legtöbb vizsga vagy állásinterjú kérdésnek van egy központi része, amit ha nem tudunk, akkor szinte kizárt, hogy megoldjuk a feladatot. Ennek a valószínűségét sok gyakorlással tudjuk csökkenteni. Ha azonban valamit mégsem tudunk, akkor annak könnyen utána tudunk nézni (legalábbis otthon), de legrosszabb esetben ne féljünk egy kis segítséget kérni a velünk szembeülőtől. Ebből a szituációból hiszed vagy sem, de akár még jól is ki tudsz jönni. Ha a felvételiztető látja, hogy hogyan reagálsz egy ismeretlen helyzetre az nagyon pozitív is tud lenni, mivel a munkád elején valószínűleg több dolog lesz ismeretlen, mint amennyit már tudsz.

 

Hogyan tudunk utánanézni valaminek magunktól?

Használjuk a Google-t, keressünk rá arra a konkrét kifejezésre, amit keresünk, esetleg írjuk is be mellé a programozási nyelvet, amit használni szeretnénk és nézzük meg az első 3 találatot. Íme az eredmény: Google Találatok

 

Két szám legkisebb közös többszöröse az a legkisebb egész szám, amelyet mindegyik szám maradék nélkül oszt.

 

Például 2 és 3 esetében a legkisebb közös többszörös a 6, mert azt a 2 és a 3 is osztja. Azért nem a 12 a legkisebb közös többszörös, mert a 6 kisebb mint a 12.

 

 

  1. Programtervezés

 

Mielőtt vadul elkezdjük írni a forráskódot, előtte próbáljunk meg felállítani egy tervet, készítsünk egy tervrajzot a programunkhoz.

Ha általánosan gondolkozunk, akkor mi lehet tetszőleges két számnak az Elméleti legkisebb közös többszöröse? => Az 1, de csak akkor ha az 1-nek és az 1-nek keressük a legkisebb közös többszörösét.

Mi lehet a lehető Legnagyobb legkisebb közös többszöröse két számnak? => Ez a két szám szorzata, mert annak eredményét biztosan mind a két szám osztja maradék nélkül.

 

Rendben, van tehát egy programunk, ami bemenetként vár két egész számot, A-t és B-t, kimenetként pedig kiad egy 1 és A*B között egy számot, nevezzük C-nek. A definícióból tudjuk, hogy C-t osztva A-val a maradék 0 és C-t osztva B-vel a maradék szintén 0. Meghatároztuk tehát a programunk bemenetét, a programunk kilépési pontját és egy algoritmust, ami képes megtalálni az elvárt kimenetet.

 

 

  1. Programváz felépítése

 

Most, hogy megvan a tervrajzunk a megoldáshoz, kezdjük el felépíteni az alapokat. Először csináljunk egy dedikált függvényt a feladathoz, de csak a vázát írjuk le:

„… van tehát egy programunk, ami bemenetként vár két egész számot, A-t és B-t, kimenetként pedig kiad egy 1 és A*B között egy számot, nevezzük C-nek.”

 

int getLKKT(int numberA, int numberB)
{
      /** Local variables, Always Initialize */
      int numberC = 0;

 

            /** Program Code */

 

            /** Return */
            return numberC;
      }

Read More

Java és C Függvények

Függvények Használata

Ebben a témában: Alapok, C Programozas, Java Programozas

Többször beszéltem már a függvények használatának fontosságáról (többek között Programok működésének felépítése és Függvény és Változó nevek). De még nem beszéltem arról, hogy pontosan, hogyan is kell létrehozni illetve használni a függvényeket. Ez az egyik alapvető része a programozásnak, ezért következzen most egy rövid gyakorlati bemutatás.

 

 

Ez a bemutató érvényes mind a Java, mind pedig a C nyelvre, minthogy a függvények használata mind a két nyelvben ugyanúgy történik, de én most mégis egy rövid Java programban fogom végigvenni a lényeget.

 

Mielőtt rátérnék a gyakorlati részre, gyorsan nézzük meg, hogy elméletben mit is jelent egy függvény a programozásban?
Egy függvény nem más mint egy végrehajtható kódhalmaz, ami mindig ugyanazt csinálja, éppen attól függően, hogy milyen céllal hozták létre az adott függvényt. Tekintsünk a függvényre úgy mint egy fekete doboz, nem kell feltétlen ismernünk a tartalmát, van valamilyen bemenete és abból valamilyen módon előállítja a kimenetét. Ezt a dobozt (a függvényt) bárhonnan fel lehet használni, meg lehet hívni. Egy ilyen függvényhívás során, a függvényben lévő kódhalmaz végrehajtódik. A függvények célja nem más, mint a program egyes részeinek feldarabolása. Mintha egy könyv tartalmát fejezetekbe osztanánk fel, úgy osztjuk fel a programot különböző függvényekbe. Illetve mivel egy függvényt többször is meghívhatunk, ezért a program egy fontos részegységét elég egyszer lekódolni és azt utána tetszőlegesen sokszor felhasználhatjuk. Minden függvényhívás során ugyanaz a kód fog végrehajtódni, függetlenül attól, hogy a függvényt honnan hívták. Attól, hogy a függvény végrehajtása befejeződött, attól még maga program nem ér véget, hanem onnan folytatódik tovább ahonnan a függvény meg lett hívva. Két fontos lépés van:

  1. A függvényhívás helye
  2. A függvény tartalma

Read More

Nem késő munkahelyet váltani?

Ebben a témában: C Programozas, Java Programozas, Onfejlesztes

Többen kérdeztétek már tőlem, hogy mi a véleményem a munkahelyváltásról. Van-e esély 30-40 éves fejjel egy új szakmát megtanulni és junior programozóként elhelyezkedni? Alapvetően az oldal célja is a felnőtt oktatás, mert szerintem igenis meg lehet csinálni és érdemes is belevágni. Én teljes mellszélességgel támogatom az elképzelést és ezt abszolút komolyan is gondolom.

 
 
 

De beszéljünk egy kicsit a konkrétumokról. Érdekel a programozás, valószínűleg már hallottál arról, hogy egész jól lehet vele keresni, ráadásul most nem is vagy megelégedve a jelenlegi munkáddal, életszínvonaladdal. De hogyan fogsz belevágni? A jó hírem az, hogy itt vagy a blogon, olvasgatsz, nézelődsz, elindultál valamerre, ez egy jó kezdet. Valószínűleg két (+egy) dolog miatt aggódsz isten igazából.

 

1.: Hogyan fogsz tudni belátható időn belül és pénzért megtanulni alapszinten programozni?

2.: Van-e bármi esélyed egy sikeres állásinterjúra iskolai papír nélkül?

+1.: Milyen hivatalos papírok léteznek a diploma mellett?

Nézzük meg ezt a pár pontot szépen sorjában.

 
 
 

1. Hogyan lehet megtanulni programozni?

 

Erről a témáról ilyen-olyan aspektusból már írtam néhány cikket, többek között Megtanulni Programozni, Önfejlesztés, Tanulás és Ki a Junior Programozó?, ezért most csak röviden érinteném.

Az alapvető feladat egy választott programozási nyelv elsajátítása alapszinten. Én általában egy széles körben ismert és használt, elterjedt, többcélú programozási nyelvet szoktam első nyelvnek ajánlani, például Java-t, C#-ot vagy C-t, ritkább esetben C++-t. Ezek viszonylak gyorsan megtanulhatóak és eléggé keresettek is, illetve rajtuk keresztül a többi nyelv már sokkal könnyebben megérthető. Egy programozási nyelv nulláról való elsajátítása, ha van heti 1-2 konzultáció tanárral, ahol át tudjátok beszélni az aktuális kérdéseket, tud feladatokat és iránymutatást adni, akkor otthoni gyakorlástól függően szerintem 2-3 hónap alatt meg lehet tanulni. Ekkor már leszel olyan szinten amivel már érdemes elmenni egy állásinterjúra. Fel lehet építeni egy nagyon szép ívet az egésznek. Először magával a programozással és az egész gondolatmenetével kell megismerkedned, hogy mire is jó a programozás maga, ez után jönnek a specifikus nyelvi elemek. Ha már ismered a nyelv alapjait, akkor már egyre komplexebb problémák megoldásával tudsz szépen fejlődni. A programozás ugyanis egy nagyon gyakorlatias szakma. Ez nagy vonalakban azt jelenti, hogy ha már megoldottál 10 problémát vagy feladatot akkor valószínűleg a 11. már sokkal gyorsabban fog menni. Ha pedig már rövid problémákra tudsz kitalálni és leimplementálni megoldásokat, algoritmusokat akkor már egy nagyon jó úton vagy. Ez az egész csak gyakorlás kérdése. Ami van elmélet az maximum 5-10 oldalban összefoglalható, szóval senkinek nem kell majd magolással töltenie az éjszakát.

 

Én azt tudom tanácsolni, hogy mielőtt súlyos költségekbe vered magad a különböző oktatásokkal, először mindenképpen próbálj meg egy-két nagyon egyszerű feladatot megoldani otthon saját magad, hogy érezd kicsit az ízét az egésznek. Erre egyrészről később úgyis szükséged lesz, mármint, hogy magadtól tudj feladatokat értelmezni és megoldani, másrészt akkor már fogod tudni, hogy kb mire is vállalkozol. Ilyen alapszintű feladatokra amúgy itt az oldalon is találsz pár példát, részletes magyarázattal és megoldással teljesen ingyenesen.

 

Most lehet, hogy úgy gondolod, hogy majd egy nagy létszámú csoportos kurzuson ez az egész tanulás könnyebb lesz de sajnos el kell keserítselek. Az ilyen csoportos kurzusokkal pont az a baj, hogy nincs idő szépen mindenkihez egyesével odamenni. Leadják az anyagot, elmondják a feladatokat, ami akkor éppen eszedbe jut azt átbeszélitek, ami meg nem, azt majd a következő alkalmon. Ott is pont az a lényeg, hogy neked kell otthon egyedül értelmezned az elhangzottakat és utána nekiesni a feladatoknak. Az intenzív kurzusokról pedig ne is beszéljünk. Nem voltam még egyen sem, de kizártnak tartom, hogy heti 5-6 nap, több héten keresztül és bárki is bírná a tempót. Annyi új dolog hangzik el egyszerűen, hogy nincs is ideje berögzülni a dolgoknak. De legalább jó drágák.

 
 
 

2. Van-e bármi esélyed egy sikeres állásinterjúra iskolai papír nélkül?

 

Nem szeretnék képmutató lenni, nyilván te is sejted, hogy ha van két teljesen ugyanolyan jelentkező az adott pozícióra és csak annyiban különböznek, hogy az egyiknek van diplomája a másiknak pedig nincs semmilyen hivatalos papírja, de amúgy szakmailag hajszálpontosan ugyanazt tudják, akkor a diplomás jelentkezőt fogják választani. Azonban a helyzet általában közel sem ilyen egyszerű…

Read More

Bináris Keresés

Ebben a témában: C Programozas

Sok fajta keresési algoritmus létezik. Ma megnézzük az egyik leggyorsabbat, a bináris keresést és az ahhoz tartozó C nyelvű implementációt.

 

Mi a bináris keresés?

A bináris keresés egy rendezett listán belül képes keresni. Az elméleti koncepciója az, hogy ha létezik a rendezett lista, akkor a keresett számról egyértelműen el tudom dönteni, hogy az aktuális számtól kisebb-e vagy nagyobb és ez alapján egyértelműen tudom, hogy a lista melyik maradék részében kell tovább keresnem. Az algoritmus a keresési listát mindig megfelezi, attól függően, hogy a keresett szám kisebb-e vagy nagyobb az aktuális lista elemnél, neve az algoritmus működési elvére utal. A bináris keresés rendkívül optimális, a futási komplexitása O(log N), tehát logaritmikus, ami azt jelenti, hogy nagyon lassan nő csak a futási ideje, vagyis milliós nagyságrendű adatoknál is csak pár lépésre van szüksége általában. Nézzünk egy példát:

 

  • A lista: [1,2,3,4,5]
  • Keresett szám: {4}

Az algoritmus futásának lépései:

  1. Keresési lista: [1,2,3,4,5]
  2. A lista középső eleme: [3]
  3. Aktuális szám: [3] < {4} -> Jobbra kell keresnem a maradék listában
  4. Felezés! Új keresési lista: [4,5]
  5. Aktuális szám: [4] = {4} -> Keresett szám megtalálva, a keresésnek vége

 

A bináris keresés kihasználja a lista rendezett tulajdonságát, rendezetlen listán nem is használható. Az algoritmus bemenete a lista első és utolsó elemének az indexe, illetve a keresett érték. A trükk az, hogy a bináris keresés mindig a keresési listát felezi, azáltal, hogy az első és utolsó elemének az indexét folyamatosan frissíti. Majd a frissített indexeknek veszi a közepét és azt az elemet hasonlítja össze a keresettel majd ismétli a folyamatot.
Nézzük meg a fenti példát még egyszer, most már feltüntetve az indexeket is (a tömbök indexe mindig 0-ról indul!):

 

  • A lista: [1,2,3,4,5]
  • Keresett szám: {4}
  • Első elem indexe (EI)
  • Utolsó elem indexe (UI)
  • Aktuális index (AI)

Az algoritmus futásának lépései:

  1. Keresési lista: [1,2,3,4,5]
    1. EI = 0
    2. UI = 4
    3. AI = EI + ((UI-EI)/2) = 0 + ((4-0)/2) = 2
  2. Aktuális szám: [3] < {4} -> Jobbra kell keresnem a maradék listában
  3. Felezés! Új keresési lista: [4,5]
    1. EI = AI+1 = 3
    2. UI = 4
    3. AI = EI + ((UI-EI)/2) = 3 + ((4-3)/2) = 3
  4. Aktuális szám: [4] = {4} -> Keresett szám megtalálva, a keresésnek vége

 

Hogyan frissítődnek az indexek?

Read More

Ismétléses utasítások – A While Ciklus

Ebben a témában: Alapok, C Programozas, Java Programozas

Egy korábbi cikkemben már bemutattam a ciklikus végrehajtás fontosságát. Java és C programozásban egy ciklus létrehozására két fajta nyelvi elem létezik, a korábban már bemutatott For ciklus és az úgynevezett While ciklus.

 

A két nyelvi elem mindig átjárható, tehát egy adott szituációra bármelyik használható. Azt, hogy ki melyiket választja az inkább helyzet és megszokás kérdése. A leglényegesebb különbség a kettő között, hogy amíg a For ciklusnál a létrehozáskor egy sorban meg tudjuk adni a feltételt és a ciklus számlálót, addig a While ciklusnál csak a feltételt tudjuk közvetlenül definiálni. A ciklusváltozó kezelését magunknak kell megoldani! Ez tipikusan azt jelenti, hogy a ciklus előtt már létre kell hoznunk a ciklusváltozót és a cikluson belülről kell növelnünk az értékét, ciklusonként egyszer.

 

Röviden vegyük át ismét a ciklusok működésének alapelvét:

  1. Meddig kell ismételni az utasításmagot, feltétel megadása
  2. Maga az utasításmag

 

A While ciklusnak két fajtája van:

  1. Elöl Tesztelő Ciklus

Azért elöl tesztelő, mert már az első végrehajtás előtt ellenőrzi a megadott feltételt, tehát nem biztos, hogy a ciklus egyszer is végre fog hajtódni. Az elöl tesztelő ciklus szintaktikailag így épül fel:

 

while(condition)

{

}

 

Látható, hogy a létrehozása jóval kevesebb karakterből megoldható mint egy For ciklus esetében (ez azonban nem biztos, hogy előny), mindössze a While kulcsszót és egy feltételt kell leírnunk. A ciklus addig fut amíg a feltétel teljesül. Nézzünk egy konkrét példát, adjuk össze az egész számokat 1-től 5-ig:

int baseNumber = 5;

int result = 0;

while (baseNumber > 0)

{

result = result + baseNumber;

baseNumber--;

}

 

Amire ennél a formánál nagyon oda kell figyelni, az a ciklusváltozó kezelése a cikluson belül. Nem hívja fel rá semmi a figyelmünket, ezért könnyen el tud felejtődni!

Nézzük meg ugyanezt a feladatot For ciklussal:

int result = 0;

for(int baseNumber = 5; baseNumber > 0; baseNumber--)

{

result = result + baseNumber;

}

 

  1. Hátul Tesztelő Ciklus

Ennél a formánál garantált, hogy a ciklus egyszer lefut! A nevét onnan kapta, hogy a feltétel ellenőrzés a ciklus végén történik. Íme a váza ennek a formának:

Read More

Programok működésének felépítése

Ebben a témában: Alapok, C Programozas, Java Programozas

Amikor valaki elkezd programozással foglalkozni, programozást tanulni, akkor mindig az első leckék között szerepel, hogy megértsük, hogy hogyan is működnek a programok. Milyen sorrendben hajtódnak végre egymás után az utasítások, hogyan épül fel egy program.

 

Egy program nem más, mint utasítások szekvenciális végrehajtásának halmaza.

Kezdjük a legegyszerűbb eshetőséggel, az egyszálú programokkal. Mit jelent ez?
Azt, hogy van egy fő szál, ami szekvenciálisan hajtja végre az egymás után következő utasításokat. Nézzünk erre egy példát:

int a = 2;

int b = 3;

int c, d;

c = a+b;

d = c*a;

 

Hogyan fognak egymás után lefutni az utasítások?

Felülről lefelé. Először létrejönnek egymás után a változók „a”, „b”, „c” és „d”. A változók vagy úgy jönnek létre, hogy van valamilyen dedikált kezdőértékük („a”, „b”) vagy úgy, hogy csak létrejön, de nem kap értéket („c”, „d”). Ezután kiszámoljuk „c” értékét majd végül pedig „d” értékét. Nincsenek kereszthatások és nincsenek ugrások sem. Mi történik, ha megcserélem „c” és „d” kiszámításának sorrendjét?

Mivel „d”-nek bemenete „c”, de mivel „c” csak „d” után kap számolt értéket, ezért nem tudjuk megmondani pontosan, hogy mi lesz „d” értéke. Azonban a program továbbra is működőképes marad, de biztosan kapunk egy hatalmas figyelmeztető üzenetet, hogy úgy használunk fel egy változót, hogy annak értékét mi magunk még sosem állítottuk. De hogyan lehetséges ez?
Úgy, hogy valamilyen előre nem definiált értéket minden változó kap a létrehozásakor, ha mi magunk nem állítunk be semmilyen kezdőértéket. Ez az érték igazából bármi lehet, nem lehet előre megmondani. Ez egy nagyon gyakori hiba és veszélyes szituáció, éppen ezért komoly figyelmeztetéseket küld ilyen esetben a fordító és a fejlesztő környezet is, ha észreveszi. Éppen ezért a legjobb megközelítés, amit én mindenkinek kifejezetten ajánlani szoktam, hogy mindig minden változónak adjunk kezdőértéket! Ez sokszor feleslegesnek tűnik, de ha egyszer bekerül a napi rutinba akkor sok fejfájást meg tudunk spórolni.

 

Függvények

Egy jól strukturált kód első ismérve a függvények megfelelő minőségű és mennyiségű használata. Mi is pontosan egy függvény?
A programozásban használt függvények analóg módon működnek a matematikában megszokott függvényekhez. Azaz valamilyen bemeneti adatokból valamilyen módon előállít kimeneti adatot vagy adatokat, áttranszformálja a bemeneti adatokat kimeneti adatokká. Azt, hogy ezt pontosan hogyan teszi, az már a függvénynek a belső hatásköre. Ezért ami fontos, hogy minden függvénynek (mostmár a programozásbeli függvényekről beszélek) kell, hogy legyen egy jól definiált bemeneti és kimeneti leírása. Pontosan milyen bemeneti adatokból milyen kimeneti adatokat fog előállítani. Persze a belső működésének a leírása is mindig szükséges, de vannak olyan szituációk amikor az nem feltétlenül fontos számunkra, csakis a bemenetek és a kimenetek.

 

Hogyan néz ki egy függvény deklarációja a programozásban?

VisszatérésiÉrtékTípusa FüggvényNév(Parameter1Típusa Parameter1, Parameter2Típusa Parameter2, …, ParameterNTípusa ParameterN) { … }

 

Deklaráljuk az összeadás függvényt, ami 2 számot ad össze:

int SumOfTwoNumbers( int Number1, int Number2) { … }

 

VisszatérésiÉrtékTípusa int
FüggvényNév SumOfTwoNumbers
Parameter1Típusa int
Parameter1 Number1
Parameter2Típusa int
Parameter2 Number1

 

Minden függvénynek kötelező, hogy legyen be és kimenete is?

Read More

Ismétléses utasítások – A For Ciklus

Ebben a témában: Alapok, C Programozas, Java Programozas

Az előző cikkben már megnéztük az egyik legalapvetőbb programozási eszközt, a feltétel vizsgálatot. Most ehhez hasonlóan szeretnék bemutatni egy szintén nagyon alapvető elemet, az ismétléses utasítás végrehajtást. Gyakran találkozunk olyan feladattal, amikor van egy nagyobb bemeneti adathalmaz és annak minden elemén ugyanazt az utasítást kell végrehajtani.

Ha a mostani ismereteinkkel közelítenénk meg ezt a problémát és feltesszük, hogy ismerjük, hogy pontosan mennyi bemeneti adatunk van, akkor minden feldolgozási lépést leprogramoznánk minden bemenetre. Ez a módszer maximum 5-10 adat esetén még esetleg működőképes lehet, de el lehet képzelni, hogy több száz vagy akár még több adat esetén már kivitelezhetetlen. Pontosan ilyen problémákra találták ki az utasításismétlést, ami az alábbiak szerint épül fel:

  1. Meddig kell ismételni az utasításmagot
  2. Maga az utasításmag

Addig hajtja végre a program újra és újra ugyan azt a blokkot, ameddig a megadott feltétel teljesül. Tehát mondjuk, ha ötvenszer kell végrehajtani egy kiírató utasítást, akkor az valahogy így nézne ki:

i := 0

[i < 50]

{

Kiíratás

}

 
Ennek megvalósítására több szintaktikai eszköz létezik C-ben és Java-ban is, de ezek egyenértékűek, átjárhatóak. Én azt gondolom, hogy a legismertebb az úgynevezett FOR Ciklus, ami az alábbiak szerint épül fel:

for(inicializálás; feltételvizsgálat; paraméter kezelés)

{

utasításmag

}

 

Read More