Pszeudokód

A pszeudokód olyan nyelvezet, amellyel algoritmusokat írunk le emberi olvasónak. Kevésbé részletes, mint egy programozási nyelv, de a szerkezete hasonló. Az, hogy a pszeudokód helyes-e, az attól függ, hogy megértik-e az olvasók az általa leírt lépéssort (szemben a programozási nyelvekkel, ahol a fordítóprogram egy merev szabályrendszer betartását várja el).

Itt elérhető egy román nyelvű cikk a pszeudokódról (pbinfo.ro).

Tartalom

  1. Változók, kifejezések
  2. Összetett utasítások
  3. Nyomonkövetés
  4. Pszeudokód átírása C++ nyelvre
  5. Egyik ciklus átírása a másikba

1. Változók, kifejezések

A változókat nem kell előre bejelenteni a típus megadásával, az első értékadáskor létrejönnek. Az értékadás alakja:

    valtozonev ← ertek

Tehát a C++-ban megszokott = jel helyett egy balra mutató nyilat használunk.

A kifejezésekben használhatók változók és konstans értékek, illetve ezekkel végzett műveletek:

Feltételekben használható relációs műveletek (a megszokott matematikai jelentéssel):

Logikai műveletek:

Beolvasás és kiírás: A “beolvas” (röviden “be”) és kiír (röviden “ki”) utasításokkal történik.

2. Összetett utasítások

2.1. Elágazás (az if megfelelője)

Szerkezete:

    Ha feltétel akkor
    │   utasítások1
    │különben
    │   utasítások2
    └■ 

A különben rész elhagyható, ha nincs rá szükség:

    Ha feltétel akkor
    │   utasítások1
    └■ 

Működése:

Román megfelelője:

    Dacă feltétel atunci
    │   utasítások1
    │altfel
    │   utasítások2
    └■ 

2.2. Elöltesztelő ciklus (a while megfelelője)

Szerkezete:

    Amíg feltétel végezd el
    │   utasítások
    └■ 

Románul:

    Cât timp feltétel execută 
    │   utasítások
    └■ 

A működése azonos a while ciklussal (amíg a feltétel igaz, ismétli az utasításokat). A “végezd el” szószerkezet rövidíthető “v.e."-re (de vizsgákon nem ajánlott).

2.3. Hátultesztelő ciklus (a do-while megfelelője)

Két típusát is használják:

Végezd el … amíg

Szerkezete:

    Végezd el
    │   utasítások
    │   ...
    │amíg feltétel
    └■ 

A működése azonos a do-while ciklussal (egyszer biztosan elvégzi az utasításokat, majd addig ismétel amíg a feltétel igaz).

Ismételd … ameddig

Szerkezete:

    Ismételd
    │   utasítások
    │   ...
    │ameddig feltétel
    └■ 

A működése abban különbözik az előzőtől, hogy akkor ismétel, ha a feltétel HAMIS (ezért használunk más szavakat, az amíg szó jelenti azt, hogy igaz feltétel esetén ismétlünk, akár elöl, akár hátul van; az ameddig pedig azt, hogy hamis feltétel esetén ismétlünk és megállunk, amint igazzá válik).

Román megfelelője a végezd el … amíg-nak:

    Execută 
    │   utasítások
    │   ...
    │cât timp feltétel
    └■ 

Román megfelelője az ismételd … ameddig-nek:

    Repetă
    │   utasítások
    │   ...
    │până când feltétel
    └■ 

2.4. Meghatározott lépésszámú ciklus (a for-hoz hasonlít, de sajátosabb)

Szerkezete:

    Minden változónév ← kezdőérték, végérték, lépés végezd el
    │   utasítások
    └■ 

Románul:

    Pentru változónév ← kezdőérték, végérték, lépés execută
    │   utasítások
    └■ 

Működése:

Példák:

    Minden i ← 1, n végezd el
    │  kiír i 
    └■ 
    Minden i ← n, 1, -1 végezd el
    │  kiír i 
    └■ 
    Minden i ← 1, 100, 2 végezd el
    │  kiír i 
    └■ 

3. Nyomonkövetés

A nyomonkövetés azt jelenti, hogy végrehajtjuk kézzel egy algoritmus utasításait (sorban, egyesével) adott bemenetre. Közben egy táblázatban követjük a változók értékeinek változásait és a képernyőre kerülő kimenetet.

Példa: kövessük nyomon az alábbi algoritmust, ha a bemenet 8 3!

    beolvas a, b
    Ha a > b akkor 
    │   x ← a
    │   a ← b 
    │   b ← x 
    └■ 
    Minden i ← a, b, 2 végezd el
    │   kiír 2*i + 1, " "
    └■ 
    kiír "vége"

Táblázat:

     a | 8  3
    ---+------------------------------
     b | 3  8
    ---+------------------------------
     x |    8
    ---+------------------------------
     i |       3  5  7

Kimenet:

    7 11 15 
    vége

A táblázat egyes soraiban hagyhatunk ki helyett, hogy jobban követhető legyen, hogy melyik változás mikor történt (mintha lenne egy vízszintes időtengely a rajzon). Ha papíron dolgozunk, akkor a változók régi értékeit érdemes egy ferde vonallal lehúzni (így az 1-es mellé írt 2-est nem fogjuk véletlenül tizenkettőnek olvasni).

Ha egy változó tömb, akkor érdemes annak elemeit valamilyen jelekkel körülhatárolni (pl. [ és ], vagy { és }). És minden változást vagy helyben bejelölni (az adott elem alá vagy fölé), vagy mindegyik esetén úrja leírni a tömböt.

4. Pszeudokód átírása C++ nyelvre

Az átírás általában egyszerű, de néhány dologra oda kell figyelni:

Példa: az alábbi algoritmust szeretnénk C++-ra árírni.

    beolvas n
    Ismételd 
    │   kiír n, ': ' 
    │   Minden i ← n, 1, -1 végezd el
    │   │   kiír i, ' '
    │   └■
    │   kiír <új sor>

    │   n ← n - 1
    │ameddig n ≤ 0
    └■ 

Megoldás:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
using namespace std;

int main()
{
    int n;
    cin >> n;

    do {
        cout << n << ": ";
        for (int i = n; i >= 1; i--) {
            cout << i << " ";
        }
        cout << endl;
        n = n - 1;
    } while (!(n <= 0)); // feltétel tagadva

    return 0;
}

5. Egyik ciklus átírása a másikba

Arra kell figyelni, hogy a két algoritmus BÁRMILYEN MEGENGEDETT BEMENETRE ugyanúgy viselkedjen (tehát ugyanazt a kimenetet produkálja, néha esetleg még arra is figyelünk, hogy a változók értékei ugyanazok legyenek a végén).

Amíg → Végezd el … amíg

Mindkettő igaz feltétel mellett ismétel, de a hátultesztelő ciklus legalább egyszer végrehajtaná a benne levő utasításokat. Úgy tesszük a kettőt ekvivalenssé, hogy a végezd el … amíg köré egy elágazást rakunk az eredeti feltétellel.

Példa: írjuk át az alábbi algoritmust úgy, hogy amíg ciklus helyett végezd el … amíg-ot használjon!

    beolvas n
    Amíg n > 0 végezd el
    │   kiír n, ' '
    │   n ← n - 2
    └■ 

Átírva:

    beolvas n
    Ha n > 0 akkor
    │   Végezd el 
    │   │    kiír n, ' '
    │   │    n ← n - 2
    │   │amíg n > 0
    │   └■ 
    └■ 

Megjegyzés: az n = 0 bemenetre az algoritmus semmit nem kell kiírjon!

Amíg → Ismételd … ameddig

Hasonlít az előzőhöz, de arra is kell figyelni, hogy az ismételd … ameddig ciklus hamis feltétel esetén ismétel. Emiatt az eredeti feltételt meg kell tagadni!

Példa: írjuk át az alábbi algoritmust úgy, hogy amíg ciklus helyett ismételd … ameddig-et használjon!

    beolvas n
    Amíg n > 0 végezd el
    │   kiír n, ' '
    │   n ← n - 2
    └■ 

Átírva:

    beolvas n
    Ha n > 0 akkor
    │   Ismételd 
    │   │    kiír n, ' '
    │   │    n ← n - 2
    │   │ameddig n ≤ 0
    │   └■ 
    └■ 

Vagy:

    beolvas n
    Ha n > 0 akkor
    │   Ismételd 
    │   │    kiír n, ' '
    │   │    n ← n - 2
    │   │ameddig NEM (n > 0)
    │   └■ 
    └■ 

Megjegyzés: az n = 0 bemenetre az algoritmus semmit nem kell kiírjon!

Végezd el … amíg → Amíg

Az előző két átíráshoz képest a problémánk itt most pont fordított jellegű: a végezd el … amíg ciklus legalább egy iteráció erejéig fut, még akkor is, ha a feltétele hamis (ezért is van a végére írva). Ahhoz, hogy ezt a viselkedést egy amíg ciklussal reprodukáljuk, kénytelenek leszünk megismételni a ciklus előtt azokat az utasításokat, amik a ciklustörzsben szerepelnek (feltéve, hogy egyáltalán fennállhat az a helyzet, hogy a feltétel kezdetben hamis).

Példa: amígra fogjuk átírni a következő algoritmus ismétlését.

    beolvas n
    Végezd el 
    │    kiír n, ' '
    │    n ← [n / 10]
    │amíg n ≠ 0
    └■ 

Átírva:

    beolvas n
    kiír n, ' '
    n ← [n / 10]
    Amíg n ≠ 0 végezd el
    │    kiír n, ' '
    │    n ← [n / 10]
    └■ 

Megjegyzés: az algoritmus az n = 0 bemenetre is ki kell írjon egy nullát, ezért az amíg előtt megismételtük a ciklusban szereplő utasításokat (hogy egyszer biztosan végre legyenek hajtva, aztán amíg a feltétel igaz, még ismétlődni fognak).

Ismételd ameddig → Amíg

Hasonlít az előzőhöz (tehát a ciklus belsejében levő utasításokat itt is leírjuk a ciklus elé), de arra is kell figyelni, hogy az ismételd … ameddig ciklus hamis feltétel esetén ismétel (ezért a feltételt meg fogjuk tagadni).

Példa: amígra fogjuk átírni a következő algoritmus ismétlését.

    beolvas n
    Ismételd 
    │    kiír n, ' '
    │    n ← [n / 10]
    │ameddig n = 0
    └■ 

Átírva:

    beolvas n
    kiír n, ' '
    n ← [n / 10]
    Amíg n ≠ 0 végezd el
    │    kiír n, ' '
    │    n ← [n / 10]
    └■ 

Megjegyzés: az algoritmus az n = 0 bemenetre is ki kell írjon egy nullát, ezért az amíg előt megismételtük a ciklusban szereplő utasításokat, a feltételt pedig tagadtuk, mert az amíg ciklus igaz feltétel esetén ismétel.

Végezd el … amíg → Ismételd … ameddig

A két ciklus viselkedése csak abban különbözik, hogy igaz vagy hamis feltétel esetén ismételnek, így átíráskor elég a feltételt tagadni. Például:

    beolvas n
    Végezd el 
    │    kiír n, ' '
    │    n ← [n / 10]
    │amíg n ≠ 0
    └■ 

Átírva:

    beolvas n
    Ismételd 
    │    kiír n, ' '
    │    n ← [n / 10]
    │ameddig n = 0
    └■ 

Ismételd ameddig → Végezd el … amíg

Az előző fordítottja (mert az ismételd … ameddig az hamis, a végezd el … amíg pedig igaz feltétel esetén ismétel).

Példa:

    beolvas a, b
    Ismételd 
    │    kiír a, ' '
    │    a ← a + 2
    │ameddig a > b
    └■ 

Átírva:

    beolvas a, b
    Végezd el 
    │    kiír a, ' '
    │    a ← a + 2
    │amíg a ≤ b
    └■ 

Megjegyzés: az algoritmus legalább egy értéket akkor is kiír, ha kezdetben a > b.

Minden → Amíg

Az átírás a ciklusok ismeretében egyszerű, arra kell odafigyelni, hogy a kezdeti és végső értéket is bevegyük az ismétlésbe (zárt legyen az intervallum), illetve a léptetést is mi végezzük.

Példa:

    beolvas a, b
    Minden k ← a, b, 2 végezd el
    │    kiír k
    └■ 

Átírva:

    beolvas a, b
    k ← a
    Amíg k ≤ b végezd el
    │    kiír k
    │    k ← k + 2
    └■ 

Megjegyzés: Előfordulhat (de nem kötelezően), hogy b értéke is ki lesz írva (pl. a = 2, b = 6).

Minden → Végezd el … amíg

Ez az átalakítás elvégezhető úgy is, hogy előbb amíg-ra, majd onnan végezd el … amíg-ra alakítunk, kis gyakorlattal viszont egyetlen lépésben is átírható (figyelni kell arra, hogy előfordulhat olyan eset, amikor a minden ciklus egy kört sem tesz meg).

Példa:

    beolvas a, b
    Minden k ← a, b, 2 végezd el
    │    kiír k
    └■ 

Átírva:

    beolvas a, b
    Ha a ≤ b akkor
    │    k ← a
    │    Végezd el 
    │    │    kiír k
    │    │    k ← k + 2
    │    │amíg k ≤ b
    │    └■ 
    └■

Megjegyzés: Előfordulhat (de nem kötelezően), hogy b értéke is ki lesz írva (pl. a = 2, b = 6).

Minden → Ismételd … ameddig

Az előzőhöz hasonlóan elvégezhető a mindenamígismételd … ameddig vonalon haladva, vagy akár egyből is (figyelmesen):

Példa:

    beolvas a, b
    Minden k ← a, b, 2 végezd el
    │    kiír k
    └■ 

Átírva:

    beolvas a, b
    Ha a ≤ b akkor
    │    k ← a
    │    Ismételd
    │    │    kiír k
    │    │    k ← k + 2
    │    │ameddig k > b
    │    └■ 
    └■

Amíg → Minden (ha lehet)

Nem mindig megoldható az átírás a minden ciklus sajátosságainak köszönhetően. Ha viszont elvégezhető (tehát előre meghatározott lépésközzel haladunk két határ között), akkor az eredetinél rövidebb leírást kapunk.

Szintén nem megoldható olyankor, ha a ciklusváltozót a ciklustörzsben módosítja az eredeti amíg ciklus, ugyanis ilyet a minden esetében konvenció szerint nem engedünk meg.

Példa:

    beolvas a, b
    i ← a
    Amíg i ≤ b végezd el
    │    kiír i
    │    i ← i+1
    └■ 

Átírva:

    beolvas a, b
    Minden i ← a, b végezd el
    │    kiír i
    └■ 

Más példa:

    beolvas a, b
    Amíg a ≤ b végezd el
    │    kiír a
    │    a ← a+1
    └■ 

Átírva:

    beolvas a, b
    Minden i ← a, b végezd el
    │    kiír i
    └■ 

Ez utóbbinál már új változót használtunk, hogy ne legyen a kifejezés megtévesztő (Minden a ← a, b v.e.), ezért a ciklustörzsben is a helyett i-t használunk.

Végezd el … amíg → Minden (ha lehet)

Ugyanaz a helyzet, mint az amíg → minden átírásnál, elvégezhető egyetlen lépésben vagy a végezd el … amíg → amíg → minden útvonalon.

Példa:

    beolvas a, b
    i ← a
    Végezd el 
    │    kiír i
    │    i ← i+1
    │amíg i ≤ b
    └■ 

Átírva:

    beolvas a, b
    kiír a
    Minden i ← a+1, b végezd el
    │    kiír i
    └■ 

Megjegyzés: az új kiírásra szükség van, mert az algoritmus akkor is ki kell írja az a értékét, ha kezdetben a >b. Mivel a-t már kiírtuk, ezért a minden ciklus a+1-től indul.

Ismételd … ameddig → Minden (ha lehet)

Ugyanaz a helyzet, mint az előzőnél, csak figyelembe kell venni, hogy az ismételd … ameddig hamis feltétel esetén ismétel.

Példa:

    beolvas a, b
    i ← a
    Ismételd
    │    kiír i
    │    i ← i+1
    │ameddig i > b
    └■ 

Átírva:

    beolvas a, b
    kiír a
    Minden i ← a+1, b végezd el
    │    kiír i
    └■