III. Vezérlések 2: Ciklusok

A ciklusok

A ciklusok adják a programozás magját. Alapvetően 3 fajtája van (a 4. a forEach, de ez majd csak később lesz):

  • while
  • do
  • for

A while ciklus

Előltesztelős ciklus. Addig fut a ciklus, amíg a feltétel hamis nem lesz. VIGYÁZAT: végtelen ciklusba kerülhetünk, ha nem vigyázzunk a feltétel helyes beállítására. Általános szerkezete:

while (feltétel) {
  // utasitasok
  // feltétel modositas
}

Példa a while ciklusra: Írjuk ki a képernyőre a számokat 0 - 10 -ig! Megoldás:

<html>
<head>
<title>while ciklus</title>
</head>
<body>
<script type="text/javascript">
var i=0; // szamlalo inicializalasa
while ( i < 11 ){ // a feltetel ellenorzese
	document.writeln(i);
    i++; // szamlalo novelese
} 
 </script>

</body>
</html>

A do ciklus

Hátultesztelős ciklus. Addig fut a ciklus, amíg a feltétel hamis nem lesz. VIGYÁZAT: végtelen ciklusba kerülhetünk, ha nem vigyázzunk a feltétel helyes beállítására. Általános szerkezete:

do{
  // utasitasok
  // feltétel modositas
} while(feltétel)

Példa a do ciklusra: Írjuk ki a képernyőre a számokat 0 - 10 -ig! Megoldás:

<html>
<head>
<title>do ciklus</title>
</head>
<body>
<script type="text/javascript">
var i=0; // szamlalo inicializalasa
do{ 
	document.writeln(i);
	i++; // szamlalo novelese
} while ( i < 11 ) // a feltetel ellenorzese
 </script>

</body>
</html>

A for ciklus

Adott kezdőértéktől, adott végértékig egy változót növelünk, és ellenőrizzük, hogy mikor teljesül a végérték feltétele. Általános szerkezete:

for (inicializalas; feltetel; noveles/csokkenes){
  // utasitasok
} 

Példa a for ciklusra: Írjuk ki a képernyőre a számokat 0 - 10 -ig! Megoldás:

<html>
<head>
<title>for ciklus</title>
</head>
<body>
<script type="text/javascript">
for(var i = 0; i < 11; i++)
{
    document.writeln(i);
}
</script>

</body>
</html>

1. Példa: átlagszámítás, egy adott tömbben lévő számok átlagának kiszámítása

<html>
<head>
<meta charset="utf-8" />
<title>Átlagszámítás</title>
</head>
<body>
<script type="text/javascript">
var szamok = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var osszeg = 0.0;
var atlag = 0.0;
for(var i = 0; i < szamok.length; i++)
{
	osszeg += szamok[i];
}
atlag = osszeg / szamok.length;
document.writeln("A számok átlaga: "+ atlag);
</script>

</body>
</html>

2. Példa: mennyi az összege a 1 + 1/2 + 1/4 + 1/8 + ... + 1 /2n sornak?

<html>
<head>
<meta charset="utf-8" />
<title>sorösszeg</title>
</head>
<body>
<script type="text/javascript">
var osszeg = 0.0;
var maximum = 1000;
for(var i = 0; i < maximum; i++)
{
	osszeg += 1.0/Math.pow(2,i);
}

document.writeln("A számok átlaga: "+ osszeg);
</script>

</body>
</html>

Matematikai függvények

Method Description
abs(x) Returns the absolute value of x
acos(x) Returns the arccosine of x, in radians
asin(x) Returns the arcsine of x, in radians
atan(x) Returns the arctangent of x as a numeric value between -PI/2 and PI/2 radians
atan2(y, x) Returns the arctangent of the quotient of its arguments
ceil(x) Returns the value of x rounded up to its nearest integer
cos(x) Returns the cosine of x (x is in radians)
exp(x) Returns the value of Ex
floor(x) Returns the value of x rounded down to its nearest integer
log(x) Returns the natural logarithm (base E) of x
max(x, y, z, ..., n) Returns the number with the highest value
min(x, y, z, ..., n) Returns the number with the lowest value
pow(x, y) Returns the value of x to the power of y
random() Returns a random number between 0 and 1
round(x) Returns the value of x rounded to its nearest integer
sin(x) Returns the sine of x (x is in radians)
sqrt(x) Returns the square root of x
tan(x) Returns the tangent of an angle

3. Példa: Döntsük el, hogy egy szám teljesnégyzet-e.

<html>
<head>
<meta charset="utf-8" />
<title>teljesnegyzet</title>
</head>
<body>
<script type="text/javascript">
var szam=prompt("Kérek egy egész számot!");
var ok = 1;
for(i=1; i*i<=szam  ; i++)
{
	if(i*i == szam)
	{
		document.writeln("A szám teljes négyzet!");
		ok = 0;
	}
}
		
if(ok == 1)
	document.writeln("A szám nem teljes négyzet!");
</script>
</body>
</html>

4. Példa: Döntsük el, hogy egy szám prímszám-e.

<html>
<head>
<meta charset="utf-8" />
<title>primszam</title>
</head>
<body>
<script type="text/javascript">
var szam=prompt("Kérek egy egész számot!");
var ok = 1;
if(szam == 2)
{
    document.writeln("A szám prímszám!");
} else {
    if(szam % 2 == 0)
	{
	    document.writeln("A szám nem prímszám!");
	} else {
	    for(i=3; i*i<=szam  ; i+=2)
		{
			if(szam % i == 0)
			{
			    document.writeln("A szám nem prímszám!");
				ok = 0;
			}
		}
		
		if(ok == 1)
			document.writeln("A szám prímszám!");
	}
}
</script>
</body>
</html>

A break és continue utasítás

Vegyük a prímszám meghatározásának a példáját. Legyen a kérdéses szám a 81. A 81 osztható 3-mal (= 27), azaz mar a for ciklus legelső iterációjában tudjuk, hogy nem prímszám, de a ciklus nem áll le, hanem megy tovább 9-ig. Ezért is jelenik meg a 'A szám nem prímszám!' kétszer. Ez felesleges iterációkat jelent, azaz le kéne állítani az iterációt már 3-nál. Erre szolgál a break parancs. A continue paranccsal kihagyhatunk egy iterációs ciklust.


break megszakítja a szülő (azaz a felette elhelyezkedő) ciklust, de csak azt
continue a következő iterációs cilkura ugrik

A megszakításra felhasználható még a goto parancs, amivel a kódban ugrálhatunk, de mivel ezáltal a kód átláthatatlan lesz, a legtöbb helyen tiltják a használatát. Legjobb, ha elfelejtük a létezését.

A 4. példában lévő for ciklus megszakítása break paranccsal:


	for(i=3; i*i<=szam  ; i+=2)
	{
		if(szam % i == 0)
		{
			document.writeln("A szám nem prímszám!");
			ok = 0;
			break;
		}
	}

Egy másik módja is van a for ciklus megszakításának, hamár ugyis ott van az 'ok' változó


    var ok = 1;
	for(i=3; i*i<=szam && ok; i+=2)
	{
		if(szam % i == 0)
		{
			document.writeln("A szám nem prímszám!");
			ok = 0;
			break;
		}
	}

Ciklusok egymásba ágyazása

Természetesen nem csak egy ciklusváltozón futhatunk végig, tetszőleges számú for ciklust lehet egymásba ágyazni. Példa:

<html>
<head>
<meta charset="utf-8" />
<title>sor-oszop kiiratas</title>
</head>
<body>
<script type="text/javascript">
var sor = 6;
var oszlop = 4;

for(var i = 1; i <= sor; i++)
{
   for(var j = 1; j <= oszlop; j++)
   {
		document.write(i+". sor "+j+". oszlop || ");
   }
   document.write("<br>");
}
</script>
</body>
</html>

A break parancs bemutatása futtaható példával. 10 sor és 10 oszlop kiiratása, de a páros sorok csak 5 oszlopot tartalmazzanak! Látható, hogy a break parancs csak a j futtó indexű ciklust szakítja meg.

<html>
<head>
<meta charset="utf-8" />
<title>sor-oszop kiiratas</title>
</head>
<body>
<script type="text/javascript">
var sor = 10;
var oszlop = 10;

for(var i = 1; i <= sor; i++)
{
   for(var j = 1; j <= oszlop; j++)
   {
		if(i % 2 == 0 && j > 5)
			break;
			
		document.write(i+". sor "+j+". oszlop || ");
   }
   document.write("<br>");
}
</script>
</body>
</html>

A continue parancs bemutatása futtaható példával. 10 sor és 10 oszlop kiiratása, de a páros sorok csak páros indexű oszlopot tartalmazzanak!

<html>
<head>
<meta charset="utf-8" />
<title>sor-oszop kiiratas</title>
</head>
<body>
<script type="text/javascript">
var sor = 10;
var oszlop = 10;

for(var i = 1; i <= sor; i++)
{
   for(var j = 1; j <= oszlop; j++)
   {
		if(i % 2 == 0 && j % 2 != 0)
			continue;
			
		document.write(i+". sor "+j+". oszlop || ");
   }
   document.write("<br>");
}
</script>
</body>
</html>

Három alkalmazás

1. alkalmazás: egyedi elemeket megkeresése. Adott egy számhalmaz, kérdés, hogy milyen egyedi elemek találhatóak ebben a számhalmazban.

<html>
<head>
<meta charset="utf-8" />
<title>Egyedi elemeket megkeresese</title>
</head>
<body>
<script type="text/javascript">
var szamok =[13,16,39,38,40,4,5,11,46,17,22,31,31,44,1,37,37,2,14,45,8,33,13,9,50,27,34,28,3,160,20,40,45,46,12,46,8,27,28,37,27,10,48,42,7,12,44,5,13,42,12,
38,20,13,21,1,41,3,5,40,6,143,25,15,7,37,4,38,32,19,49,48,3,441,40,7,44,12,130,34,23,33,39,43,26,41,46,50,47,31,9,25,40,11,12,29,17,14,21,47,150,23,29,42,14,
39,33,8,33,9,21,49,38,25,10,10,29,15,44,44,200,5,43,1,22,39,6,36,22,40,48,34,21,38,45,8,17,49,47,48,280,5,2,21,29,39,12,2,11,26,21,25,17,17,27,11,41,49,45,31,
18,35,1,18,13,40,35,19,37,46,14,6,28,45,45,18,17,22,3,44,42,24,920,10,35,22,5,5,25,7,9,10,33,16,10,31,5,28,42,49];
// kerdes: milyen számok talalhatoak ebben a tombben

var egyediszamok = [];
var vanmar = false;

for(var i = 0; i < szamok.length; i++)
{
	vanmar = false;
	for(var j = 0; j < egyediszamok.length; j++)
	{
		if(egyediszamok[j] == szamok[i])
		{
			vanmar = true;
			break;
		}
	}
	
	if(vanmar == false)
		egyediszamok.push(szamok[i]);
}

document.write(egyediszamok);

</script>
</body>
</html>

2. alkalmazás: egyedi elemek eloszlásának meghatározása. Adott egy számhalmaz, kérdés, hogy milyen egyedi elemek találhatóak ebben a számhalmazban és ezen egyedi elemek hányszor fordul elő a tömbben. Konkrét feladat: adott egy 200 elemű tömb, ami valós számokat tartalmaz a [0, 50) intervalumban. Hány darab szám talalható ebben a tömbben [0,1), [1, 2), [2, 3), ..., [49, 50) intervallumokban?

A legegyszerűbb, ám legcsunyább megoldás (ami kb. kivitelezhetetlen is)

<html>
<head>
<meta charset="utf-8" />
<title>Egyedi elemeket eloszlasa</title>
</head>
<body>
<script type="text/javascript">
var szamok = [27.18,20.67,38.26,41.38,44.78,6.82,14.47,7.58,10.30,36.86,1.25,49.46,10.72,7.12,21.78,38.51,19.10,16.98,0.51,11.73,36.75,4.87,15.33,20.30,42.46,22.62,
21.73,37.27,3.28,3.42,31.54,47.98,44.68,2.92,32.50,13.83,6.07,31.27,40.69,10.07,37.53,42.59,26.11,47.06,1.89,20.14,16.36,34.99,41.43,30.90,2.34,1.96,
29.32,42.86,10.82,42.52,36.07,34.67,21.38,41.28,48.78,46.63,23.43,32.21,4.50,18.15,14.44,46.54,25.66,21.21,24.61,41.89,42.58,41.46,46.30,39.43,48.12,
6.34,17.41,28.84,22.92,49.03,49.17,0.46,26.82,26.88,44.98,0.71,18.11,11.79,34.17,49.24,18.37,11.89,26.84,2.68,25.07,40.42,43.27,48.23,48.61,15.57,
24.51,26.10,47.93,16.49,4.09,6.07,25.25,27.29,21.25,10.23,5.43,1.90,13.41,22.92,18.87,17.30,6.29,14.81,18.61,33.22,7.14,0.11,27.95,38.07,42.36,11.81,
49.40,28.77,44.32,5.80,35.68,2.06,40.57,8.25,6.98,22.91,4.69,38.50,35.29,40.91,33.90,49.29,5.62,11.52,34.34,13.20,4.07,5.82,11.20,18.84,29.71,43.49,
37.29,20.07,34.56,37.21,1.40,6.10,2.24,41.16,19.15,17.93,49.35,32.38,32.46,11.50,9.80,30.74,15.23,36.99,12.66,36.11,16.10,22.66,20.26,11.98,15.00,
13.26,10.89,36.19,8.18,12.37,19.19,0.81,13.07,46.79,30.94,10.99,4.22,8.16,33.56,17.63,22.80,34.90,6.65,44.16,42.55,40.37];

// tudjuk, hogy 50 intervallum van, letrehozunk egy 50-es tombot nullakkal

var darabszam = [];
for(var i = 0; i < 50; i++)
	darabszam.push(0);
	
for(var i = 0; i < szamok.length; i++)
{
	if(szamok[i] < 1.0)
	   darabszam[0]++;
	   
	if(szamok[i] >= 1.0 && szamok[i] < 2.0)
	   darabszam[1]++;  
	   
	if(szamok[i] >= 2.0 && szamok[i] < 3.0)
	   darabszam[2]++; 
	   
	if(szamok[i] >= 3.0 && szamok[i] < 4.0)
	   darabszam[3]++; 
	   
	if(szamok[i] >= 4.0 && szamok[i] < 5.0)
	   darabszam[4]++; 
	   
	 // akinek van kedve folytassa
}
document.write(darabszam);
</script>
</body>
</html>

Jobb lenne az if-ket is egy for ciklusba szerveznénk

<html>
<head>
<meta charset="utf-8" />
<title>Egyedi elemeket eloszlasa</title>
</head>
<body>
<script type="text/javascript">
var szamok = [27.18,20.67,38.26,41.38,44.78,6.82,14.47,7.58,10.30,36.86,1.25,49.46,10.72,7.12,21.78,38.51,19.10,16.98,0.51,11.73,36.75,4.87,15.33,20.30,42.46,22.62,
21.73,37.27,3.28,3.42,31.54,47.98,44.68,2.92,32.50,13.83,6.07,31.27,40.69,10.07,37.53,42.59,26.11,47.06,1.89,20.14,16.36,34.99,41.43,30.90,2.34,1.96,
29.32,42.86,10.82,42.52,36.07,34.67,21.38,41.28,48.78,46.63,23.43,32.21,4.50,18.15,14.44,46.54,25.66,21.21,24.61,41.89,42.58,41.46,46.30,39.43,48.12,
6.34,17.41,28.84,22.92,49.03,49.17,0.46,26.82,26.88,44.98,0.71,18.11,11.79,34.17,49.24,18.37,11.89,26.84,2.68,25.07,40.42,43.27,48.23,48.61,15.57,
24.51,26.10,47.93,16.49,4.09,6.07,25.25,27.29,21.25,10.23,5.43,1.90,13.41,22.92,18.87,17.30,6.29,14.81,18.61,33.22,7.14,0.11,27.95,38.07,42.36,11.81,
49.40,28.77,44.32,5.80,35.68,2.06,40.57,8.25,6.98,22.91,4.69,38.50,35.29,40.91,33.90,49.29,5.62,11.52,34.34,13.20,4.07,5.82,11.20,18.84,29.71,43.49,
37.29,20.07,34.56,37.21,1.40,6.10,2.24,41.16,19.15,17.93,49.35,32.38,32.46,11.50,9.80,30.74,15.23,36.99,12.66,36.11,16.10,22.66,20.26,11.98,15.00,
13.26,10.89,36.19,8.18,12.37,19.19,0.81,13.07,46.79,30.94,10.99,4.22,8.16,33.56,17.63,22.80,34.90,6.65,44.16,42.55,40.37];
	
var darabszam = [];
for(var i = 0; i < 50; i++)
	darabszam.push(0);
	
for(var i = 0; i < szamok.length; i++)
{
	for(var j = 0; j < 50; j++)
	{
		if(szamok[i] >= j && szamok[i] < j+1)
		{
			darabszam[j]++;
			break;
		}
	} 
}


document.write(darabszam);
</script>
</body>
</html>

Gondolkodtató feladat: Írd át a fenti algoritmust úgy, hogy csak egy for ciklust tartalmaz és nincs benne if sem, azaz:

<html>
<head>
<meta charset="utf-8" />
<title>Egyedi elemeket eloszlasa</title>
</head>
<body>
<script type="text/javascript">
var szamok = [27.18,20.67,38.26,41.38,44.78,6.82,14.47,7.58,10.30,36.86,1.25,49.46,10.72,7.12,21.78,38.51,19.10,16.98,0.51,11.73,36.75,4.87,15.33,20.30,42.46,22.62,
21.73,37.27,3.28,3.42,31.54,47.98,44.68,2.92,32.50,13.83,6.07,31.27,40.69,10.07,37.53,42.59,26.11,47.06,1.89,20.14,16.36,34.99,41.43,30.90,2.34,1.96,
29.32,42.86,10.82,42.52,36.07,34.67,21.38,41.28,48.78,46.63,23.43,32.21,4.50,18.15,14.44,46.54,25.66,21.21,24.61,41.89,42.58,41.46,46.30,39.43,48.12,
6.34,17.41,28.84,22.92,49.03,49.17,0.46,26.82,26.88,44.98,0.71,18.11,11.79,34.17,49.24,18.37,11.89,26.84,2.68,25.07,40.42,43.27,48.23,48.61,15.57,
24.51,26.10,47.93,16.49,4.09,6.07,25.25,27.29,21.25,10.23,5.43,1.90,13.41,22.92,18.87,17.30,6.29,14.81,18.61,33.22,7.14,0.11,27.95,38.07,42.36,11.81,
49.40,28.77,44.32,5.80,35.68,2.06,40.57,8.25,6.98,22.91,4.69,38.50,35.29,40.91,33.90,49.29,5.62,11.52,34.34,13.20,4.07,5.82,11.20,18.84,29.71,43.49,
37.29,20.07,34.56,37.21,1.40,6.10,2.24,41.16,19.15,17.93,49.35,32.38,32.46,11.50,9.80,30.74,15.23,36.99,12.66,36.11,16.10,22.66,20.26,11.98,15.00,
13.26,10.89,36.19,8.18,12.37,19.19,0.81,13.07,46.79,30.94,10.99,4.22,8.16,33.56,17.63,22.80,34.90,6.65,44.16,42.55,40.37];
	
var darabszam = [];
for(var i = 0; i < 50; i++)
	darabszam.push(0);
	
for(var i = 0; i < szamok.length; i++)
{
	// ide jon a kod, nincs se if, se for ciklus, megis ugyanaz az eredmeny, mint a fenti peldaban
}

document.write(darabszam);
</script>
</body>
</html>

3. alkalmazás: párképzés: adott két tömb(kis és nagy), a kis tömb elemit kell megtalálni a nagy tömbben. Feltételek: minden kis tömb elemnek kell lennie párnak, egy nagy tömb elemet csak egy kis tömb elemhez lehet rendelni (és fordítva), a maximális eltérés 0.5 lehet.
1. konkrét példa:
nagytomb = [1.0, 2.0, 2.5, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0]
kistomb = [2.2, 2.3, 3.1, 6.3, 7.2, 8.4]

<html>
<head>
<meta charset="utf-8" />
<title>parkepzes</title>
</head>
<body>
<script type="text/javascript">
var nagytomb = [1.0, 2.0, 2.5, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0];
var kistomb = [2.2, 2.3, 3.1, 6.3, 7.2, 8.4];

var match;
var mindiff;

for(var i = 0; i < kistomb.length; i++)
{
	mindiff = 1000.0;
	for(var j = 0; j < nagytomb.length; j++)	
	{
		if(Math.abs(kistomb[i] - nagytomb[j]) < 0.5)
		{
			if(mindiff > Math.abs(kistomb[i] - nagytomb[j]))
			{
				match = j;
				mindiff =  Math.abs(kistomb[i] - nagytomb[j]);
			}
		}
	}
	document.write(kistomb[i]+ " párja: "+nagytomb[match]+"<br>");
	
}

</script>
</body>
</html>
2. konkrét példa:
nagytomb = [1.0, 2.0, 2.5, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0]
kistomb = [2.2, 2.22, 3.1, 6.3, 7.2, 8.4]

<html>
<head>
<meta charset="utf-8" />
<title>parkepzes</title>
</head>
<body>
<script type="text/javascript">
var nagytomb = [1.0, 2.0, 2.5, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0];
var kistomb = [2.2, 2.22, 3.1, 6.3, 7.2, 8.4];

var foglalt = [];

for(var j = 0; j < nagytomb.length; j++)
   foglalt.push(0);
  
var match;
var mindiff;

for(var i = 0; i < kistomb.length; i++)
{
	mindiff = 1000.0;
	for(var j = 0; j < nagytomb.length; j++)	
	{
		if(Math.abs(kistomb[i] - nagytomb[j]) < 0.5 && foglalt[j] == 0)
		{
			if(mindiff > Math.abs(kistomb[i] - nagytomb[j]))
			{
			    foglalt[j] = 1;
				match = j;
				mindiff =  Math.abs(kistomb[i] - nagytomb[j]);
			}
		}
	}
	document.write(kistomb[i]+ " párja: "+nagytomb[match]+"<br>");
}

</script>
</body>
</html>