JavaScript alapok

Tartalomjegyzék

  1. bevezetés: egy egyszerű JavaScript program ("Hello!" kiírása)
  2. változók használata
  3. ciklusok
  4. elágazások
  5. függvények
  6. alkalmazás: logikai igazságtáblázatok
  7. alkalmazás: kombinatorikai feladatok
  1. nyelvi elemek
  2. adatok bevitele és kiírása
  3. vezérlési szerkezetek
  4.  
  5. ajánlott irodalom, felhasznált források
  6. további gyakorló feladatok

A példákhoz használt online JavaScript interpreter:

Online JavaScript Interpreter by Peter Jipsen, Chapman University (January 2013).
http://math.chapman.edu/~jipsen/js/ (2019-11-23)


Ismerkedés a JavaScript nyelvvel


egy egyszerű JavaScript program

/* 1. program */
writeln("Hello!");

Általában bármilyen programozási nyelvvel kezdünk el ismerkedni, az első lépés mindig egy "Hello!" (vagy "Hello, World!") kiírása. A JavaScript eredetileg a Netscape Navigator böngészőprogram programozási nyelve volt, de manapság már egy önálló, magas szintű programozási nyelv (bár a legtöbb JavaScript programot ma is böngészőprogramok számára írják). A JavaScript utasításokat rendszerint egy program, az ún. JavaScript interpreter egyenként hajtja végre, azonban a program végrehajtásának feltétele, hogy a JavaScript utasítások nyelvileg, szintaktikailag helyesen legyenek megadva.

Tanuljuk meg:

/* 2. program */
writeln("Hello!");
writeln();
writeln("------");

A fenti program három JavaScript utasításból áll. Mindhárom utasítás a 'writeln' eljárást hívja meg (kétszer string típusú paraméterrel, egyszer paraméter nélkül). A 'writeln' eljárás meghívásakor a böngésző JavaScript interpretere ("motorja")

a 'writeln' eljárás meghívása

változók használata

/* 3. program */
var s;
s="Hello!";
writeln(s);
s="Hello, World!";
writeln(s);
writeln();
writeln("------");

A programban a 'var' utasítással egy 's' nevű változót hozunk létre, majd az '=' operátor segítségével értéket adunk a változónak. Innentől kezdve az 's' változó addig tárolja a megadott string típusú értéket ("Hello!"), amíg azt egy másik értékadó utasítással meg nem változtatjuk.

A 'writeln' eljárás paramétereként nemcsak input értékeket adhatunk meg, hanem változókat is. Ebben az esetben az eljárás a változó értékét fogja kiírni.

/* 4. program */
var x,y,z;
x=1;
writeln(x);
y=2;
writeln(y);
z=x+y;
writeln(z);
writeln("------");

A létrehozott változók tárolhatnak számokat, numerikus típusú értékeket is.A számok között műveleteket (pl. összeadást) is végezhetünk, és a művelet eredményét kiírathatjuk vagy eltárolhatjuk egy újabb változóban.

/* 5. program */
var s1,s2,s3;
s1="Hello";
writeln(s1);
s2="World";
writeln(s2);
s3=s1+", "+s2+"!";
writeln(s3);
writeln();
writeln("------");

A karakterlánc vagy string típusú értékek között használhatjuk az összefűzés vagy konkatenáció ('+') műveletét. Ezzel mind string típusú értékek (pl. ", " vagy "!"), mind string típusú változók (pl. s1, s2) összekapcsolhatók.

/* 6. program */
var x,y,z;
x=1;
writeln("x = "+x);
y=2;
writeln("y = "+y);
z=x+y;
writeln("x+y = "+x+"+"+y+" = "+z);
writeln("------");
A fenti programban mind a string típusú értékek közötti konkatenáció (pl. "y = "+y), mind a numerikus értékek közötti összeadás (x+y) előfordul. Vegyük észre, hogy a '+' művelet mást jelent, ha számokat vagy ha stringeket kapcsolunk össze. (A '+' operátornak több jelentése van, a kontextustól függően. Az ilyen operátorokat szokás "túlterhelt" operátoroknak nevezni.) Ha pedig a '+' operátor egy számot és egy stringet (vagy ilyen típusú értékeket tartalmazó változókat) kapcsol össze, akkor mindig konkatenációként értelmezzük, vagyis ilyenkor a művelet eredménye mindig string típusú érték. A 'writeln' eljárás paraméterében a konkatenáció műveletét nagyon sokszor alkalmazzuk.

A fenti, 6. program képernyőképe a következő: egy változókat használó program képernyőképe

/* 7. program */
var x,y,z;
x=1;
y=2;
z=x+y;
writeln("x+y = "+x+"+"+y+" = "+z);
z=x-y;
writeln("x-y = "+x+"-"+y+" = "+z);
z=x*y;
writeln("x*y = "+x+"*"+y+" = "+z);
z=x/y;
writeln("x/y = "+x+"/"+y+" = "+z);
writeln("------");

Az összeadás mellett más műveletek operátorai is rendelkezésre állnak. A fenti programban a számok közötti alapműveletek szerepelnek: az összeadás (+), a kivonás (-), a szorzás (*) és az osztás (/). Például az 1/2 művelet eredménye 0.5 (a programozási nyelvekben szinte mindig tizedespontot használunk).

Tanuljuk meg:

Gyakorló feladatok:

(1) Futtassal le a korábbi (1-7) programokat, és változtasson rajtuk úgy, hogy minden sorban jelenjen meg valamilyen módosítás, és minden programhoz legalább öt új sort adjon hozzá!

Lehetséges változtatások:

(2) Hozzon létre három változót, és adja nekik értékül a "Tercsi", "Fercsi" és "Kata" neveket. Írassa ki külön sorokban a nevek összes lehetséges permutációját (szögletes zárójelek között és a neveket vesszővel elválasztva).

A megoldás képernyőképe a következő: az (1) feladat megoldásának képernyőképe

(3) Írassa ki a négyzetszámok és köbszámok táblázatát 1-től 10-ig!

A megoldás képernyőképe a következő: a (2) feladat megoldásának képernyőképe


ciklusok

/* 8. program */
var k,n;
k=1;
n=10;

for(var i=1;i<=n;i++) {
 writeln(i+". szám: "+k);
 k=k+1;
 }

writeln();
writeln("-----");

A fenti program az első 10 egész számot íratja ki egymás alá (némi magyarázó szöveggel egyetemben). Ezt természetesen megtehetnénk a következőképpen is:

writeln("1. szám: 1");
writeln("2. szám: 2");
writeln("3. szám: 3");
writeln("4. szám: 4");
writeln("5. szám: 5");
writeln("6. szám: 6");
writeln("7. szám: 7");
writeln("8. szám: 8");
writeln("9. szám: 9");
writeln("10. szám: 10");

Ha a 8. programhoz teljesen hasonlóan szeretnénk eljárni, a fenti utasítások helyett a következőket is írhatnánk:

writeln(1+". szám: "+1);
writeln(2+". szám: "+2);
writeln(3+". szám: "+3);
writeln(4+". szám: "+4);
writeln(5+". szám: "+5);
writeln(6+". szám: "+6);
writeln(7+". szám: "+7);
writeln(8+". szám: "+8);
writeln(9+". szám: "+9);
writeln(10+". szám: "+10);

Azonban már komolyabb nehézségbe ütköznénk, ha egy olyan programot kellene készítenünk, amely pl. az első 100 számot írja ki (éppen másolgathatnánk az utasításokat, de azért a türelemnek is van határa :) ). Ha pedig a programtól azt várnánk el, hogy 'n' darab számot írjon ki, például egy adott 'k' számtól kezdve, akkor minden különböző 'k' értékre állandóan át kellene írnunk a 'writeln' utasítások paramétereit. Ezért a 8. programot úgy készítettük el, hogy a 'k' és az 'n' változóknak különböző kezdőértéket adva a program mindig 'n' darab számot ír ki a 'k' számtól kezdve.

A 8. program képernyőképe a következő: egymás után következő egész számokat kiíró program képernyőképe

A program alapját a

for(var i=1;i<=n;i++) {
 ...
 }

szerkezettel megvalósított ún. rögzített lépésszámú ciklus jelenti, amely a JavaScript programozási nyelv legfontosabb ismétlő (iterációs) szerkezete. Ezt használva tudjuk elérni, hogy esetünkben az egyes 'writeln' utasításokat a program helyettünk készítse el egy megadott minta szerint, és pontosan addig ismételje őket (bizonyos szabályszerű változtatásokkal), amíg kell.

A 'for' ciklus a következő elemekből tevődik össze:

A ciklus lényege a ciklus blokkjában szereplő utasítások ismétlése. A legfontosabb feladat annak a beállítása, hogy a program hányszor hajtsa végre a ciklusblokkot. A ciklus a következő lépések végrehajtását valósítja meg:

  1. a ciklusváltozó kezdőértékének beállítása;
  2. a ciklusfeltétel megvizsgálása
  3. a ciklusblokk utasításainak végrehajtása;
  4. a ciklusváltozó nővelése (ha a ciklusfejben 'i++' szerepel, akkor az 'i' ciklusváltozó értékét eggyel növeljük);
  5. visszaugrás a 2. lépésre.

Nagyon fontos annak a megértése, hogy a ciklusváltozó kezdőértékének beállításával, a ciklusfeltétellel, és a ciklusváltozó növelésével tudjuk beállítani, pontosan hányszor ismétlődjön meg a ciklusblokk (vagyis hányszor hajtódjon végre a ciklusblokkban szereplő utasítások sorozata, szekvenciája).

Gyakorlásképpen írassuk ki az első 15 négyzetszámot, azaz a {1, 4, 9, 25, ...} számsorozat első 15 elemét:

/* 9. program */
var k,n;
k=1;
n=15;

for(var i=1;i<=n;i++) {
 k=i*i;
 writeln(i+". szám: "+k);
 }

writeln();
writeln("-----");

Írassuk ki az si=(1+i)/i sorozat első 15 elemét két tizedesjegy pontossággal:

/* 10. program */
var k,n;
k=1;
n=15;

for(var i=1;i<=n;i++) {
 k=(1+i)/i;
 writeln(i+". szám: "+k.toFixed(2));
 }

writeln();
writeln("-----");

Tanuljuk meg, hogy egy számot adott számú tizedesjegyre a .toFixed(tizedesjegyek_szama) függvény segítségével kerekíthetjük (pl. (1/3).toFixed(2) értéke 0.33, (7/6).toFixed(3) értéke 1.167, (−5/9).toFixed(4) értéke -0.5556 stb.).

A 10. program képernyőképe a következő: egy változókat használó program képernyőképe

Ezek után írassuk ki 2 első 20 hatványát, azaz az {1, 2, 4, 8, 16, ...} számsorozat első 20 elemét:

/* 11. program */
var k,n;
k=1;
n=20;

for(var i=1;i<=n;i++) {
 writeln(i+". szám: "+k);
 k=k*2;
 }

writeln();
writeln("-----");

Végül írassuk ki d=3 növekmény mellett az s1=1, si=si−1+d (i>1, i∈ℕ) számtani sorozat első 10 elemét, valamint a számtani sorozat első 10 elemének összegét:

/* 12. program */
var d,k,n,sum;
d=3;
k=1;
n=10;
sum=0;

for(var i=1;i<=n;i++) {
 writeln(i+". szám: "+k);
 sum=sum+k;
 k=k+d;
 }

writeln();
writeln("Az első "+n+" elem összege: "+sum);

writeln();
writeln("-----");

A programban annyi újdonság van az előzőekhez képest, hogy egy 'sum' nevű változóban állítottuk elő az első 'n' sorozatelem összegét:

Most foglaljuk össze az eddigieket. Az előző programok a 'for' ciklus segítségével különböző számsorozatok első 'n' elemét írták ki. A programokban a sorozatok i-dik elemét kétféleképpen számoltuk ki:

(1) A sorozat elemeit egy képlet segítségével adtuk meg, közvetlenül az elem sorszáma ('i') segítségével (9-10. programok). Ekkor a sorozat i-dik elemét tartalmazó 'k' változó értékét a 'writeln' kiíró utasítás előtt állítottuk be, az 'i' ciklusváltozó aktuális értékét felhasználva (ilyenkor a 'k' változó kezdőértékének nincs semmilyen jelentősége).
(2) A sorozat elemeit a megelőző sorozatelem segítségével, ún. rekurzív módon adtuk meg (11-12. programok). Ekkor
– először kiírattuk a sorozat i-dik elemét tartalmazó 'k' változó aktuális értékét, majd
– a 'writeln' kiíró utasítás után beállítottuk a 'k' változó értékét úgy, hogy az értékadás után már a sorozat következő, (i+1)-dik elemét tartalmazza. Ehhez az értékadásban (az = értékadó operátor jobb oldalán) felhasználtuk a 'k' változó korábbi értékét, amely az értékadáskor a sorozat előző, i-dik elemét tartalmazta.

Azokat a rekurzív módon megadott sorozatokat, amelyekben a sorozat i-dik elemének megadásakor az (i−1)-dik és az (i−2)-dik elemre is szükségünk van, egy 'm' segédváltozó segítségével tudjuk a legegyszerűbben kiíratni. Például tekintsük az alábbi sorozatot:

s1=1; s2=1; si=si−1+si−2 (i>2, i∈ℕ).

A sorozat elemei: {1, 1, 2, 3, 5, 8, ...} (ún. Fibonacci-sorozat).

Az alábbi program a Fibonacci-sorozat első 10 elemét íratja ki:

/* 13. program */
var m,k,n;
m=1
k=1;
n=10;

writeln(1+". szám: "+m);

for(var i=2;i<=n;i++) {
 writeln(i+". szám: "+k);
 k=k+m;
 m=k-m;
 }

writeln();
writeln("-----");

Vegyük észre, hogy az 'm' segédváltozóban a sorozat (i−1)-dik elemét tároljuk. Mivel a 'k' változóra vonatkozó k=k+m; értékadás után 'k' a sorozat (i+1)-dik elemét fogja tartalmazni, az előző, i-dik elemet újra elő kell állítanunk, hogy tárolni tudjuk 'm'-ben. Ha egy 'temp' nevű segédváltozót is bevezetünk, ez elkerülhető:

/* 14. program */
var m,k,n;
m=1
k=1;
n=10;

writeln(1+". szám: "+m);

for(var i=2;i<=n;i++) {
 writeln(i+". szám: "+k);
 var temp;
 temp=k;
 k=k+m;
 m=temp;
 }

writeln();
writeln("-----");

Mivel a 'temp' változót csak a 'for' ciklus ciklusmagjában használjuk a sorozat i-dik elemének ideiglenes tárolására, érdemes ott létrehozni.

Gyakorló feladatok (1):

Készítse el az alábbi sorozatok első 'n' elemét kiíró programot:

(1) n=20; si=3*i

(2) n=10; s0=1; s1=1; si=si−1*i (i>1, i∈ℕ); a sorozat elemei: {1, 1, 2, 6, 24, ...} (faktoriálisok sorozata, si=i!)

(3) n=9; si=(2*i2−3*i+4)

(4) n=8; si=(i2−7*i+12)/(3*i−6)

(5) n=10; q=0.5; s1=1; si=si−1*q (i>1, i∈ℕ) (mértani sorozat)

(6) n=11; s1=3; si=2*si−1 (i>1, i∈ℕ); a sorozat elemei: {3, 6, 12, 24, ...}

(7) n=12; s1=3; si=3*si−12−4*si−1+5 (i>1, i∈ℕ)

(8) n=15; s1=0, s2=1, si=(si−1+si−2)/2 (i≥3, i∈ℕ)

Végül két, valamivel nehezebb feladat:

(9) n=10; s1=1; si=si−1+(i−1) (i>1, i∈ℕ); a sorozat elemei: {1, 2, 4, 7, 11, ...} (növekményes sorozat)

(10) n=12; s1=2; si=si−1+(2*i−1) (i>1, i∈ℕ); a sorozat elemei: {2, 5, 10, 17, ...} [tipp: alakítsuk át a sorozat növekményét megadó (2*i−1) kifejezést (2*i−1) = (2*(i−1+1)−1) = (2*(i−1)+2−1) = (2*(i−1)+1) módon]

Az utolsó két feladat egy 'm' segédváltozó segítségével is megoldható, ha a sorozatok növekményét egy új, ti sorozatnak tekintjük, és ennek az elemeit állítjuk elő 'm'-ben.

Például a (9) feladat esetében a növekményt előállító sorozat
    t1=0; ti=i−1 (i>1, i∈ℕ), a sorozat elemei: {0, 1, 2, 3, ...}.
Vegyük észre, hogy ez a ti sorozat rekurzív módon is megadható
   t1=0; ti=ti−1+1 (i>1, i∈ℕ)
módon. Az így definiált ti sorozattal az eredeti sorozat
   s1=1; si=si−1+ti (i>1, i∈ℕ)
módon állítható elő.

Nézzük meg a (9)-as feladat megoldását ilyen módon:

/* 15. program */
var m,k,n;
m=0;
k=1;
n=10;

for(var i=1;i<=n;i++) {
 writeln(i+". szám: "+k);
 m=m+1;
 k=k+m;
 }

writeln();
writeln("-----");

Gyakorló feladatok (2):

Módosítsa az előző gyakorló feladatokban szereplő sorozatok első 'n' elemének kiírását megvalósító programokat úgy, hogy azok az elemek összegét is kiírják!


Utolsó feladatként készítsük el ciklussal az első 'n' négyzetszám és köbszám táblázatát! Emlékezzünk rá, hogy a feladatot korábban már megoldottuk, így a ciklusmagban szereplő 'writeln' utasítás mintája adott, pusztán a változó értékeket kell megfelelő változókkal helyettesíteni.

/* 16. program */
var k1,k2,n;
n=10;

writeln("szám szám_négyzete szám_köbe");

for(var i=1;i<=n;i++) {
 k1=i*i;
 k2=k1*i;
 writeln("  "+i+"         "+k1+"          "+k2);
 }

writeln();
writeln("-----");

A megoldás képernyőképe a következő: a 16. program megoldásának képernyőképe

Vegyük azonban észre, hogy az előző feladat megoldásához képest a két- és háromjegyű számok megjelenése eltolja a kiírt számokat, így a táblázat (finoman szólva) nem lesz esztétikus. Ennek kiküszöbölésére egy újabb programozási eszközre lesz szükségünk.


elágazások

A korábbi, 16. programban azért nem tudtuk a négyzetszámokat és a köbszámokat egy táblázatban, esztétikusan elrendezni, mert a táblázat soraiban a számok pozícióját meghatározó szóközök száma független volt a megjelenített számjegyek számától. Például a 3. sorban jelenik meg először egy két számjegyből álló köbszám (27), amely egy szóközzel eltolja a köbszámok oszlopát. A 4. sorban pedig először jelenik meg egy két számjegyből álló négyzetszám (16), amely egy szóközzel eltolja a négyzetszámok oszlopát, és egy további szóközzel eltolja köbszámok oszlopát.

A megoldás az, hogy a szóközök számát a megjelenítendő számok számjegyeinek függvényében állapítsuk meg. Mivel a táblázat oszlopaiban az 'i', 'k1' és 'k2' nevű változók értékét íratjuk ki, a következő szerkezetet kellene megvalósítanunk a programban (feltéve, hogy 'i' esetében maximum 2 jegyű számokkal, 'k1' esetében maximum 3 jegyű számokkal, 'k1' esetében pedig maximum 4 jegyű számokkal dolgozunk):

ha i<10 akkor írassunk ki 3 db. szóközt,
egyébként írassunk ki 2 db. szóközt,
és ezután írassuk ki i-t;

ha k1<10 akkor írassunk ki 9 db. szóközt,
egyébként ha k1<100, akkor írassunk ki 8 db. szóközt,
egyébként írassuk ki 7 db. szóközt,
és ezután írassuk ki k1-t;

ha k2<10 akkor írassunk ki 10 db. szóközt,
egyébként ha k2<100, akkor írassunk ki 9 db. szóközt,
egyébként ha k2<1000, akkor írassunk ki 8 db. szóközt,
egyébként írassuk ki 7 db. szóközt,
és ezután írassuk ki k2-t.

A JavaScript programozási nyelv az if(...) {...} else {...}, ún. kétirányú elágazás szerkezetet biztosítja a fenti megoldásokhoz. Lássuk ezzel a szerkezettel megvalósítva a korábbi, 16. program javított változatát:

/* 17. program */
var k1,k2,n,s1,s2,s3;
n=10;

writeln("szám szám_négyzete szám_köbe");

for(var i=1;i<=n;i++) {
 k1=i*i;
 k2=k1*i;

 if(i<10) {
  s1="   "; // 3 db. szóköz
  }
 else {
  s1="  "; // 2 db. szóköz
  }

 if(k1<10) {
  s2="        "; // 8 db. szóköz
  }
 else if(k1<100) {
  s2="       "; // 7 db. szóköz
  }
 else {
  s2="      "; // 6 db. szóköz
  }

 if(k2<10) {
  s3="          "; // 10 db. szóköz
  }
 else if(k2<100) {
  s3="         "; // 9 db. szóköz
  }
 else if(k2<1000) {
  s3="        "; // 8 db. szóköz
  }
 else {
  s3="       "; // 7 db. szóköz
  }

 writeln(s1+i+s2+k1+s3+k2);
 }

writeln();
writeln("-----");

A programban használt új nyelvi elemek a következők:

A program képernyőképe a következő: a 17. program képernyőképe

Az elágazások kiválóan felhasználhatóak olyan számsorozatok kiíratására, amelyek két részsorozatból állíthatóak elő. Tekintsük például az

si = { 1/i  ha i páratlan szám
i  ha i páros szám

sorozatot (i∈ℕ). Vegyük észre, hogy az si sorozatot két részsorozat alkotja: az első részsorozat elemeit azok az si elemek alkotják, amelyekre 'i' páratlan, a második részsorozat elemeit pedig azok az si elemek alkotják, amelyekre 'i' páros szám. Ennek megfelelően a sorozat első 'n' elemét előállító program a következő:

/* 18. program */
var k,n;
k=1;
n=10; // legyen 'n' páros szám!

for(var i=1;i<=n;i++) {
 if(i%2==0) {
  k=i;
  }
 else {
  k=1/i;
  }
 writeln(i+". szám: "+k);
 }

writeln();
writeln("-----");

A programban két fontos JavaScript nyelvi elemet vezettünk be:

Jegyezzük meg, hogy két szám összehasonlítására a JavaScript nyelvben használhatók a következő operátorok is: < (kisebb, mint; ld. 17. program), , > (nagyobb, mint), , és != (nem egyenlő).

Az előző, 18. programban az 'if' elágazó utasításban szereplő i%2==0 logikai feltétel arra szolgál, hogy eldöntsük, az 'i' egész szám osztható-e 2-vel (azaz páros-e). Általánosan megfogalmazva: ha meg akarjuk vizsgálni, hogy az 'i' egész szám osztható-e a 'j' egész számmal, az i%j==0 logikai feltételt kell megvizsgálnunk. Ha igaz, 'i' osztható 'j'-vel, ha hamis, nem osztható. Ezek után a JavaScript ciklusát és összehasonlító operátorait felhasználva egy egész számról el tudjuk dönteni, hogy prímszám-e vagy nem.

/* 19. program */
var p,k,n;
p=49; // vizsgálandó szám
k=0;
n=p;

for(var i=2;i<n;i++) {
 if(p%i==0) {
  k=i;
  break;
  }
 if(i*i>p) {
  break;  
  }
 }
if(k!=0) {
 writeln(k+" osztója a "+p+" számnak");
 writeln("a "+p+" szám nem prímszám");
 }
else {
 writeln("a "+p+" szám prímszám");
 }

writeln();
writeln("-----");

A program képernyőképe a következő: a 19. program képernyőképe

A megoldás azon alapul, hogy egy 'p' számról úgy tudjuk eldönteni, hogy prímszám-e, hogy 2-től egészen (p-1)-ig egyenként megvizsgáljuk, hogy 'p'-nek van-e valódi (azaz nem triviális) osztója (lényegében ezen az elven alapul Erasztothenész szitája is). Érdemes megjegyeznünk, hogy 'p'>3 esetében nem szükséges egészen (p-1)-ig megvizsgálnunk a számokat, elegendő a vizsgálatot p négyzetgyökéig (p-ig) folytatni. Például p=5 esetében 3-ra és 4-re már nem kell vizsgálnunk az oszthatóságot, mivel 3*3>5 teljesül.

A program működésének megértéséhez néhány fontos új programozási eszközt is meg kell tanulnunk:

Bizonyos esetekben egy ügyes trükkel kikerülhető az elágazás használata. Oldjuk meg például a következő feladatot kétféleképpen:

Feladat: írassuk ki a következő sorozat első 20 elemét (i∈ℕ):

si = (−1)i*(2*i+3)

Először oldjuk meg a feladatot kétirányú elágazással:

/* 20. program, első változat */
var n;
n=10; 

for(var i=1;i<=n;i++) {
 if(i%2==0) {
  writeln(i+". szám: "+(2*i+3));
  }
 else {
  writeln(i+". szám: "+(-1)*(2*i+3));
  }
 }

writeln();
writeln("-----");

Ezután oldjuk meg az előző feladatot annak az ötletnek a felhasználásával, hogy ha egy változó (pl. "kit") értéke 1, akkor (−1)-gyel szorozva (−1) értéket kapunk, ha pedig ezt újra megszorozzuk (−1)-gyel, akkor a változó értéke ismét 1 lesz (és így tovább, minden szorzás után megváltozik a változó előjele):

/* 20. program, második változat */
var kit,n;
kit=-1;
n=10; 

for(var i=1;i<=n;i++) {
 writeln(i+". szám: "+kit*(2*i+3));
 kit=-1*kit;
 }

writeln();
writeln("-----");

A program képernyőképe a következő lesz: a 20. program képernyőképe

Gyakorló feladatok:

(1) Írassa ki a következő sorozat első 15 elemét (i∈ℕ):

si = { i*/(2*i−1)  ha i páratlan szám
−1/i  ha i páros szám

(2) Írassa ki kétféleképpen a következő sorozat első 20 elemét (i∈ℕ):

si = (−1)i+1*(4*i2−10*i+5)

(3) Írassa ki kétféleképpen a következő sorozat első 10 elemét (i∈ℕ):

si = (−1)i*(3*i−1)+(−1)(i+1)*(i2−6*i)

(4) Írassa ki a következő sorozat első 10 értékét: {2, −6, 18, −54, ...}

(5) Írassa ki a következő sorozat első 20 értékét: {99, 1, 96, 4, 93, 7, ...}


függvények

Ha egy összetett képletet akarunk kiszámítani és akár többször is felhasználni egy programban, akkor készíthetünk egy olyan alprogramot, amely a képlet értékét kiszámítja, és bármikor fel tudjuk használni. Tegyük fel, hogy különböző sugarú körök kerületét és területét akarjuk kiíratni:

/* 21. program, első változat */
var r,dr,kerulet,terulet,n;
n=8; 

r=1;
dr=0.2;
for(var i=1;i<=n;i++) {
 kerulet=2*r*Math.PI;
 terulet=r*r*Math.PI;
 writeln("A kör sugara: "+r.toFixed(2));
 writeln("      kerülete: "+kerulet.toFixed(4));
 writeln("      területe: "+terulet.toFixed(4));
 r=r+dr;
 }

writeln();
writeln("-----");

A programban hivatkoztunk a π állandóra Math.PI módon. Mivel sokszor van szükségünk π értékére, a JavaScript nyelv ún. nevesített konstansként tartalmazza ennek az értékét. Egy másik nevezetes matematikai állandó az 'e' szám (2.71828...). A JavaScript nyelvben erre is bármikor hivatkozhatunk Math.E módon. Vegyük észre, hogy a nevesített konstansok két részből tevődnek össze: a Math osztálynévből és egy nagybetűs azonosítóból (pl. PI vagy E), amelyeket egy pont operátorral (.) kapcsolunk össze.

A program képernyőképe a következő lesz: a 21. program képernyőképe

Most készítsük el az előző program egy módosított változatát úgy, hogy a kör kerületének és területének a kiszámítását két alprogram segítségével végezzük el. Az alprogramok közül a standard eljárásokról a 'writeln' eljárás kapcsán már beszéltünk. Most hozzunk létre két saját függvényt (function) 'kerulet' és 'terulet' néven:

/* 21. program, második változat */
function kerulet(r) {
 var k;
 k=2*r*Math.PI; 
 return k;
 }

function terulet(r) {
 var t;
 t=r*r*Math.PI; 
 return t;
 }

var r,dr,n;
n=8; 

r=1;
dr=0.2;
for(var i=1;i<=n;i++) {
 writeln("A kör sugara: "+r.toFixed(2));
 writeln("      kerülete: "+kerulet(r).toFixed(4));
 writeln("      területe: "+terulet(r).toFixed(4));
 r=r+dr;
 }

writeln();
writeln("-----");

Figyeljük meg, hogy a függvényeket megvalósító, kapcsos zárójelek között megadott {...} utasítások sokban hasonlítanak azokhoz a programokhoz, amelyeket eddig készítettünk. Létrehozhatunk bennük változókat (pl. var k;), ezekkel műveleteket végezhetünk, értékeket adhatunk nekik (pl. k=2*r*Math.PI;) stb. A függvényeknek mint alprogramoknak azonban egyedi jellemzőik is vannak. Emeljük ki a függvények legfontosabb ilyen jellemzőit:

  1. Minden függvényt egyértelműen azonosít a függvény neve. A függvény meghatározása során a nevet közvetlenül a function azonosító ("kulcsszó") után adjuk meg. A név után mindig zárójelek állnak. Az előző programban a függvények nevei: kerület(...) és terület(...).
  2. A függvény neve után szereplő zárójelek között egy vagy több változót adhatunk meg. A fenti programban például (r) módon egy 'r' nevű változót adtunk meg (egyes függvények esetében előfordulhat az az eset is, hogy nem adunk meg egy változót sem). A függvény neve után megadott változókat a függvény paramétereinek nevezzük. Az előző programban szereplő mindkét függvénynek egy paramétere van, az r változó.
  3. A függvények meghatározásakor általában az utolsó utasítás a return, amely befejezi a függvény végrehajtását, és az utána megadott változó vagy kifejezés értékét hozzárendeli a függvény nevéhez (hasonló módon, mint amikor értéket adunk egy változónak). Például a return k; utasítás végrehajtása után a 'kerulet' függvény értéke a 'k' változóban tárolt érték lesz. Emeljük ki: a 'kerulet' függvény értéke az 'r' paraméter értékétől függ, a függvényt meghatározó képletnek (ill. az ezt megvalósító utasításoknak) megfelelően.
  4. Ha szükségünk van a függvények értékére, az elkészített függvényeket a programban meghívhatjuk a függvény nevének, és (zárójelek között) a megfelelő paraméterértékeknek a megadásával. Például a fenti programban a 'kerület' függvényt a 'writeln' utasításban hívjuk meg writeln(...+kerulet(r).toFixed(4)); módon. A függvény meghívásakor megadott paraméterértékek a függvény paramétereinek mint változóknak értéket adnak, ezután a JavaScript interpreter végrehajtja a függvény utasításait, majd a 'return' utasításhoz érve értéket rendel a függvény nevéhez, és visszatér a függvényt meghívó utasításhoz.

Gyakorlásképpen írassuk ki néhány korábbi sorozat elemeit úgy, hogy létrehozunk egy 'sorozat' függvényt:

/* 22. program */

function sorozat(i) {
 var k;
/* k=i; // 8. program */
/* k=i*i; // 9. program */
 k=(1+i)/i; // 10. program
 return k;
 }

var n;
n=10;

for(var i=1;i<=n;i++) {
 writeln(i+". szám: "+sorozat(i));
 }

writeln();
writeln("-----");

Figyeljük meg, hogy a különböző programok a 'sorozat' függvény egyszerű módosításával megvalósíthatók.

Gyakorló feladatok:

Oldja meg a ciklusok rész végén szereplő gyakorló feladatok közül az (1)-(4) feladatokat saját függvények létrehozásával!


A rekurzív módon megadott sorozatok elemei is kiszámíthatók függvények segítségével, mivel egy függvény saját magát is meghívhatja (ez ún. rekurzív függvényhívás). Ebben az esetben azonban nagyon óvatosan kell eljárnunk, mert ha nem megfelelően készítjük el a függvényeket, az könnyen végtelen hívásláncot eredményezhet. próbaképpen Írassuk ki 2 első 'n' hatványát ilyen módon (ezt korábban, a 11. programban már megoldottuk):

/* 23. program */
function sorozat(i) {
 if(i<=1) k=1;
 else k=sorozat(i-1)*2; 
 return k;
 }

var n;
n=20;

for(var i=1;i<=n;i++) {
 writeln(i+". szám: "+sorozat(i));
 }

writeln();
writeln("-----");

Nézzük meg a program működését akkor, ha meghívjuk a sorozat(3) függvényt. Ekkor

A hívási lánc eredményeképpen tehát

sorozat(3)=2*sorozat(2)=2*(2*sorozat(1))=2*(2*(1))=4

adódik, ami pontosan megegyezik a sorozat 3-dik elemével (s1=1, s2=21=2 és s3=22=4). Nagyon fontos, hogy a hívási lánc befejeződését az garantálja, hogy i folyamatos csökkentésével előbb-utóbb eljutunk az (i==1) feltétel teljesüléséig, ami után a függvény visszaadja az 1 értéket (és nem hívja meg többször önmagát). Vagyis a 'sorozat' függvény helyes működését az

if(i<=1) k=1;
else ...

feltételes elágazó utasítás biztosítja.


Alkalmazások


Logikai igazságtáblázatok

A JavaScript logikai operátorai lehetővé teszik lényegében bármilyen logikai függvény (formula) kiszámítását. A legfontosabb logikai operátorok (feltéve, hogy 'p' és 'q' logikai típusú, azaz logikai értékeket tartalmazó változók):

Ha logikai igaz (true) értékként az 1, logikai hamis (false) értékként a 0 értéket használjuk, ügyelnünk kell rá, hogy a JavaScript számára mindig egyértelmű legyen, hogy az 1 és 0 értékek számokat (Number) vagy logikai értékeket (Boolean) jelentenek.

Írassuk ki elsőként a konjunkció (∧) igazságtáblázatát!

// konjunkció igazságtáblázata (saját függvény létrehozásával)

function kon(x,y) {
 var a=Boolean(x), b=Boolean(y);
 var c=x && y;
 return Number(c);
 }

writeln("A"+" " +"B"+" "+"A∧B");
writeln("-------");

for(i=0;i<=1;i++) {
 for(j=0;j<=1;j++) {
  var k=kon(i,j);
  writeln(i+" " +j+"  "+k);
  }
 }

writeln("-------");

A program képernyőképe a következő: Az konjunkció igazságtáblázata

Az igazságtáblázatban szereplő A és B változók értékeit az 'i' és 'j' ciklusváltozók állítják elő. A 'kon' függvényben

Mivel a konjunkció igazságtáblázatát kiíró programban a 'kon' függvényt csak egyszer hívtuk meg, könnyen készíthető egy olyan program, amely saját függvény használata nélkül írja ki a konjunkció igazságtáblázatát.

// konjunkció igazságtáblázata (saját függvény használata nélkül)

writeln("A"+" " +"B"+" "+"A∧B");
writeln("-------");

for(i=0;i<=1;i++) {
 for(j=0;<<=1;j++) {
  var a=Boolean(i), b=Boolean(j);
  var c=a && b;
  var k=Number(c);
  writeln(i+" " +j+"  "+k);
  }
 }

writeln("-------");

Jegyezzük meg, hogy a Boolean(...) függvény elhagyásával mindkét fenti program megfelelően fog működni, mert a logikai operátor (&&) használata egyértelművé teszi, hogy az 'i' és 'j' változók értékét logikai értéknek (vagyis nem számnak) tekintjük. A Number(...) függvényre azonban szükségünk van, ha biztosítani akarjuk, hogy a 'k' változó értékét, azaz az 1 (true) vagy 0 (false) logikai értékeket a JavaScript interpreter mindig számként írja ki.

Ezután írassuk ki a diszjunkció (∨) és a negáció (⌝) igazságtáblázatát!

// diszjunkció

function disz(x,y) {
 var a=Boolean(x), b=Boolean(y);
 var c=x || y;
 return Number(c);
 }

writeln("A"+" " +"B"+" "+"A∨B");
writeln("-------");

for(i=0;i<=1;i++) {
 for(j=0;j<=1;j++) {
  var k=disz(i,j);
  writeln(i+" " +j+"  "+k);
  }
 }

writeln("-------");

A program képernyőképe a következő: Az diszjunkció igazságtáblázata

// negáció

function neg(x) {
 var a=Boolean(x);
 var c=!a;
 return Number(c);
 }

writeln("A"+" "+"A⌝B");
writeln("-----");

for(i=0;i<=1;i++) {
 var k=neg(i);
 writeln(i+"  "+k);
 }

writeln("-----");

A program képernyőképe a következő: Az negáció igazságtáblázata

Írassuk ki gyakorlásként az implikáció (⊃) és az ekvivalencia (≡) igazságtáblázatát is!

// implikáció

function imp(x,y) {
 var a=Boolean(x), b=Boolean(y);
 var c=!x || y;
 return Number(c);
 }

writeln("A"+" "+"B"+" "+"A⊃B");
writeln("-------");

for(i=0;i<=1;i++) {
 for(j=0;j<=1;j++) {
  var k=imp(i,j);
  writeln(i+" " +j+"  "+k);
  }
 }

writeln("-------");

A program képernyőképe a következő: Az implikáció igazságtáblázata

// ekvivalencia

function ekv(x,y) {
 var a=Boolean(x), b=Boolean(y);
 var c=(x && y) || (!x && !y);
 return Number(c);
 }

writeln("A"+" "+"B"+" "+"A≡B");
writeln("-------");

for(i=0;i<=1;i++) {
 for(j=0;j<=1;j++) {
  var k=ekv(i,j);
  writeln(i+" " +j+"  "+k);
  }
 }

writeln("-------");

A program képernyőképe a következő: Az ekvivalencia igazságtáblázata

Végezetül határozzuk meg a C = A ∧ (A ⊃ B) ⊃. B formula igazságtáblázatát (modus ponens)!

// modus ponens

function mp(x,y) {
 var a=Boolean(x), b=Boolean(y);
 var x=!a || b; // (A ⊃ B) kiszámítása
 var y=a && x; // A ∧ (A (A ⊃ B) B) kiszámítása
 var c=!y || b;
 return Number(c);
 }

writeln("C = A ∧ (A ⊃ B) ⊃. B");
writeln();

writeln("A"+" "+"B"+" "+"C");
writeln("-----");

for(i=0;i<=1;i++) {
 for(j=0;j<=1;j++) {
  var k=mp(i,j);
  writeln(i+" " +j+" "+k);
  }
 }

writeln("-----");

A program képernyőképe a következő: A modus ponens formula igazságtáblázata

A program elkészítésekor felhasználtuk az implikációra vonatkozó A ⊃ B=⌝A ∨ B logikai azonosságot. Az igazságtáblázatból kiolvasható, hogy a modus ponens formula logikai törvény.

Gyakorló feladatok:

Írassa ki az összes fenti logikai művelet és formula igazságtáblázatát saját függvény használata nélkül is!


Kombinatorikai feladatok

A legalapvetőbb kombinatorikai műveletek a permutáció, a variáció és a kombináció. Elsőként állítsuk elő az (1,2,3,4) számok 3-ad osztályú ismétléses variációit, és számláljuk meg, hány ilyen variáció létezik.

/* ismétléses variációk, V4,3,i (1,2,3,4) */

var i,j,k;
var sorszam=0;

for(var i=1;i<=4;i++) {
 for(var j=1;j<=4;j++) {
  for(var k=1;k<=4;k++) {
   writeln("("+i+","+j+","+k+")");
   sorszam++;
   }
  }
 }
writeln();
writeln("a variációk száma: "+sorszam);

writeln("-----");

A program képernyőképe a következő: Az (1,2,3,4) számok ismétléses variációi Az (1,2,3,4) számok ismétléses variációi

Figyeljük meg, hogy a programban szereplő 'for' ciklusok száma megegyezik azzal, ahány elemet kiválasztunk a variációk előállítása során (3), és a 'for' ciklusok ciklusváltozói ('i', 'j' és 'k') azokat az értékeket veszik egymás után fel (1,2,3,4), amelyek közül a variációk előállítása során választhatunk.

A kiírt variációk megszámlálását úgy végezzük, hogy

Végül pedig ellenőrizzük, hogy a program által kiírt ismétléses variációk száma V43,i=43=64, megegyezik az ismétléses variációk számát megadó képlet által szolgáltatott értékkel.

Ezután állítsuk elő az (1,2,3,4) számok 3-ad osztályú ismétlés nélküli variációit, és számláljuk meg, hány ilyen variáció létezik.

/* ismétlés nélküli variációk, V4,3 (1,2,3,4) */
/* első változat */

var i,j,k;
var sorszam=0;

for(var i=1;i<=4;i++) {
 for(var j=1;j<=4;j++) {
  if(j!=i) {
   for(var k=1;k<=4;k++) {
    if(k!=i && k!=j) {
     writeln("("+i+","+j+","+k+")");
     sorszam++;
     } // második if(...) blokk vége
    }
   } // első if(...) blokk vége
  }
 }
writeln();
writeln("a variációk száma: "+sorszam);

writeln("-----");

A program hasonlóan működik az előző programhoz, amely az (1,2,3,4) számok ismétléses variációit állította elő. Azonban most csak azokat a variációkat íratjuk ki, amelyekben

Így tudjuk biztosítani, hogy a kiírt variációkban nincsenek azonos (ismétlődő) értékek.

A program egyszerűsíthető a continue; utasítás használatával, amelyet egy ciklusban használva a JavaScript interpreter kihagyja ("átugorja") a ciklusmag további utasításait.

/* ismétlés nélküli variációk, V4,3 (1,2,3,4) */
/* második változat */

var i,j,k;
var sorszam=0;

for(var i=1;i<=4;i++) {
 for(var j=1;j<=4;j++) {
  if(j==i) continue;
  for(var k=1;k<=4;k++) {
   if(k==i || k==j) continue;
   writeln("("+i+","+j+","+k+")");
   sorszam++;
   }
  }
 }
writeln();
writeln("a variációk száma: "+sorszam);

writeln("-----");

A programban a continue; utasítás használatával kihagyjuk ("kiszitáljuk") azokat a variációkat, amelyekben

A program képernyőképe a következő: Az (1,2,3,4) számok ismétlés nélküli variációi

Végül ellenőrizzük, hogy a program által kiírt ismétlés nélküli variációk száma V43=4!/(4-3)!=(4*3*2*1)/(1)=24 megegyezik az ismétlés nélküli variációk számát megadó képlet által szolgáltatott értékkel.

Mivel az ismétlés nélküli permutációk az ismétlés nélküli variációk speciális esetei (ha n=k, akkor Vnn=Pn), ezért a fenti program segítségével könnyen előállíthatók az (1,2,3) számok ismétlés nélküli permutációi.

/* ismétlés nélküli permutációk, P3 (1,2,3) */

var i,j,k;
var sorszam=0;

for(var i=1;i<=3;i++) {
 for(var j=1;j<=3;j++) {
  if(j==i) continue;
  for(var k=1;k<=3;k++) {
   if(k==i || k==j) continue;
   writeln("("+i+","+j+","+k+")");
   sorszam++;
   }
  }
 }
writeln();
writeln("a variációk száma: "+sorszam);

writeln("-----");

Az egyetlen különbség az előző programhoz képest, hogy a 'for' ciklusokban a ciklusváltozók értéke csak az (1,2,3) értékeket veheti fel.

A program képernyőképe a következő: Az (1,2,3) számok ismétlés nélküli permutációi

Végül ellenőrizzük, hogy a program által kiírt ismétlés nélküli variációk száma P3=3!=(3*2*1)=6 megegyezik az ismétlés nélküli permutációk számát megadó képlet által szolgáltatott értékkel.

Ezután állítsuk elő az (1,2,3,4) számok 3-ad osztályú ismétlés nélküli kombinációit, és számláljuk meg, hány ilyen kombináció létezik.

/* ismétlés nélküli kombinációk, C4,3 (1,2,3,4) */

var i,j,k;
var sorszam=0;

for(var i=1;i<=4;i++) {
 for(var j=i+1;j<=4;j++) {
  for(var k=j+1;k<=4;k++) {
   writeln("{"+i+","+j+","+k+"}");
   sorszam++;
   }
  }
 }
writeln();
writeln("a kombinációk száma: "+sorszam);

writeln("-----");

A program képernyőképe a következő: Az (1,2,3,4) számok ismétlés nélküli kombinációi

A program azon az elven működik, hogy mivel a kombinációk esetében a kiválasztott elemek sorrendje nem számít (halmazokat állítunk elő), a kiválasztott elemeket tetszőlegesen, például növekvő sorrendben elrendezhetjük. Ez a program szempontjából azt jelenti, hogy az egymásba ágyazott 'for' ciklusok 'i', 'j' és 'k' ciklusváltozóira az i<j<k feltételnek kell teljesülnie (vegyük észre, hogy egy kombinációt {i,j,k} módon állítunk elő!). Ha a 'j' ciklusváltozó kezdőértéke i+1, a 'k' ciklusváltozó kezdőértéke pedig j+1, akkor a fenti feltétel nyilvánvalóan teljesül.

Végül ellenőrizzük, hogy a program által kiírt ismétlés nélküli kombinációk száma C43=4!/(3!*(4-3)!)=(4*3*2*1)/(3*2*1)=4 megegyezik az ismétlés nélküli kombinációk számát megadó képlet által szolgáltatott értékkel.

Az előző program ismeretében könnyen elő tudjuk állítani az (1,2,3,4) számok 3-ad osztályú ismétléses kombinációit. Számláljuk meg most is, hány ilyen kombináció létezik.

/* ismétléses kombinációk, C4,3,i (1,2,3,4) */

var i,j,k;
var sorszam=0;

for(var i=1;i<=4;i++) {
 for(var j=i;j<=4;j++) {
  for(var k=j;k<=4;k++) {
   writeln("{"+i+","+j+","+k+"}");
   sorszam++;
   }
  }
 }
writeln();
writeln("a kombinációk száma: "+sorszam);

writeln("-----");

A program képernyőképe a következő: Az (1,2,3,4) számok ismétléses kombinációi

A program abban különbözik az előző programtól, hogy most megengedjük, hogy a ciklusváltozók értéke megegyezzen. Azaz most az egymásba ágyazott 'for' ciklusok 'i', 'j' és 'k' ciklusváltozóira az i≤j≤k feltételnek kell teljesülnie. Ennek megfelelően

vagyis a ciklusváltozók kezdőértékének beállítása biztosítja, hogy a fenti feltétel teljesüljön.

Végül ellenőrizzük, hogy a program által kiírt ismétlés nélküli kombinációk száma

C43,i=(4+3-1)!/(3!*(4+3-1-3)!)=(6*5*4*3*2*1)/((3*2*1)*(3*2*1))=(6*5*4)/(3*2*1)=(2*5*2)=20

megegyezik az ismétléses kombinációk számát megadó képlet által szolgáltatott értékkel.

Végül jegyezzük meg, hogy az ismétléses permutációk szintén előállíthatóak lennének egy megfelelő JavaScript program segítségével, azonban ezzel most nem foglalkozunk.


Gyakorló feladatok:

(ismétléses variációk)

(1.1) Írassa ki az (1,2,3,4,5) számok 3-ad osztályú ismétléses variációit, és ellenőrizze az eredményt!

(1.2) Írassa ki az (1,2,3,4,5) számok 2-ad osztályú ismétléses variációit, és ellenőrizze az eredményt!

(1.3) Írassa ki az (1,2,3,4) számok 2-ad osztályú ismétléses variációit, és ellenőrizze az eredményt!

(1.4) Írassa ki az (1,2,3) számok 2-ad osztályú ismétléses variációit, és ellenőrizze az eredményt!

(ismétlés nélküli variációk)

(2.1) Írassa ki az (1,2,3,4,5) számok 3-ad osztályú ismétlés nélküli variációit, és ellenőrizze az eredményt!

(2.2) Írassa ki az (1,2,3,4,5) számok 2-ad osztályú ismétlés nélküli variációit, és ellenőrizze az eredményt!

(2.3) Írassa ki az (1,2,3,4) számok 2-ad osztályú ismétlés nélküli variációit, és ellenőrizze az eredményt!

(2.4) Írassa ki az (1,2,3) számok 2-ad osztályú ismétlés nélküli variációit, és ellenőrizze az eredményt!

(ismétlés nélküli permutációk)

(3.1) Írassa ki az (1,2) számok ismétlés nélküli permutációit!

(3.2) Szorgalmi feladat: írassa ki az (1,2,3,4) számok ismétlés nélküli permutációit!

(ismétlés nélküli kombinációk)

(4.1) Írassa ki az (1,2,3,4,5) számok 3-ad osztályú ismétlés nélküli kombinációit, és ellenőrizze az eredményt!

(4.2) Írassa ki az (1,2,3,4,5) számok 2-ad osztályú ismétlés nélküli kombinációit, és ellenőrizze az eredményt!

(4.3) Írassa ki az (1,2,3,4) számok 2-ad osztályú ismétlés nélküli kombinációit, és ellenőrizze az eredményt!

(4.4) Írassa ki az (1,2,3) számok 2-ad osztályú ismétlés nélküli kombinációit, és ellenőrizze az eredményt!

(ismétléses kombinációk)

(5.1) Írassa ki az (1,2,3,4,5) számok 3-ad osztályú ismétléses kombinációit, és ellenőrizze az eredményt!

(5.2) Írassa ki az (1,2,3,4,5) számok 2-ad osztályú ismétléses kombinációit, és ellenőrizze az eredményt!

(5.3) Írassa ki az (1,2,3,4) számok 2-ad osztályú ismétléses kombinációit, és ellenőrizze az eredményt!

(5.4) Írassa ki az (1,2,3) számok 2-ad osztályú ismétléses kombinációit, és ellenőrizze az eredményt!


JavaScript összefoglaló


a JavaScript nyelvi elemei

Írjon be egy adatot:

[elemi adattípusok, adatok (literálok)]

[változók, változótípusok]

[elemi típusú változók]

// számrendszerek

var x,d,b,h;

x=123;
d=Number(x).toString();
writeln(x+" | "+d);

x=123;
b=Number(x).toString(2);
writeln(x+" | "+b);

x=123;
h=Number(x).toString(16);
writeln(x+" | "+h);

writeln("--------------------------------------------------");

b="10110100";
x=parseInt(b,2)
writeln(x+" | "+b);

h="2cd";
x=parseInt(h,16)
writeln(x+" | "+h);

writeln("--------------------------------------------------");

b="10101010";

write(b+" közvetlen átváltása decimális számrendszerbe: ");
x=1*128+0*64+1*32+0*16+1*8+0*4+1*2+0*1;
writeln(x);

x=0; // részösszegek
he=1; // helyiérték
i=b.length-1; // ciklusváltozó

while(i>=0) {
 d=parseInt(b.charAt(i),2); // számjegy adott helyiértéken
 x+=d*he; // vagy x=x+d*he;
 he*=2; // vagy he=he*2;
 i--; // vagy i=i-1;
 }

writeln(b+"  -->  "+x);
writeln("--------------------------------------------------");

h="3de5";

write(h+" közvetlen átváltása decimális számrendszerbe: ");
x=3*16**3+13*16**2+14*16+5*1;
writeln(x);

x=0; // részösszegek
he=1; // helyiérték
i=h.length-1; // ciklusváltozó

while(i>=0) {
 d=parseInt(h.charAt(i),16); // számjegy adott helyiértéken
 x+=d*he; // vagy x=x+d*he;
 he*=16; // vagy he=he*16;
 i--; // vagy i=i-1;
 }

writeln(h+"  -->  "+x);
writeln("--------------------------------------------------");

[egy- és többdimenziós tömbök (array)]

Egy példa egydimenziós tömbök létrehozására:

// egydimenziós tömbök

var tanulok=["Jancsi","Zoe","Peti","Kata","Ildi"];
var i;

tanulok[5]="Tercsi"; // vagy tanulok[this.length]="Tercsi";
tanulok[6]="Fercsi";

writeln("Névsor:\n");

for(i=0;i<tanulok.length;i++) {
 writeln(tanulok[i]);
 }

writeln("\nÖsszesen "+tanulok.length+" tanuló.\n");

writeln("--------------------------------------------------");

tanulok.sort();

writeln("Rendezett névsor:\n");

for(i=0;i<tanulok.length;i++) {
 writeln(tanulok[i]);
 }

writeln("--------------------------------------------------");

Egy példa egydimenziós, számokból álló tömbök (vektorok) létrehozására és a tömb elemeinek összeadására:

// számok (tömbelemek) összeadása

var szamok=[1,4,3,2];
var i,osszeg=0;

for(i=0;i<szamok.length;i++) {
 osszeg+=szamok[i];
 // if(i+1>=szamok.length) break;
 writeln("részösszeg: "+osszeg);
 }

writeln("\nvégösszeg: "+osszeg);

writeln("--------------------------------------------------");

Egy példa többdimenziós tömbök (mátrixok) létrehozására és kiírására:

// többdimenziós tömbök (mátrixok) létrehozása

// négyzetes mátrix

var i,j;
var matrix=[
 [1,4,3,2],
 [6,1,5,5],
 [1,2,3,4],
 [7,1,2,6]
 ];

for(i=0;i<matrix.length;i++) {
 for(j=0;j<matrix.length;j++) {
  write(matrix[i][j]+" ");
  }
 writeln();
 }

writeln("--------------------------------------------------");

// általános mátrix

matrix=[
 [1,4,3,2,8],
 [6,1,5,5,0],
 [1,2,3,4,9],
 [7,1,2,6,4]
 ];

// 4 sor és 4 oszlop kiírása

for(i=0;i<matrix.length;i++) {
 for(j=0;j<matrix.length;j++) {
  write(matrix[i][j]+" ");
  }
 writeln();
 }

writeln();

// 4 sor és 5 oszlop kiírása

for(i=0;i<matrix.length;i++) {
 for(j=0;j<matrix[i].length;j++) {
  write(matrix[i][j]+" ");
  }
 writeln();
 }

writeln("--------------------------------------------------");

[objektumok]

[nem definiált értékű és típusú változók]

Az azonosítók (pl. a változók neve) esetében tartsuk be a következőket: a nevek kezdődjenek kisbetűvel és csak betűket, számjegyeket, és aláhúzás-karaktert (_) tartalmazzanak. Az azonosítók neveiben a nagy- és kisbetűk különbözőek, nagybetűt csak kivételes esetben használjunk (pl. két szóból álló név esetén, szóköz helyett: tanuloNeve, tanarNeve stb.), és a magyar ékezetes betűket a nevekben ne használjuk.

[operátorok, függvények]

aritmetikai operátorok

logikai operátorok


Lássunk néhány példát a logikai operátorok használatára:

// igazságtáblázat készítése (implikáció)

function imp(x,y) {
 var a=Boolean(x), b=Boolean(y);
 var c=!a || b;
 return Number(c);
 }

writeln("A"+" " +"B"+" "+"⊃");
writeln("A"+" " +"B"+" "+"\u2283");
writeln("-----");

for(i=0;i<=1;i++) {
 for(j=0;j<=1;j++) {
  writeln(i+" " +j+" "+imp(i,j));
  }
 }

writeln("--------------------------------------------------");

Készítsük el a

geza(A,B) = ( A ⊃ ( A ⊃ B) ) ∨. A

és a

peti(A,B) = ( ( A ⊃ B) ⊃ A ) ∨. A

logikai függvények igazságtáblázatát:

// geza(A,B) = ( A ⊃ ( A ⊃ B) ) ∨. ⌝A
// peti(A,B) = ( ( A ⊃ B) ⊃ A ) ∨. ⌝A

function imp(x,y) {
 var a=Boolean(x), b=Boolean(y);
 var c=!a || b;
 return Number(c);
 }

function geza(x,y) {
 var a=Boolean(x), b=Boolean(y);
// var c=(imp(x,imp(x,y))) || !a;
// var c=(imp(a,imp(a,b))) || !a;
  var c=(!a || (!a || b)) || !a;
 return Number(c);
 }

function peti(x,y) {
 var a=Boolean(x), b=Boolean(y);
// var c=(imp(imp(x,y),x)) || !a;
// var c=(imp(imp(a,b),a)) || !a;
  var c=(!(!a || b) || a) || !a;
 return Number(c);
 }

writeln("A"+" " +"B"+" "+"(A g B)");
writeln("-----------");

for(i=0;i<=1;i++) {
 for(j=0;j<=1;j++) {
  writeln(i+" " +j+"    "+geza(i,j));
  }
 }

writeln("--------------------------");

writeln("A"+" " +"B"+" "+"(A p B)");
writeln("-----------");

for(i=0;i<=1;i++) {
 for(j=0;j<=1;j++) {
  writeln(i+" " +j+"    "+peti(i,j));
  }
 }

writeln("--------------------------");

Készítsük el a kata(A,B) = ( A ∧ ( A ⊃ B) ) logikai függvény igazságtáblázatát:

// kata(A,B) = ( A ∧ ( A ⊃ B) ) 

function imp(x,y) {
 var a=Boolean(x), b=Boolean(y);
 var c=!a || b;
 return Number(c);
 }

function kata(x,y) {
 var a=Boolean(x), b=Boolean(y);
// var c=a && imp(x,y);
// var c=a && imp(a,b);
 var c=a && (!a || b);
 return Number(c);
 }

writeln("A"+" " +"B"+" "+"(A k B)");
writeln("-----------");

for(i=0;i<=1;i++) {
 for(j=0;j<=1;j++) {
  writeln(i+" " +j+"    "+kata(i,j));
  }
 }

writeln("--------------------------");

Végül egy összetettebb példa: készítsük el az mp(A,B) = ( A ∧ ( A ⊃ B) ) ⊃. B logikai függvény igazságtáblázatát, valamint Quine-táblázatát:

// mp(A,B) = ( A ∧ ( A ⊃ B) ) ⊃. B (modus ponens)

function imp(x,y) {
 var a=Boolean(x), b=Boolean(y);
 var c=!a || b;
 return Number(c);
 }

function mp(x,y) {
 var a=Boolean(x), b=Boolean(y);
 var c=!(a && (!a || b)) || b;
 return Number(c);
 }

writeln("A"+" " +"B"+" "+"mp(A,B)");
writeln("-----------");

for(i=0;i<=1;i++) {
 for(j=0;j<=1;j++) {
  writeln(i+" " +j+"     "+mp(i,j));
  }
 }

writeln("--------------------------------------------------");

writeln("( A ∧ ( A ⊃ B) ) ⊃. B");
writeln("-----------");

for(i=0;i<=1;i++) {
 for(j=0;j<=1;j++) {
  writeln(" "+
         i+" " +
         Number(i && imp(i,j))+"  "+  
         i+" "+
         imp(i,j)+" "+
         j+" | "+
         mp(i,j)+" | "+
         j);
  }
 }

writeln("--------------------------------------------------");

Megjegyzések:

(I.) Az mp(A,B) = ( A ∧ ( A ⊃ B) ) ⊃. B logikai függvény Quine-táblázatában a belső ( A ∧ ( A ⊃ B) ) konjunkciót (i && imp(i,j)) módon állíthatjuk elő (A ↔ i, B ↔ j), mert az 'i' ciklusváltozó 0 vagy 1 értékű szám, amelyet a && logikai operátor használata miatt a JavaScript interpreter automatikusan logikai (Boolean) értékké alakít át. Azonban a kifejezés értéke logikai érték (true vagy false) lesz, amit a táblázatban számként (1 vagy 0) akarunk megjeleníteni, tehát a logikai kifejezés értékét számmá kell alakítanunk Number(Boolean(i) && imp(i,j)) módon.

(II.) A modus ponens következtetési szabálynak megfelelő logikai törvény levezethető a logikai azonosságokból:

( A ∧ ( A ⊃ B) ) ⊃. B ~ ( A ∧ ( A ∨ B) ) ⊃. B (az implikáció átalakítása)
( A ∧ ( A ∨ B) ) ⊃. B ~ ( ( A ∧ A ) ∨ ( A ∧ B) ) ⊃. B (disztributivitás)
( ( A ∧ A ) ∨ ( A ∧ B) ) ⊃. B ~ ( A ∧ B ) ⊃. B (az ellentmondás törvénye és a ⊥ ∨ P ~ P kiszámítási törvény)
( A ∧ B ) ⊃. B ~ ( A ∧ B ) ∨ B (az implikáció átalakítása)
( A ∧ B ) ∨ B ~ ( A ∨ B ) ∨ B (De Morgan-azonosság)
( A ∨ B ) ∨ B ~ A ∨ ( B ∨ B ) (asszociativitás)
A ∨ ( B ∨ B ) ~ (a kizárt harmadik törvénye és a P ∨ ⊤ ~ ⊤ kiszámítási törvény).

Vagyis az mp(A,B) = ( A ∧ ( A ⊃ B) ) ⊃. B logikai függvény tautológia.


összehasonlító operátorok

matematikai állandók, függvények (Math osztály)

// kör kerülete és területe

var kor_sugara, x,xk,xt;

kor_sugara=4;
xk=(2*kor_sugara*Math.PI);

writeln("kerület = "+xk);
x=Math.round(xk*100)/100;
// x=xk.toFixed(2);
writeln("kerület (közelítőleg) = "+x);

writeln("--------------------------------------------------");

xt=kor_sugara*kor_sugara*Math.PI;
writeln("terület = "+xt);
x=Math.round(xt*100)/100;
// x=xt.toFixed(2);
writeln("terület (közelítőleg) = "+x);

writeln("--------------------------------------------------");

karakterláncokkal kapcsolatos függvények, operátorok, elemváltozók, metódusok (String osztály)

// betűk kiírása egymás alá

var s;
var idezojel="?"; // stringen belül nem lehet közvetlenül megadni
var i;

s="Hello!";
for(i=0;i<s.length;i++){
 writeln(s.charAt(i));
 }

writeln("--------------------------------------------------");

// betűk kiírása egymás mellé, szóközzel elválasztva

s="HELLO-BELLO";
for(i=0;i<s.length;i++){
 write(s.charAt(i)+" "); 
 }

writeln();
writeln("--------------------------------------------------");

// az idézőjel kódját megnéztük a Google-val (34 vagy 0x22)
// idezojel=String.fromCharCode(34);
idezojel="\u0022";

s="alma kajszibarack";
// writeln("Az \""+s+"\" string hossza: "+s.length);
writeln("Az "+idezojel+s+idezojel+ " string hossza: "+s.length);

writeln("--------------------------------------------------");

i=0;
while(i<s.length) {
writeln("Az "+idezojel+
 s.substring(0,4)+"..."+
 idezojel+
 " string "+i+"-dik karaktere: "+
 s.charAt(i));
 i++;
 }

writeln("--------------------------------------------------");

adatok bevitele és kiírása

Egy egyszerű táblázat
1 2
3 4

Egy egyszerű bekezdés

adatok bevitele

adatok kiírása


vezérlési szerkezetek

utasításblokkok

függvények

ciklusok

Hozzuk létre a 'szamok' tömböt pl. var szamok=[1,4,3,2]; módon!

// egyszerű ciklusok

var i,m,n,s;

writeln("első 5 természetes szám (while):\n"); 

i=1;
while(i<=5) {
 writeln(i);
 i++;
 }

writeln("--------------------------------------------------");

writeln("első 5 természetes szám (for):\n"); 
for(i=1;i<=5;i++) {
 writeln(i);
 }

writeln("--------------------------------------------------");

m=3;
n=10;
writeln("'m' és 'n' közötti természetes számok:\n"); 
for(i=m;i<=n;i++) {
 writeln(i);
 }

writeln("--------------------------------------------------");

s="A";
writeln("sok 'A' kiírása:\n"); 
i=0;
while(i<5){
 writeln((i+1)+"-dik ismétlés: "+s);
 s+="A";
 i++; 
 }

writeln("--------------------------------------------------");

elágazások

// páros számok kiíratása

var i,n=10;

for(i=1;i<=n;i++) {
 if(i%2==0) {
  writeln(i);
  }
 }

writeln("--------------------------------------------------");

// hárommal osztható számok kiíratása

for(i=1;i<=n;i++) {
 if(i%3==0) {
  writeln(i);
  }
 }

writeln("--------------------------------------------------");

// hárommal osztható páros számok kiíratása

for(i=1;i<=n;i++) {
 if(i%2==0 && i%3==0) {
  writeln(i);
  }
 }

writeln("--------------------------------------------------");

Irodalomjegyzék

Moncur, Michael 2006. Tanuljuk meg a JavaScript használatát 24 óra alatt. [SAMS Teach Yourself HTML and CSS in 24 Hours.] Budapest: Kiskapu.

Suehring, Steven; Valade, Janet 2014. PHP, MySQL, JavaScript és HTML5. Budapest: Panem K. (Tantusz könyvek)

Internetes források

Online JavaScript Interpreter by Peter Jipsen, Chapman University (January 2013).
http://math.chapman.edu/~jipsen/js/ (2018-12-12)

W3Schools Online Web Tutorials.
https://www.w3schools.com/ (2018-11-23)

JavaScript Tutorial.
https://www.w3schools.com/js/ (2018-12-12)

JavaScript and HTML DOM Reference.
https://www.w3schools.com/jsref/default.asp (2018-12-12)

JavaScript Global Reference.
https://www.w3schools.com/jsref/jsref_obj_global.asp (2018-12-12)

JavaScript - Wikipédia.
https://hu.wikipedia.org/wiki/JavaScript (2020-03-22)

A JavaScript programozási nyelv. (Programnyelvek portál.)
http://nyelvek.inf.elte.hu/leirasok/JavaScript/index.php?chapter=24 (2018-12-12)

Számsorozat fogalma | | Matekarcok.
https://matekarcok.hu/szamsorozat-fogalma/ (2020-03-27)


Boda István, 2018.