Programozási tételekipari118-szerencs.sulinet.hu/jegyzet/info/Programozási...Programozási...

63
2015 PROGRAMOZÁSI TÉTELEK Java nyelven Nagy Zsolt Informatika Szakközépiskolai képzés

Transcript of Programozási tételekipari118-szerencs.sulinet.hu/jegyzet/info/Programozási...Programozási...

Page 1: Programozási tételekipari118-szerencs.sulinet.hu/jegyzet/info/Programozási...Programozási tételek 10 – 11. évfolyam 3. oldal Programozási tételek, algoritmusok Az algoritmus

2015

PROGRAMOZÁSI TÉTELEK

Java nyelven

Nagy Zsolt

Informatika

Szakközépiskolai képzés

Page 2: Programozási tételekipari118-szerencs.sulinet.hu/jegyzet/info/Programozási...Programozási tételek 10 – 11. évfolyam 3. oldal Programozási tételek, algoritmusok Az algoritmus

Programozási tételek 10 – 11. évfolyam

1. oldal

Tartalom Programozási tételek, algoritmusok ....................................................................................................................... 3

Feldolgozás végjelig ............................................................................................................................................ 3

Egy sorozathoz egy érték rendelése ........................................................................................................................ 4 Megszámlálás tétele ........................................................................................................................................... 4

Összegzés tétele ................................................................................................................................................. 5

Átlagszámítás tétele ........................................................................................................................................... 6

Eldöntés tétele .................................................................................................................................................... 7

Kiválasztás tétele ................................................................................................................................................ 9

Gyakorlás .......................................................................................................................................................... 10

Minimum- / Maximum-kiválasztás ................................................................................................................... 12

Keresés tétele ................................................................................................................................................... 13

Lineáris keresés: rendezetlen sorozatban ........................................................................................................ 16

Lineáris keresés: rendezett sorozatban ............................................................................................................ 18

Bináris keresés .................................................................................................................................................. 19

Egy sorozathoz egy sorozat rendelése .................................................................................................................. 22 Másolás ............................................................................................................................................................. 22

Kiválogatás ........................................................................................................................................................ 23

Egy sorozathoz több sorozat rendelése ................................................................................................................ 24 Szétválogatás .................................................................................................................................................... 25

Gyakorlás (másolás, kiválogatás, szétválogatás) .............................................................................................. 28

Rendezések, rendezettség .................................................................................................................................... 28 Rendezettség .................................................................................................................................................... 28

Minimum-kiválasztásos rendezés ..................................................................................................................... 30

Maximum kiválasztásos rendezés..................................................................................................................... 34

Gyakorlás .......................................................................................................................................................... 34

Buborék rendezés ............................................................................................................................................. 41

Beszúrásos rendezés ......................................................................................................................................... 45

Rendezések összehasonlítása ........................................................................................................................... 46

Minimum-kiválasztásos rendezés ................................................................................................................. 46

Buborék rendezés ......................................................................................................................................... 46

Javított Buborékos rendezés ......................................................................................................................... 46

Beszúró rendezés .......................................................................................................................................... 46

Gyorsrendezés .............................................................................................................................................. 47

Kupacrendezés .............................................................................................................................................. 47

Halmazműveletek ................................................................................................................................................. 47 Metszetképzés tétele ........................................................................................................................................ 49

Unióképzés tétele ............................................................................................................................................. 52

Page 3: Programozási tételekipari118-szerencs.sulinet.hu/jegyzet/info/Programozási...Programozási tételek 10 – 11. évfolyam 3. oldal Programozási tételek, algoritmusok Az algoritmus

Programozási tételek 10 – 11. évfolyam

2. oldal

Különbség-képzés tétele ................................................................................................................................... 54

Rekurzió ................................................................................................................................................................ 56 Rekurzív függvények ......................................................................................................................................... 56

Rekurzív és iteratív forma ................................................................................................................................. 58

Gyorsrendezés (QuickSort) ............................................................................................................................... 60

Felhasznált és ajánlott irodalom ........................................................................................................................... 62

Page 4: Programozási tételekipari118-szerencs.sulinet.hu/jegyzet/info/Programozási...Programozási tételek 10 – 11. évfolyam 3. oldal Programozási tételek, algoritmusok Az algoritmus

Programozási tételek 10 – 11. évfolyam

3. oldal

Programozási tételek, algoritmusok Az algoritmus különböző feladatok megoldására szolgáló utasítások jó szervezett együttesét

jelenti. Jellemzői: véges, determinisztikus, teljes.

Az informatikai programozási tételek olyan alap algoritmusokat jelentenek, amelyek

különböző típusfeladatok általános megoldásait adják. Ezeket kis átalakítással alkalmazhatjuk

egy konkrét feladat megoldása során.

Fajtái:

sorozathoz érték rendelése,

sorozathoz sorozat rendelése,

sorozathoz több sorozat rendelése,

több sorozathoz egy sorozat rendelése.

Feldolgozás végjelig

Egy feladat többszöri végrehajtása során, az ismétlések meghatározására három eset

különböztethető meg:

végtelen számú ismétlés nincs leállító feltétel

meghatározott számú ismétlés a leállító feltétel az adott érték meghaladása

feltételtől függő ismétlés végfeltétel alkalmazása.

Az utóbbi két esetben beszélhetünk végjelről, vagy végértékről. Ez a végjel fogja leállítani a

feldolgozást. A végjelet sosem dolgozzuk fel. Fontos, hogy a végjelnek választott érték, ne

essen a feldolgozandó adatok értelmezési tartományába.

Alapvetően előfeltételes ciklussal szokás megoldani. Ugyanis lehetővé kell tenni, hogy már az

első alkalommal végjelet kapunk, és nem a sorozat első értékes elemét.

Az alapelv a következő: A ciklus előtt beolvassuk az első adatot (lehet végjel is), majd

előfeltételes ciklus feltételében megvizsgáljuk, hogy nem végjel-e. Amennyiben nem,

feldolgozzuk az adatot, majd újra beolvasást alkalmazunk. Abban az esetben, ha végjelet

kapunk (ez lehet az első eset is), vége az ismétlésnek. A ciklust követő utasítással folytatjuk a

programot.

Page 5: Programozási tételekipari118-szerencs.sulinet.hu/jegyzet/info/Programozási...Programozási tételek 10 – 11. évfolyam 3. oldal Programozási tételek, algoritmusok Az algoritmus

Programozási tételek 10 – 11. évfolyam

4. oldal

Algoritmus:

be: Adat

amíg Adat<>Végjel ismétel

Az adat feldolgozása

be: Adat

avége

Feladat:

Kérjük be egy kör sugarát, és számítsuk ki a kör területét és kerületét. A bekérést

addig végezzük, amíg a felhasználó nullát nem ad meg.

Egy sorozathoz egy érték rendelése Az algoritmus egy sorozatot dolgoz fel és egy értéket ad vissza.

Megszámlálás tétele

Adott egy N elemű A tömb. A feladat az, hogy számoljuk meg, hány T tulajdonságnak

megfelelő A(i) értéke van a tömbnek. Az A tömb elemek sorozatát tartalmazza. Az i értéke az

A tömb i. sorszámú értékét hivatkozza. A T(A(i)) tulajdonság (logikai függvény) egy {igaz,

hamis} értéket ad vissza, attól függően, hogy az A tömb i. értéke teljesíti-e a kitűzött feltételt.

A darabszámot egy Db változóban gyűjtjük.

A legegyszerűbb esetben a sorozat (A tömb) minden elemét megszámoljuk.

Algoritmus:

Db := 0

Ciklus i := 1-től N-ig

Ha T(A(i)) akkor Db := Db + 1

Ciklus vége

Ki: Db

Feladat:

Kérjünk be számokat nulla végjelig, majd határozzuk meg a darabszámot.

Feladat:

Határozzuk meg, hogy adott két szám között hány hárommal osztható szám van.

Pascal: szam MOD 3 = 0

Java: szam % 3 == 0

Feladat:

Határozzuk meg, hogy adott két szám között hány prímszám van.

Egy szám akkor prímszám, ha csak 1-el és önmagával osztható maradék nélkül. Az osztást

elég a szám négyzetgyökéig végezni.

Page 6: Programozási tételekipari118-szerencs.sulinet.hu/jegyzet/info/Programozási...Programozási tételek 10 – 11. évfolyam 3. oldal Programozási tételek, algoritmusok Az algoritmus

Programozási tételek 10 – 11. évfolyam

5. oldal

Java kód:

package primek;

public class Primek {

public static void main(String[] args) {

//2000-től 20001-ig keressük meg a prímszámokat!

int primekszama = 0;

for (int n = 2000; n <= 20001; n++) {

int i = 2;

double sq = Math.sqrt(n);

while ((n%i != 0) && (i <= sq)) {

i++;

}

if (i > sq) {

primekszama++;

//Kiíratásnál csak 15 számot írunk egy sorba.

if (primekszama % 15 != 0){

System.out.print(n+", ");

}

else {

System.out.println();

System.out.print(n+", ");

}

}

}

System.out.println("");

System.out.println("Primek száma 2000 és 20000 között:

"

+primekszama+" darab.");

}

}

Összegzés tétele

Határozzuk meg egy számsorozat összegét. A számsorozatot egy N elemű A tömb

tartalmazza.

Algoritmus:

S := 0

Ciklus i := 1-től N-ig

S := S + A(i)

Ciklus vége

Ki: S

A sorozat összegét az S változó fogja tartalmazni, amit az összegzés előtt nullázni kell. A

sorozat elemein (az A tömbön), az i változó segítségével megyünk végig.

Feladat:

Olvassunk be számokat nulla végjelig, majd írjuk ki a számok összegét.

Az összegzéshez hasonló művelet még: A(i) elemek esetén, ahol A, a számokat tartalmazó

tömb, i = {1..N} természetes szám, az A tömb elemszáma.

a szorzat számítás: A(i)*A(i+1)*…*A(N-1)*A(N),

Page 7: Programozási tételekipari118-szerencs.sulinet.hu/jegyzet/info/Programozási...Programozási tételek 10 – 11. évfolyam 3. oldal Programozási tételek, algoritmusok Az algoritmus

Programozási tételek 10 – 11. évfolyam

6. oldal

számtani közép (átlag) számítás: (A(i)+A(i+1)+…+A(N-1)+A(N)) / N

mértani közép: N√(A(i)*A(i+1)*…*A(N-1)*A(N)) N. gyök alatt egy szorzat

Feladat:

Számítsuk ki egy adott n nemnegatív egész szám faktoriálisát (n!).

Java-kód:

package faktorialis;

import java.util.Scanner;

public class Faktorialis {

public static void main(String[] args) {

Scanner be = new Scanner(System.in);

System.out.println("Faktoriális");

System.out.print("Szám: ");

int szam = be.nextInt();

int n;

//-1 végjelig folytatjuk

while(szam != -1){

if(szam < 0)

System.out.println("Csak nemnegatív számnak van

faktoriálisa!");

else {

n = fakt(szam);

System.out.println(szam+" faktoriálisa: "+n);

}

System.out.print("Szám: ");

szam = be.nextInt();

}

}

//Faktoriálist számító metódus

public static int fakt(int sz){

int n = 1;

if(sz == 0)

return 1;

else{

while(sz > 0){

n *= sz;

sz--;

}

return n;

}

}

}

Átlagszámítás tétele

Átlagszámításkor egyszerre kell elvégezni a megszámlálást és az összegképzést, majd

elosztani az összeget a darabszámmal. Viszont az átlagszámítást csak abban az esetben szabad

végrehajtani, ha volt átlagolandó adat, különben nullával osztanánk!

Page 8: Programozási tételekipari118-szerencs.sulinet.hu/jegyzet/info/Programozási...Programozási tételek 10 – 11. évfolyam 3. oldal Programozási tételek, algoritmusok Az algoritmus

Programozási tételek 10 – 11. évfolyam

7. oldal

Feladat:

Határozzuk meg két felhasználótól bekért szám közötti páros / páratlan számok

átlagát.

Eldöntés tétele

Az eldöntés tételével egy adott tulajdonságú elem meglétét akarjuk bizonyítani. Adott egy N

elemű A tömb. Továbbá adjunk meg egy olyan T tulajdonságot (logikai függvényt), amely

{igaz} értékkel jelzi, ha az A tömbnek van ilyen eleme.

A T logikai függvény tehát akkor ad vissza {igaz} értéket, ha az A tömb 1..N elemei között

találunk megfelelő elemet.

Algoritmus:

i := 1

Ciklus amíg (i <= N) és nem T(A(i)) i := i + 1

Ciklus vége

Ki: (i <= N)

Az elemek vizsgálatát az első elemtől kezdjük (i := 1), és lépegetünk sorba az elemeken (i := i

+ 1), amíg el nem érjük a tömb végét (i <= N), vagy nem találunk T tulajdonságú elemet

(nem T(A(i))). A visszatérési érték akkor lesz igaz, ha nem értük el tömb végét (i <= N).

Feladat:

Döntsük el, hogy egy szavakat tároló tömbben van-e olyan szó, amely palindróma

(tükörszó). Java: String str;

str.equals((new StringBuilder(str)).reverse().toString());

Feladat:

Kérjünk be egész számokat nulla végjelig, és határozzuk meg, hogy van-e közöttük

négyzetszám.

Egy egész szám pontosan akkor négyzetszám, ha négyzetgyöke (létezik, és) egész. Minden

négyzetszám nemnegatív.1

Tízes számrendszerben a négyzetszámok a következő végződésűek lehetnek: 00, 1, 4, 6, 9

vagy 25 a következő szabályok szerint:

Ha a szám utolsó számjegye 0, akkor a négyzete 00 végződésű és az azt megelőző

számjegyek is négyzetszámot alkotnak.

1 https://hu.wikipedia.org/wiki/Négyzetszámok

Page 9: Programozási tételekipari118-szerencs.sulinet.hu/jegyzet/info/Programozási...Programozási tételek 10 – 11. évfolyam 3. oldal Programozási tételek, algoritmusok Az algoritmus

Programozási tételek 10 – 11. évfolyam

8. oldal

Ha a szám utolsó számjegye 1 vagy 9, akkor a négyzete 1-re végződik és az azt

megelőző számjegyek 4-gyel osztható számot alkotnak.

Ha a szám utolsó számjegye 2 vagy 8, akkor a négyzete 4-re végződik és az azt

megelőző számjegyek páros számot alkotnak.

Ha a szám utolsó számjegye 3 vagy 7, akkor a négyzete 9-re végződik és az azt

megelőző számjegyek 4-gyel osztható számot alkotnak.

Ha a szám utolsó számjegye 4 vagy 6, akkor a négyzete 6-ra végződik és az azt

megelőző számjegyek páratlan számot alkotnak.

Ha a szám utolsó számjegye 5, akkor a négyzete 25-re végződik.

Java-kód:

package negyzetszam;

import java.util.Scanner;

import java.lang.Math;

public class NegyzetSzam {

public static void main(String[] args) {

Scanner be = new Scanner(System.in);

int szam;

System.out.println("Írj be egy számot, megmondom

nényzetszám-e!");

System.out.print("Szám = ");

while((szam = be.nextInt()) != 0){

if(isNegyzetSzam(szam))

System.out.println("Négyzetszám");

else

System.out.println("Nem négyzetszám");

System.out.print("Szám = ");

}

}

//logikai függvény

public static boolean isNegyzetSzam(int sz){

int e;

double d;

if(sz >= 0){

d = Math.sqrt(sz);

e = (int) Math.round(d);

return (e * e == sz);

}

else {

return false;

}

}

}

Page 10: Programozási tételekipari118-szerencs.sulinet.hu/jegyzet/info/Programozási...Programozási tételek 10 – 11. évfolyam 3. oldal Programozási tételek, algoritmusok Az algoritmus

Programozási tételek 10 – 11. évfolyam

9. oldal

Kiválasztás tétele

A kiválasztás tételével keresünk egy adott T() tulajdonsággal rendelkező elemet, vagy annak

az indexét (helyét a sorozaton belül). Tudjuk, hogy a tömbnek van T() tulajdonságú eleme. A

sorozatot egy N elemszámú A tömb reprezentálja. A T() függvény {igaz} értéket ad, ha a

sorozat i. eleme adott tulajdonságú.

Algoritmus:

i := 1

Ciklus amíg nem T(A(i))

i := i + 1

Ciklus vége

Ki: i, A(i)

A visszatérési érték tehát az A tömb i. eleme, vagy annak A(i) értéke.

Feladat:

70 és 200 között melyik az első 9-cel osztható szám. (Kilenccel osztható a szám, ha a

számjegyek összege osztható 9-cel.)

Java-kód:

package oszthatokilenc;

public class OszthatoKilenc {

public static void main(String[] args) {

System.out.println("A program 70 - 200 között megkeresi

"

+ "az első 9-cel osztható számot.");

for(int i = 70; i<= 200; i++){

if(isOszthatoKilenc(i)){

System.out.println("Az első kilenccel osztható

szám: "+i);

break;

}

}

}

public static boolean isOszthatoKilenc(int szam){

int m, ossz = 0;

while(szam != 0){

m = szam % 10;

szam /= 10;

ossz += m;

}

return (ossz % 9) == 0;

}

}

Feladat:

Határozzuk meg egy számtani sorozat mediánját (középértékét).

Page 11: Programozási tételekipari118-szerencs.sulinet.hu/jegyzet/info/Programozási...Programozási tételek 10 – 11. évfolyam 3. oldal Programozási tételek, algoritmusok Az algoritmus

Programozási tételek 10 – 11. évfolyam

10. oldal

Véges elemszámú sokaság esetén a medián a sorba rendezett adatok közül a középső érték;

vagy másképpen: a medián az az érték, amely a sorba rendezett adatokat két egyenlő részre

osztja. Ha a sokaság elemeinek száma páratlan, akkor az iménti meghatározás egyértelmű,

mert akkor van egy középső adat, amely előtt ugyanannyi adat van, mint utána. Páros számú

elem esetén két középső adat van, ez esetben a kettő közti bármelyik érték mediánnak

tekinthető. A gyakorlatban a két érték számtani közepét szokták megadni.2

Páratlan elemszám esetén:

1 2 5 4 3 1 4 3 3 4 3 5 1

A rendezett sokaság:

1 1 1 2 3 3 3 3 4 4 4 5 5

A medián a középső elem:

1 1 1 2 3 3 3 3 4 4 4 5 5

Páros elemszám esetén:

1 4 2 4 2 3 5 3 1 1

A rendezett sokaság:

1 1 1 2 2 3 3 4 4 5

A medián a középső elemek számtani közepe: 2,5.

Gyakorlás

Feladat:

Határozzuk meg két szám legnagyobb közös osztóját.

Leírás:3

Két (nem egyszerre nulla) egész szám közös osztói közül a lehetséges legnagyobb nem nulla

pozitív egész, amely mindkét egész számot (maradék nélkül) osztja.

Az euklideszi algoritmus egy számelméleti algoritmus, mellyel két szám legnagyobb közös

osztója határozható meg.

Legyen:

2 https://hu.wikipedia.org/wiki/Medián 3 Forrás: http://hu.wikipedia.org/wiki/Euklideszi_algoritmus

Page 12: Programozási tételekipari118-szerencs.sulinet.hu/jegyzet/info/Programozási...Programozási tételek 10 – 11. évfolyam 3. oldal Programozási tételek, algoritmusok Az algoritmus

Programozási tételek 10 – 11. évfolyam

11. oldal

Az algoritmus első lépésében maradékosan osztjuk -t -vel, a második lépésben -t a

maradékkal, majd az előbbi maradékot az új maradékkal, és így tovább, mindig az osztót a

maradékkal.

Így a következő lépéssorozatot kapjuk:

ahol

A maradék véges sok lépés után nulla lesz, hiszen amíg nem nulla, addig minden lépésben

legalább eggyel csökkenni fog, tehát az utolsó lépésnél:

A keresett legnagyobb közös osztó az , azaz az utolsó nem nulla maradék.

Példa:

A 360 és a 225 legnagyobb közös osztójának meghatározása az euklideszi algoritmussal:

Tehát a legnagyobb közös osztó a 45.

Java-kód:

package lnkoeuklidesz;

import java.util.Scanner;

public class LnkoEuklidesz {

public static void main(String[] args) {

Scanner be = new Scanner(System.in);

System.out.println("LNKO meghatározása");

System.out.print("első szám: ");

int szam1 = be.nextInt();

System.out.print("második szám: ");

int szam2 = be.nextInt();

int kozos = lnko(szam1, szam2);

if(kozos > 0)

System.out.println("A két szám közös

osztója:"+kozos);

Page 13: Programozási tételekipari118-szerencs.sulinet.hu/jegyzet/info/Programozási...Programozási tételek 10 – 11. évfolyam 3. oldal Programozási tételek, algoritmusok Az algoritmus

Programozási tételek 10 – 11. évfolyam

12. oldal

else

System.out.println("A két számnak nincs közös

osztója.");

}

//0 visszatérési érték jelzi, hogy nincs közös osztó.

public static int lnko(int szam1, int szam2){

int m;

if(szam1 < szam2){

//szam1 és szam2 megcserélése kizáró vagy

művelettel (^)

szam1 = szam1 ^ szam2;

szam2 = szam1 ^ szam2;

szam1 = szam1 ^ szam2;

}

//Az osztó nem lehet nulla.

if(szam2 == 0)

return 0;

// szam1 >= szam2

m = szam1 % szam2;

while(m != 0){

szam1 = szam2;

szam2 = m;

m = szam1 % szam2;

}

return szam2;

}

}

Feladat:

Számoljuk meg, hogy egy életkorokat tartalmazó tömbben hány 10 évnél fiatalabb,

tizenéves, huszonéves, … ember adata van.

Feladat:

Olvassunk be osztályzatokat 0 végjelig, és számoljuk meg, hogy hány ötös, négyes,

hármas, kettes, illetve egyes volt közöttük.

Minimum- / Maximum-kiválasztás

Minimum-kiválasztás esetén egy A sorozat legkisebb, maximum-kiválasztásnál a legnagyobb

elemét A(i) kell meghatározni.

Minimum-kiválasztásnál az algoritmus lényege, hogy az elemeket sorban megvizsgáljuk nem

kisebb-e, mint az addigi legkisebbnek tartott elem. Ha találtunk egy kisebb elemet, akkor

megjegyezzük. Induló minimális elemnek, vagy a sorozat első elemét A(1) vesszük, vagy egy

olyan értéket, amitől a sorozat minden eleme csak kisebb lehet A(i) < MIN, ahol i a sorozat

elemeinek indexe, i 1..N.

Page 14: Programozási tételekipari118-szerencs.sulinet.hu/jegyzet/info/Programozási...Programozási tételek 10 – 11. évfolyam 3. oldal Programozási tételek, algoritmusok Az algoritmus

Programozási tételek 10 – 11. évfolyam

13. oldal

Algoritmus:

MinIndex := 1

Ciklus i := 2-től N-ig

Ha A(i) < A(MinIndex) akkor

MinIndex := i

Ha vége

Ciklus vége

Ki: MinIndex, A(MinIndex)

Feladat:

Generáljunk véletlen számokat, amelyek egy téli hónap éjszakai hőmérsékleti értékeit

jelentik. (pl. -20..-5) Határozzuk meg a leghidegebb értéket, és azt, hogy ez hányadik

napja volt a hónapnak! (Véletlen szám 0-15-ig mínusz 20.)

Java-kód:

package leghidegebb;

import java.util.Random;

public class LegHidegebb {

public static void main(String[] args) {

Random rnd = new Random();

int [] honap = new int [30];

//véletlen számok generálása -20..-5

for(int i = 0; i < honap.length; i++){

honap[i] = rnd.nextInt(16)-20;

}

//hőmérsékletek kiíratása

System.out.print("A hónap hőmérsékleteti: ");

for(int i = 0; i < honap.length; i++)

System.out.print(honap[i]+", ");

System.out.println("");

//leghidegebb nap kiválasztása

int mini = 0;

for(int i = 1; i < honap.length; i++ ){

if(honap[i] < honap[mini])

mini = i;

}

System.out.println("A leghidegebb nap: "+mini);

System.out.println("A leghidgebb hőmérséklet:

"+honap[mini]);

}

}

Keresés tétele

Adott egy N elemű A tömb, valamint egy T() tulajdonság (logikai függvény). Döntsük el,

hogy van-e az A tömbnek T tulajdonságú eleme. Ha van, adjuk meg az elemet, vagy az elem

tömbbeli indexét!

Algoritmus:

i := 1

Page 15: Programozási tételekipari118-szerencs.sulinet.hu/jegyzet/info/Programozási...Programozási tételek 10 – 11. évfolyam 3. oldal Programozási tételek, algoritmusok Az algoritmus

Programozási tételek 10 – 11. évfolyam

14. oldal

Ciklus amíg (i <= N) és nem T(A(i))

i := i + 1

Ciklus vége

Ha (i <= N) akkor

Ki: i, A(i)

különben

Ki: hamis

Elágazás vége

Az elemek vizsgálatát az első elemtől kezdjük (i := 1), és lépegetünk sorba az elemeken (i := i

+ 1), amíg el nem érjük a tömb végét (i <= N), vagy nem találunk T tulajdonságú elemet

(nem T(A(i))). Ha nem értük el tömb végét (i <= N), akkor találtunk T tulajdonságú elemet,

így ezt, illetve ennek indexét adjuk vissza, egyéb esetben hamis logikai értékkel tér vissza.

Feladat:

A felhasználótól bekért számsorozatban melyik volt és hányadik az első 6-tal osztható

szám. (Hattal osztható egy szám, ha osztható 2-vel és 3-mal is.) Nulla végjelig!

Java-kód:

package kereses6oszthato;

import java.util.Scanner;

public class Kereses6Oszthato {

public static void main(String[] args) {

Scanner be = new Scanner(System.in);

System.out.println("Keressük az első hattal osztható

számot!");

System.out.print("szám: ");

int szam = be.nextInt();

// !((szam % 2 == 0) && (szam % 3 == 0)) -->

//(szam % 2 != 0) || (szam % 3 != 0)

// 0-ra kilépés

while(((szam % 2 != 0) || (szam % 3 != 0))

&& (szam != 0)){

System.out.print("szám: ");

szam = be.nextInt();

}

//Miért hagytuk el a ciklust?

if(szam != 0)

System.out.println("Az első hattal osztható szám:

"+szam);

else

System.out.println("Nem adtunk meg hattal osztható

számot!");

}

}

Feladat:

A felhasználótól bekért számsorozatban melyik volt és hányadik az első 5-tel osztható

szám. (Öttel osztható egy szám, ha utolsó helyen 0 vagy 5 számjegy áll.)

Page 16: Programozási tételekipari118-szerencs.sulinet.hu/jegyzet/info/Programozási...Programozási tételek 10 – 11. évfolyam 3. oldal Programozási tételek, algoritmusok Az algoritmus

Programozási tételek 10 – 11. évfolyam

15. oldal

Feladat:

A felhasználótól bekért számsorozatban melyik volt és hányadik az első 25-tel

osztható szám. (Huszonöttel osztható, ha az utolsó két helyen 0 áll, vagy ha az utolsó

két számjegy osztható 25-tel.)

Feladat:

A felhasználótól bekért számsorozatban melyik volt és hányadik az első 9-cel osztható

szám. (Kilenccel osztható a szám, ha a számjegyek összege osztható 9-cel.)

Java-kód:

package oszthato;

import java.util.Scanner;

public class Oszthato {

public static void main(String[] args) {

Scanner be = new Scanner(System.in);

int szam, sorszam = 0;

boolean megvan = false;

System.out.println("Melyik és hányadik az első kilencel

osztható szám?");

System.out.print("Szám = ");

szam = be.nextInt();

while((szam != 0) && !megvan){

if(isOszthatoKilenc(szam)){

sorszam++;

megvan = true;

System.out.println("A(z) "+sorszam+". szám:

"+szam+" osztható"

+ " kilencel.");

}

else{

sorszam++;

System.out.print("Szám = ");

szam = be.nextInt();

}

}

if(!megvan)

System.out.println("Eddig nem volt 9-cel osztható

szám.");

}

//kilencel osztható, ha a számjegyek összge osztható

kilencel

private static boolean isOszthatoKilenc(int sz){

int ossz = 0;

while(sz != 0){

ossz += sz % 10;

sz = sz / 10;

}

return ossz % 9 == 0;

}

}

Page 17: Programozási tételekipari118-szerencs.sulinet.hu/jegyzet/info/Programozási...Programozási tételek 10 – 11. évfolyam 3. oldal Programozási tételek, algoritmusok Az algoritmus

Programozási tételek 10 – 11. évfolyam

16. oldal

Lineáris keresés: rendezetlen sorozatban

Adott N elemszámú sorozatban keressük a T() tulajdonsággal rendelkező elemet. Az elemeket

sorban, a sorozat elejétől egyesével vizsgáljuk. Mivel a sorozat a kereső tulajdonság szerint

nincs rendezve, ezért nem tudjuk benne van-e a keresett elem, és hol. A keresést leállító

feltétel kétféle lehet:

Egy elemet tartalmaz a sorozat, akkor az elem megtalálásáig, vagy, ha nincs benne,

akkor a sorozat végéig keresünk.

Több elem esetén, ha szükségünk van minden elemre, akkor szintén a sorozat végéig

kell keresni. Amennyiben nincs szükség minden elemre, akkor általában az első elem

megtalálása után vége a keresésnek.

A lineáris keresést hívják még szekvenciális keresésnek is.

Az összehasonlítások száma N elem estén minimum 1, maximum N, átlagban (N+1)/2.

Az, hogy a keresett elem nincs benne a sorozatban, csak az utolsó összehasonlítás után derül

ki.

Algoritmus:

változó I, Hely:egész

változó Adat: ElemTípus

változó Talált: logikai

I:=1

Ciklus amíg (I<=N) és (A[I]<>Adat) ismétel

I:=I+1

Ciklus vége

Talált := I<=N

Ha Talált akkor

Hely:=I

Ha vége

Feladat:

Generáljunk véletlen számokat -20 °C és +35 °C között, majd keressük meg benne az

első olyan hőmérsékletet, amelyiket a felhasználótól kértük be.

Java-kód:

package lineariskeresesrendezetlen;

import java.util.Scanner;

import java.util.Random;

public class LinearisKeresesRendezetlen {

public static void main(String[] args) {

Random rnd = new Random();

Scanner be = new Scanner(System.in);

//Véletlen számok generálása -20..+35.

Page 18: Programozási tételekipari118-szerencs.sulinet.hu/jegyzet/info/Programozási...Programozási tételek 10 – 11. évfolyam 3. oldal Programozási tételek, algoritmusok Az algoritmus

Programozási tételek 10 – 11. évfolyam

17. oldal

int tomb[] = new int[20];

for(int i = 0; i < tomb.length; i++)

tomb[i] = rnd.nextInt(56)-20;

//lista

System.out.println("A tömb elemei:");

for(int i = 0; i < tomb.length; i++)

System.out.print(tomb[i]+", ");

System.out.println("");

//mit keressek

System.out.print("Kérem a számot, amit meg kell

keresnem: ");

int szam = be.nextInt();

//keresés

int i = 0;

while((i < tomb.length) && (tomb[i] != szam))

i++;

//miért hagytuk el a tömböt

if(i < tomb.length)

System.out.println("Benne van, helye: "+

(i+1)+".");

else

System.out.println("Nincs benne!");

}

}

Futási kép:

run:

A tömb elemei:

5, -17, 12, 14, 22, 1, 20, 20, 8, -20, 1, 21, 13, -20, 4, -19,

15, 29, -16, 33,

Kérem a számot, amit meg kell keresnem: 1

Benne van, helye: 6.

BUILD SUCCESSFUL (total time: 3 seconds)

A pirossal szedett részt nézzük meg alaposabban! Annak az eldöntését, hogy egy elem benne

van-e a sorozatban, a ciklusból kilépve kell megvizsgálni. Logikusabbnak gondolhatnánk a

vizsgálatot, ha a tömb adott elemét a bekért számmal hasonlítanánk össze.

A következő módon:

//miért hagytuk el a tömböt

if(tomb[i] == szam)

System.out.println("Benne van, helye: "+

(i+1)+".");

else

System.out.println("Nincs benne!");

Helyes eredményt kapunk, ha a keresett elem benne van a sorozatban. Amennyiben a keresett

elem nincs benne, hibajelzést kapunk.

Futási kép:

A tömb elemei:

Page 19: Programozási tételekipari118-szerencs.sulinet.hu/jegyzet/info/Programozási...Programozási tételek 10 – 11. évfolyam 3. oldal Programozási tételek, algoritmusok Az algoritmus

Programozási tételek 10 – 11. évfolyam

18. oldal

3, -8, 7, 17, -8, 12, -19, -15, 12, 14, -16, 28, 27, -13, -20,

15, -14, 31, -2, 5,

Kérem a számot, amit meg kell keresnem: 40

Exception in thread "main"

java.lang.ArrayIndexOutOfBoundsException: 20

at

lineariskeresesrendezetlen.LinearisKeresesRendezetlen.main(Line

arisKeresesRendezetlen.java:38)

Java Result: 1

BUILD SUCCESSFUL (total time: 5 seconds)

Gondoljuk végig a ciklus működését! Mivel nincs benne a keresett elem a sorozatban, ezért

végig keresünk. A ciklus utolsó lépésében a ciklusváltozó értéke nagyobb, mint a tömb

elemszáma (i > tomb.length). Ez pedig túlindexelést eredményez, és hibát generál!

Lineáris keresés: rendezett sorozatban

A sorozatnak rendezettnek kell lenni. Az előzőhöz képest növeli a hatékonyságot, hogy akkor

is leáll a keresés, ha nagyobb elemre lépünk, mint a keresett érték.

Algoritmus:

változó I, Hely:egész

változó Adat: ElemTípus

változó Talált: logikai

I:=1

Ciklus amíg (I<=N) és (A[I]<Adat) ismétel

I:=I+1

Ciklus vége

Talált := (I<=N) és (A[I]=Adat)

Ha Talált akkor

Hely:=I

Ha vége

Feladat:

Generáljunk 20 véletlen egész számot, az 5..50 tartományból. Rendezzük nagyság

szerint, majd keressünk meg benne egy felhasználó által megadott számot.

Java-kód:

package lieariskeresrendezett;

import java.util.Scanner;

import java.util.Random;

// tömbökkel kapcsolatos metódusok, pl. rendezések

import java.util.Arrays;

public class LiearisKeresRendezett {

public static void main(String[] args) {

// Deklarációk

Scanner be = new Scanner(System.in);

int [] tomb = new int [20];

// tömb feltöltése véletlen számokkal

feltoltVeletlen(tomb);

Page 20: Programozási tételekipari118-szerencs.sulinet.hu/jegyzet/info/Programozási...Programozási tételek 10 – 11. évfolyam 3. oldal Programozási tételek, algoritmusok Az algoritmus

Programozási tételek 10 – 11. évfolyam

19. oldal

// tömb listázása rendezés előtt

System.out.println("A véletlen számok rendezés

előtt:");

lista(tomb);

// tömb rendezése

Arrays.sort(tomb);

// tömb listázása rendezés után

System.out.println("A véletlen számok rendezés után:");

lista(tomb);

// szám bekérése

System.out.print("Mit keressek: ");

int szam = be.nextInt();

// keresés rendezett tömbben

// ha nincs benne az eredmény -1, egyébként az index

int eredmeny = keres(tomb, szam);

if(eredmeny < 0)

System.out.println("Nincs benne!");

else

System.out.println("A keresett elem indexe:

"+eredmeny);

}

// tömb feltöltését elvégző metódus 5..50 közötti számokkal

public static void feltoltVeletlen(int[] t){

Random rnd = new Random();

for(int i = 0; i < t.length; i++){

t[i] = rnd.nextInt(46)+5;

}

}

// tömb listázása

public static void lista(int[] t){

for(int i = 0; i < t.length; i++){

System.out.print(t[i]+", ");

}

System.out.println("");

}

// keresés a tömbben, ha -1 nincs benne, egyébként az index

public static int keres(int[] t, int sz){

int i = 0;

while((i < t.length) && (t[i] < sz))

i++;

if((i < t.length) && (sz == t[i]))

return i;

else

return -1;

}

}

Az Arrays osztályban sok tömbökön dolgozó metódus van definiálva, pl. a rendezések

különböző típusú adatokon.

Bináris keresés

Adott egy N elemű, rendezett A sorozat. Keressük meg benne az X értéket!

Page 21: Programozási tételekipari118-szerencs.sulinet.hu/jegyzet/info/Programozási...Programozási tételek 10 – 11. évfolyam 3. oldal Programozási tételek, algoritmusok Az algoritmus

Programozási tételek 10 – 11. évfolyam

20. oldal

A keresés maximális időigénye log2(N), N az elemszám, ezért nevezik a keresést logaritmikus

keresésnek. Minél nagyobb az elemszám, annál jobban megmutatkozik az algoritmus

hatékonysága. Például 1024 elemszámnál log2(1024)=10, azaz maximum 10 lépésen belül

megvan az elem vagy kiderül, hogy nincs benne.

Algoritmus:

Logaritmikus(be:tömb[1..N], be:keresett, ki: sorszám)

Deklaráció

alsó, felső: egész

Logaritmus kezdet

alsó:=1

felső:= N

Ciklus

sorszám:= (alsó + felső) DIV 2

Ha keresett > tömb[sorszám] akkor

alsó:= sorszám + 1

Ha vége

Ha keresett < tömb[sorszám] akkor

felső:= sorszám – 1

Ha vége

Mígnem (tömb[sorszám] = keresett) VAGY (alsó > felső)

Ciklus vége

Ha alsó > felső akkor

sorszám := -1

Ha vége

Logaritmikus vége

Fontos megérteni, hogy ez az általános algoritmus a végfeltételes ciklusnál kilépési feltételt

fogalmaz meg. Az általunk használt Java nyelv végfeltételes ciklusa pedig belépési feltételt

használ.

De-Morgan azonosságok, amennyiben szükséges:

nem (a és b) = (nem a) vagy (nem b),

nem (a vagy b) = (nem a) és (nem b)

Feladat:

Töltsünk fel egy tömböt véletlen számokkal, majd keressünk meg benne egy

felhasználó által megadott számot.

package binariskereses;

import java.util.Arrays;

import java.util.Random;

import java.util.Scanner;

public class BinarisKereses {

public static void main(String[] args) {

Page 22: Programozási tételekipari118-szerencs.sulinet.hu/jegyzet/info/Programozási...Programozási tételek 10 – 11. évfolyam 3. oldal Programozási tételek, algoritmusok Az algoritmus

Programozási tételek 10 – 11. évfolyam

21. oldal

System.out.println("Bináris keresés feladat.");

int[] tomb = new int[20];

//Véletlen számok generálása - mibe, alsó, felső érték

randomGenerator(tomb, 0, 100);

//Számok kiíratása rendezetlenül

System.out.println("Rendezetlen lista:");

lista(tomb);

//Rendezés az Arrays osztály statikus sort()

metódusával.

Arrays.sort(tomb);

//Rendezett lista

System.out.println("Rendezett lista:");

lista(tomb);

//Kereséshez adat bekérés

System.out.print("Kérem a számot: ");

Scanner be = new Scanner(System.in);

int keresett = be.nextInt();

//Bináris keresés

int eredmeny = binSearch(tomb, keresett);

if(eredmeny == -1){

System.out.println("Nincs benne a keresett

érték.");

}

else{

System.out.println("Index: "+eredmeny);

}

........//Keresés az Arrays tömb beépített függvényével

eredmeny = Arrays.binarySearch(tomb, keresett);

System.out.println("\nKeresés eredménye az Arrays

beépített függvényével.");

if(eredmeny == -1){

System.out.println("Nincs benne a keresett

érték.");

}

else{

System.out.println("Index: "+eredmeny);

}

}

//Tömb feltöltése véletlen számmal.

public static void randomGenerator(int [] t, int also, int

felso){

Random rnd = new Random();

for(int i = 0; i < t.length; i++){

t[i] = rnd.nextInt(felso-also+1)+also;

}

}

//Tömb listázása.

public static void lista(int [] t){

for(int i = 0; i < t.length; i++){

System.out.print(t[i]+", ");

if((i+1) % 10 == 0)

System.out.println("");

}

System.out.println("");

}

Page 23: Programozási tételekipari118-szerencs.sulinet.hu/jegyzet/info/Programozási...Programozási tételek 10 – 11. évfolyam 3. oldal Programozási tételek, algoritmusok Az algoritmus

Programozási tételek 10 – 11. évfolyam

22. oldal

//Bináris keresés függvénye, -1 ha nincs benne egyébként az

index.

public static int binSearch(int[] t, int keresett){

int also = 0;

int felso = t.length-1;

int kozepso;

do{

kozepso = (also + felso) / 2;

if(keresett < t[kozepso])

felso = kozepso - 1;

else if(keresett > t[kozepso])

also = kozepso + 1;

}while((t[kozepso] != keresett) && (also <= felso));

if(also <= felso)

return kozepso;

else

return -1;

}

}

Egy sorozathoz egy sorozat rendelése Az algoritmus bemenete egy sorozat, a kimenete szintén egy sorozat. A kimeneti sorozat lehet

szűkebb, egyező, vagy bővebb, mint a bemeneti. Az elemeken különböző transzformációt is

végezhetünk.

Másolás

Egy bemenő sorozatból egy kimenő sorozatot készítünk, mégpedig úgy, hogy az

eredménysorozat ugyanolyan elemszámú, mint a bemeneti sorozat, és az eredménysorozat I.

tagját a bemenő sorozat I. tagjából lehet meghatározni. A bemenő sorozatot tehát átmásoljuk

úgy, hogy közben az elemeken esetleges átalakításokat végzünk.

Algoritmus:

Ciklus I:=1..NBemenő ismétel

Bemenő sorozat I. eleméből Kimenő sor I. elemének előállítása

Ciklus vége

Feladat:

A születési éveket tartalmazó tömbből hozzunk létre egy tömböt, mely az életkorokat

tartalmazza.

Feladat:

Töltsünk fel véletlen számokkal egy 20 elemű tömböt úgy, hogy az elemek 1000 és

5000 közöttiek legyenek. Ez legyen például könyvek nettó ára. Számoljuk ki a bruttó

árakat egy másik tömbbe (ÁFA: 27%).

Page 24: Programozási tételekipari118-szerencs.sulinet.hu/jegyzet/info/Programozási...Programozási tételek 10 – 11. évfolyam 3. oldal Programozási tételek, algoritmusok Az algoritmus

Programozási tételek 10 – 11. évfolyam

23. oldal

Java-kód:

package masolnettobrutto;

import java.util.Random;

import java.lang.Math;

public class MasolNettoBrutto {

public static void main(String[] args) {

// deklarációk

int[] netto = new int[20];

int[] brutto = new int[20]; // egész értékekkel

// nettó értékek feltöltése 1000..5000 között

Random rnd = new Random();

for(int i = 0; i < netto.length; i++)

netto[i] = rnd.nextInt(4001)+1000;

// másolás transzformációval - bruttó előállítása

for(int i = 0; i < brutto.length; i++)

brutto[i] = (int)Math.round(netto[i] * 1.27);

//nettó, bruttó ár listázása

System.out.println("A könyvek nettó árai:");

lista(netto);

System.out.println("A könyvek bruttó árai:");

lista(brutto);

}

// Listázó metódus

public static void lista(int[] t){

for(int i = 0; i < t.length; i++)

System.out.print(t[i]+", ");

System.out.println("");

}

}

Kiválogatás

Adott egy N elemű A tömb és egy T() tulajdonság. Válogassuk ki egy B tömbbe az A vektor

T() tulajdonságú elemeit. A két tömb elemszámának meg kell egyezni, mert lehet, hogy az első

tömb minden elemét át kell másolni.

Algoritmus:

Db := 0

Ciklus i := 1-től N-ig

Ha T(A(i) akkor

Db := Db + 1

B(Db) := A(i)

Ha vége

Ciklus vége

Feladat:

Töltsünk fel egy String tömböt nevekkel, majd válogassuk ki egy másik tömbbe a K,

L, M betűkkel kezdődő neveket.

Java-kód:

package kivalogatastetele;

public class KivalogatasTetele {

Page 25: Programozási tételekipari118-szerencs.sulinet.hu/jegyzet/info/Programozási...Programozási tételek 10 – 11. évfolyam 3. oldal Programozási tételek, algoritmusok Az algoritmus

Programozási tételek 10 – 11. évfolyam

24. oldal

public static void main(String[] args) {

// deklaráció kezdőértékadással

String[] nevek = {"Ákos", "Béla", "Zénó", "Mátyás",

"Eszter", "Leopold", "Géza", "Éva", "Laura", "Mária"};

// nevek kiíratása

kiir(nevek, nevek.length);

// a két tömb elemszámának meg kell egyezni

String[] nevek2 = new String[10];

// K,L,M betűkkel kezdődő nevek kiválogatása

// nevek2 indexváltozója -1, mert lehet, hogy egy sem

egyezik

int j = -1;

for(int i = 0; i < nevek.length; i++)

if(isEgyezik(nevek[i])){

j++;

nevek2[j] = nevek[i];

}

// Ha volt K, L, M kezdőbetűjű név, akkor kiírjuk.

if(j > -1)

kiir(nevek2, j);

else

System.out.println("Nincs K, L, M kezdőbetűvel

név.");

}

// isEgyezik metódus megvizsgálja a nevek első betűjének

egyezőségét

public static boolean isEgyezik(String nev){

return (nev.charAt(0) == 'K')||(nev.charAt(0) == 'L')

||(nev.charAt(0) == 'M');

}

// nevek kiíratása

public static void kiir(String[] n, int db){

System.out.println("Nevek:");

for(int i = 0; i < db; i++){

System.out.print(n[i]+", ");

// minden ötödik név után sort emel

if((i+1) % 5 == 0)

System.out.println("");

}

System.out.println("");

}

}

Feladat:

Töltsünk fel véletlen számokkal egy 20 elemű tömböt úgy, hogy az elemek 10 és 100

közöttiek legyenek. Válogassuk ki a 10-zel osztható számokat egy másik tömbbe.

Egy sorozathoz több sorozat rendelése Van egy bemeneti és több kimeneti sorozat.

Page 26: Programozási tételekipari118-szerencs.sulinet.hu/jegyzet/info/Programozási...Programozási tételek 10 – 11. évfolyam 3. oldal Programozási tételek, algoritmusok Az algoritmus

Programozási tételek 10 – 11. évfolyam

25. oldal

Szétválogatás

Egy bemenő sorozatból több kimenő sorozatot készítünk. Azok a feladatok tartoznak ide,

amelyeknél a bejövő adatok mindegyikére szükségünk van ugyan, de azokat valamilyen

szempontból el kell különíteni, szét kell válogatni. A kimenő sorozatok elemszámainak

összege megegyezik a bemenő sorozat elemszámával. A szétválogatást fel lehet fogni több

egymás utáni kiválogatásként is, ahol egyszer minden elemre sor kerül. Mindegyik

eredménysorozatban ugyanannyi elemszámra kell felkészülni, mint a bemenő sorozat

elemszáma, hiszen szélsőséges esetben elképzelhető, hogy minden elem egyetlen kimenő

sorozatba kerül át.

Algoritmus:

Eljárás szétválogatás

NBemenő // bemeneti sorozat elemszáma

NKimenő1:=0 // első kimeneti sorozat elemszáma

NKimenő2:=0 // második kimeneti sorozat elemszáma

... // szükség esetén további kimeneti sorozatok

ciklus I:=1..NBemenő ismétel

elágazás

amikor Bemenő[I] az 1. tulajdonságú:

NKimenő1:=NKimenő1+1

Kimenő1[NKimenő1]:=Bemenő[I]

amikor Bemenő[I] az 2. tulajdonságú:

NKimenő2:=NKimenő2+1

Kimenő2[NKimenő2]:=Bemenő[I]

...

különben

...

elágazás vége

Ciklus vége

Eljárás vége

Feladat:

Adott egy osztály névsor. Válogassuk szét a tanulókat nemük szerint két csoportba. A

Tanulo osztály tartalmaz egy ffi adattagot, a fiú/lány – igaz/hamis jelölésére.

Java-kód:

package szetvalogattanulo;

import java.util.Scanner;

public class SzetvalogatTanulo {

public static void main(String[] args) {

// Kapcsolat létrahozása a Tanulo osztállyal.

// tárolás tömbben

Tanulo[] tanulok = new Tanulo[10];

// a tanulok tömb feltöltése

feltolt(tanulok);

// lista a tanulókról

System.out.println("A tanulók listázása:");

lista(tanulok, tanulok.length);

Page 27: Programozási tételekipari118-szerencs.sulinet.hu/jegyzet/info/Programozási...Programozási tételek 10 – 11. évfolyam 3. oldal Programozási tételek, algoritmusok Az algoritmus

Programozási tételek 10 – 11. évfolyam

26. oldal

// két nemek szerinti tömb létrehozása

Tanulo[] ferfiak = new Tanulo[10];

Tanulo[] nok = new Tanulo[10];

// elemszám a lányok és férfiak tömbjeihez

// tömbben tárolva a referencia miatt

// első elem férfi, második a nők száma

int[] letszam = new int[2];

letszam[0] = 0;

letszam[1] = 0;

// nemek szerinti szétválogatás

szetvalogat(tanulok, ferfiak, nok, letszam);

// nemek szinti listázás, ha volt elem

System.out.println("Lányok listázása:");

if(letszam[1] > 0)

lista(nok, letszam[1]);

else

System.out.println("Nem voltak lányok");

System.out.println("Fiúk listázása:");

if(letszam[0] > 0)

lista(ferfiak, letszam[0]);

else

System.out.println("Nem voltak fiúk");

}

// tanulok tömb feltöltése

public static void feltolt(Tanulo[] t){

Scanner be = new Scanner(System.in);

System.out.println("A 10 elemű tanulók tömb

feltöltése");

String nev;

char ffi;

for(int i = 0; i < t.length; i++){

System.out.print("Név: ");

nev = be.nextLine();

System.out.print("Férfi-e (f/n): ");

ffi = be.nextLine().charAt(0);

t[i] = new Tanulo(nev, ffi);

}

}

// lista

public static void lista(Tanulo[] t, int letszam){

System.out.println("Név\t\tNeme");

for(int i = 0; i < letszam; i++){

System.out.printf("%10s\t%3c\n",t[i].getNev(),

t[i].getFerfi());

}

}

// szétválogatás nemek szerint

public static void szetvalogat(Tanulo[] t, Tanulo[] f,

Tanulo[] n, int[] l){

for(int i = 0; i < t.length; i++){

if(t[i].getFerfi() == 'f'){

// férfiak elemszámának növelése

l[0]++;

// elhelyezés a fiúk tömbjébe

// az index elemszam-1

Page 28: Programozási tételekipari118-szerencs.sulinet.hu/jegyzet/info/Programozási...Programozási tételek 10 – 11. évfolyam 3. oldal Programozási tételek, algoritmusok Az algoritmus

Programozási tételek 10 – 11. évfolyam

27. oldal

f[l[0]-1] = new Tanulo(t[i].getNev(),

t[i].getFerfi());

}

else if(t[i].getFerfi() == 'n'){

// nők elemszámának növelése

l[1]++;

// elhelyezés a lányok tömbjébe

// az index elemszám-1

n[l[1]-1] = new Tanulo(t[i].getNev(),

t[i].getFerfi());

}

}

}

}

A Tanulo osztály: package szetvalogattanulo;

public class Tanulo {

// adattagok

String nev;

char ffi; //f - férfi, n - nő

// konstruktor

public Tanulo(String nev, char ffi){

// A this objektumreferencia szükséges, mert a lokális

// változók takarják az osztály szintű változókat.

this.nev = nev;

this.ffi = ffi;

}

//setter (beállító) metódusok

public void setNev(String n){

// Mivel a lokális szinten lévő paraméter nem takarja

// az osztály adattagot, nem szükséges this előtag.

nev = n;

}

public void setNeme(char n){

ffi = n;

}

// getter (lekérdező) metódusok

public String getNev(){

return nev;

}

public char getFerfi(){

return ffi;

}

}

Feladat:

Állítsunk elő egy 20 elemű véletlen egészeket [0..100] tartalmazó sorozatot, majd

válogassuk szét a páros és a páratlan számokat.

Page 29: Programozási tételekipari118-szerencs.sulinet.hu/jegyzet/info/Programozási...Programozási tételek 10 – 11. évfolyam 3. oldal Programozási tételek, algoritmusok Az algoritmus

Programozási tételek 10 – 11. évfolyam

28. oldal

Gyakorlás (másolás, kiválogatás, szétválogatás)

Feladat:

Adott egy neveket (vezeték és keresztnév) tartalmazó szóközzel elválasztott tömb. A

vezeték és keresztnevek szóközzel vannak elválasztva. Állítsuk elő a monogramokat

tartalmazó tömböt. A kiíratásokat végezzük el.

Feladat:

Adott egy dolgozók nevét és fizetését tartalmazó vektor. Válogassuk ki azon dolgozók

neveit, akiknek a fizetése kisebb, mint 120000 Ft.

Feladat:

Egy iskola sportolási lehetőséget biztosít a tanulóinak. Háromféle lehetőség közül

választhatnak a diákok (futball, ping-pong, kosárlabda). Egyet kötelezően választani

kell. A tanulóknál nyílván tartják, hogy ki mit választott. Készíts listát, amelyben

szétválogatjuk a tanulókat a sport csoportoknak megfelelően.

Rendezések, rendezettség Rendezésnek nevezünk egy algoritmust, ha az valamilyen szempont alapján sorba állítja

elemek egy listáját.

Legyen adott egy N elemszámú A sorozat. A rendezés feladata, hogy a sorozat A(i) és A(i+1)

elemeit a rendező elv R(A(i), A(i+1)) szerinti sorrendbe tegye.

A legegyszerűbb esetben növekvő rendezést végzünk. Tehát az R(A(i), A(i+1)) rendezettség

(logikai) függvény igaz értékkel tér vissza, ha az A(i) értéke kisebb egyenlő, mint az A(i+1)

értéke.

Rendezettség

A rendezettség azt jelenti, hogy egy sorozat egymást követő két eleméről (pl. A és B)

egyértelműen meg lehet állapítani, hogy melyikük az előrébb való. A rendező elv lehet

bonyolultabb is, mint a kisebb/nagyobb reláció. Amikor egy összetett feltétel szerint kell

meghatározni az elemek egymáshoz viszonyított helyét, érdemes egy rendező függvényt

készíteni. Ez a függvény, akkor fog igazat visszaadni, ha a két rendezendő elem

egymáshoz képest jó helyen van.

Rendező függvény:

Rendezett(A(i), A(i+1)): logikai

return A(i) <= A(i+1)

Page 30: Programozási tételekipari118-szerencs.sulinet.hu/jegyzet/info/Programozási...Programozási tételek 10 – 11. évfolyam 3. oldal Programozási tételek, algoritmusok Az algoritmus

Programozási tételek 10 – 11. évfolyam

29. oldal

Rendezett vége

Feladat:

Töltsünk fel egy 20 elemű vektort véletlen értékekkel, és rendezzük úgy, hogy elől

legyenek a páratlan számok növekvően, majd a párosak szintén növekvő sorrendben!

Rendező elv (feltétel) meghatározása:

Azokat a feltételeket kell megtalálni, amelyek szükségesek a rendezettség előállításához.

Legyen A az első, B a második szám az R(A, B) rendező függvénynél:

A páratlan, B páros,

Ha A és B páratlan, akkor A < B,

Ha A és B páros, akkor A < B.

Nézzük a relációkat:

Páratlanság vizsgálata: (A % 2 != 0) – a szám kettővel való osztása nem nulla osztási

maradékot ad.

Párosság vizsgálata: (A % 2 == 0) – a szám kettővel való osztása esetén nincs

maradék.

Elől legyenek a páratlan számok, hátul a párosak: (A % 2 != 0) & (B % 2 == 0).

Két páratlan szám esetén az első kisebb egyenlő legyen, mint a második:

(A % 2 != 0) & (B % 2 != 0) & (A <= B).

Két páros szám esetén az első kisebb egyenlő legyen, mint a második:

(A % 2 == 0) & (B % 2 == 0) & (A <= B).

Tehát a szükséges feltétel:

((A % 2 != 0) & (B % 2 == 0)) | ((A % 2 != 0) & (B % 2 != 0) & (A <= B)) |

((A % 2 == 0) & (B % 2 == 0) & (A <= B)).

Az AND (&) erősebb prioritású művelet, mint az OR ( | ), ezért a külső zárójelek elhagyhatók.

A % szintén erősebb, mint a relációjel, ezért oda nem lett téve zárójel.

Feladat:

Rendezzük az egész számok egy listáját úgy, hogy a páros számok emelkedő, illetve a

páratlan számok csökkenő sorrendben legyenek.

A rendező feladatokban szükséges az elempárok felcserélése. Ennek az algoritmusa a

következő.

Page 31: Programozási tételekipari118-szerencs.sulinet.hu/jegyzet/info/Programozási...Programozási tételek 10 – 11. évfolyam 3. oldal Programozási tételek, algoritmusok Az algoritmus

Programozási tételek 10 – 11. évfolyam

30. oldal

Algoritmus:

csere(elso, masodik: tipus)

temp: tipus

temp := elso

elso := masodik

masodik := temp

csere vege

A csere eljárás implementálásánál Java nyelven, figyelni kell arra, hogy a Java-ban érték

szerinti paraméterátadás van. (Vagyis referenciát adunk át, például egy tömb nevet, illetve a

két megcserélendő elem indexét.)

A csere referencia átadással (Java):

csere(t: tömb, i: egész, j: egész)

temp: tipus

temp := t[i]

t[i] := t[j]

t[j] := temp

csere vége

A „t” egy tömb referencia, az „i” és „j” a cserélendő elemek indexei.

Minimum-kiválasztásos rendezés

A rendezés egy sorozat elemeinek egymáshoz viszonyított helyét állítja be. A minimum-

kiválasztásos rendezésnél a rendező elv az adott rendezettség szerinti első elem

kiválasztása.

A legegyszerűbb esetben növekvő relációt használunk.

Ebben az esetben a minimum-kiválasztásos rendezés lényege:

Első lépésben megkeressük a sorozat legkisebb elemét. Majd, ha ez nem az első elem,

kicseréljük az első elemmel. Így az első helyen a sorozat legkisebb eleme lesz.

A következő lépésben, a második legkisebb elemet keressük, a még nem rendezett

(második elemtől az utolsóig) részben. A megtalált elemet, ha ez nem egyenlő a

második helyen lévővel, megcseréljük. Ekkor a sorozatunk, a második elemig

rendezett.

A további lépések az előző kettőhöz hasonlóan futnak le, mindig megkeresve a sorozat

következő legkisebb elemét. Amely ez által addig rendezetté válik.

Utolsó lépésként az utolsó előtti helyre kell kiválasztani a legkisebb elemet. Ezt

követően a sorozat rendezetté válik.

Page 32: Programozási tételekipari118-szerencs.sulinet.hu/jegyzet/info/Programozási...Programozási tételek 10 – 11. évfolyam 3. oldal Programozási tételek, algoritmusok Az algoritmus

Programozási tételek 10 – 11. évfolyam

31. oldal

Algoritmus:

Ciklus i := 1-től a sorozat vége -1-ig

minindex := i

Ciklus j := i + 1-től a sorozat végéig

Ha sorozat[j] < sorozat[minindex] akkor

minindex := j

Ha vége

Ciklus vége

Ha i <> minindex akkor

Csere(sorozat[i], sorozat[minindex])

Ha vége

Ciklus vége

A Csere() eljárás hívása a Java-ban, a következőre módosul az érték szerinti paraméterátadás

miatt: Csere(sorozat, i, minindex). Átadjuk a tömb referenciát, majd a két cserélendő elem

helyét a tömbben. Ezzel a tömb referencia átadással a változás maradandó lesz.

Példa:

3, 6, 2, 7, 4, 9, 1, 8, 5 rendezetlen sorozat

1, 6, 2, 7, 4, 9, 3, 8, 5

1, 2, 6, 7, 4, 9, 3, 8, 5

1, 2, 3, 7, 4, 9, 6, 8, 5

1, 2, 3, 4, 7, 9, 6, 8, 5

1, 2, 3, 4, 5, 9, 6, 8, 7

1, 2, 3, 4, 5, 6, 9, 8, 7

1, 2, 3, 4, 5, 6, 7, 8, 9

1, 2, 3, 4, 5, 6, 7, 8, 9 rendezett sorozat

Ciklusok száma: 8

Feladat:

Generáljunk egy véletlen egész számokat tartalmazó tömböt, és rendezzük növekvő,

sorrendbe.

Java-kód:

package minkivalrendezes;

import java.util.Random;

public class MinKivalRendezes {

public static void main(String[] args) {

Random rnd = new Random();

// 20 elemű tömb deklarálása és feltöltése 0..100

közötti számokkal

int [] t = new int[20];

for(int i = 0; i < t.length; i++)

t[i] = rnd.nextInt(101);

// elemek kiíratása foreach jellegű ciklussal

System.out.println("Rendezetlen sorozat:");

for(int e : t)

System.out.print(e+", ");

System.out.println("");

// elemek rendezése minimum-kiválasztásos rendezéssel

int minIndex;

Page 33: Programozási tételekipari118-szerencs.sulinet.hu/jegyzet/info/Programozási...Programozási tételek 10 – 11. évfolyam 3. oldal Programozási tételek, algoritmusok Az algoritmus

Programozási tételek 10 – 11. évfolyam

32. oldal

for(int i = 0; i < t.length-1; i++){

// feltételezzük, hogy az i. elem a legkisebb

minIndex = i;

for(int j = i+1; j < t.length; j++){

// ha találtunk a minIndex. elemtől kisebbet

if(t[j] < t[minIndex]){

// akkor megjegyezzük az indexet

minIndex = j;

}

}

// ha a minIndex != i-vel akkor találtunk kisebbet,

és akkor csere

if(minIndex != i){

// cserélje meg a t tömbben az i. elemet a

minIndex. elemmel

csere(t, i, minIndex);

}

}

// rendezés után kiíratjuk

System.out.println("Rendezett sorozat:");

for(int e : t)

System.out.print(e+", ");

System.out.println("");

}

// a csere metódus definiálása, paraméterek a tömb, és a

két index

public static void csere(int[] t, int i, int j){

// segéd változó a cseréhez temporary - ideiglenes

int temp;

temp = t[i];

t[i] = t[j];

t[j] = temp;

}

}

Feladat:

Mit kell megváltoztatni az előző feladatban, hogy csökkenő rendezést kapjunk?

Feladat:

Generáljunk egy egészeket tartalmazó 20 elemű tömböt, majd rendezzük úgy, hogy

elől legyenek a páros számok növekvő, végül a páratlanok csökkenő sorrendben.

Java-kód:

package rendezesparosparatlan;

import java.util.Random;

public class RendezesParosParatlan {

public static void main(String[] args) {

// deklaráció

int[] tomb = new int[20];

// tömb feltöltése véletlen számokkal

feltolt(tomb);

// elemek kiíratása

Page 34: Programozási tételekipari118-szerencs.sulinet.hu/jegyzet/info/Programozási...Programozási tételek 10 – 11. évfolyam 3. oldal Programozási tételek, algoritmusok Az algoritmus

Programozási tételek 10 – 11. évfolyam

33. oldal

System.out.println("A tömb elemei:");

lista(tomb);

// rendezés

rendez(tomb);

// rendezett tömb kiíratása

System.out.println("\nA rendezett tömb elemei:");

lista(tomb);

}

// a tömb feltöltése véletlen számokkal 0..100

public static void feltolt(int[] t){

Random rnd = new Random();

for(int i = 0; i < t.length; i++)

t[i] = rnd.nextInt(101);

}

// a tömb elemeinek listázása

public static void lista(int[] t){

for(int i = 0; i < t.length; i++)

System.out.print(t[i]+", ");

System.out.println("");

}

// a rendezettség megállapítása függvénnyel

public static boolean rendezett(int a, int b){

// a következő esetekben ad vissza igazat

// ha a, b páros és a < b

// ha a, b páratlan és a > b

// ha a páros és b páratlan

return ((a % 2 == 0) && (b % 2 == 0) && (a < b)) ||

((a % 2 != 0) && (b % 2 != 0) && (a > b)) ||

((a % 2 == 0) && (b % 2 != 0));

}

// a csere eljárás megvalósítása

public static void csere(int[] t, int mit, int mivel){

int temp = t[mit];

t[mit] = t[mivel];

t[mivel] = temp;

}

// a tömb eleminek rendezése minimum-kiválasztásos

rendezéssel

public static void rendez(int[] t){

int minIndex;

for(int i = 0; i < t.length-1; i++){

minIndex = i;

for(int j = i+1; j < t.length; j++){

if(!rendezett(t[minIndex], t[j]))

minIndex = j;

}

if(minIndex != i){

csere(t, i, minIndex);

}

}

}

}

Futási kép:

A tömb elemei:

Page 35: Programozási tételekipari118-szerencs.sulinet.hu/jegyzet/info/Programozási...Programozási tételek 10 – 11. évfolyam 3. oldal Programozási tételek, algoritmusok Az algoritmus

Programozási tételek 10 – 11. évfolyam

34. oldal

7, 90, 48, 44, 37, 52, 30, 29, 67, 92, 30, 24, 22, 84, 26, 42,

13, 65, 96, 98,

A rendezett tömb elemei:

22, 24, 26, 30, 30, 42, 44, 48, 52, 84, 90, 92, 96, 98, 67, 65,

37, 29, 13, 7,

BUILD SUCCESSFUL (total time: 0 seconds)

Maximum kiválasztásos rendezés

A reláció megfordul, nem a legkisebbet, hanem a legnagyobbat keressük.

Gyakorlás

Feladat:

Rendezzük az előző sorozatot úgy, hogy a páros számok növekvő, majd a páratlanok

csökkenő sorrendben legyenek.

Java-kód:

Elég az előző feladat rendezettséget megállapító függvényét aktualizálni.

// a rendezettség megállapítása függvénnyel

public static boolean rendezett(int a, int b){

// a következő esetekben ad vissza igazat

// ha a, b páros és a < b

// ha a, b páratlan és a > b

// ha a páros és b páratlan

// ha a páratlan és b páros

return ((a % 2 == 0) && (b % 2 == 0) && (a < b)) ||

((a % 2 != 0) && (b % 2 != 0) && (a > b)) ||

((a % 2 == 0) && (b % 2 != 0)) ||

((a % 2 != 0) && (b % 2 == 0));

}

Futási kép:

A tömb elemei:

10, 37, 35, 7, 100, 40, 9, 36, 38, 72, 94, 96, 7, 2, 11, 92,

63, 19, 84, 57,

A rendezett tömb elemei:

2, 63, 57, 37, 10, 36, 35, 38, 40, 72, 84, 92, 19, 94, 11, 96,

9, 7, 100, 7,

BUILD SUCCESSFUL (total time: 0 seconds)

A következő feladatban a rendezendő elemek nem primitív típusok, hanem objektumok. Így

reláció jelekkel közvetlenül nem tudjuk az elsőbbséget megállapítani. Objektumok

összehasonlítására a compareTo() metódus használható. A String osztály tartalmazza, nekünk

csak használnunk kell. Az általunk létrehozott osztályokban többnyire a programozónak kell

megvalósítani.

Page 36: Programozási tételekipari118-szerencs.sulinet.hu/jegyzet/info/Programozási...Programozási tételek 10 – 11. évfolyam 3. oldal Programozási tételek, algoritmusok Az algoritmus

Programozási tételek 10 – 11. évfolyam

35. oldal

Feladat:

Rendezzünk egy sztringeket tartalmazó 10 elemű tömböt nagyság szerint.

Java-kód:

package rendezesstring;

import java.util.Scanner;

public class RendezesString {

public static void main(String[] args) {

// deklaráció

String[] tomb = new String[10];

// tömb feltöltése sztringekkel

feltolt(tomb);

// elemek kiíratása

System.out.println("A tömb elemei:");

lista(tomb);

// rendezés

rendez(tomb);

// rendezett tömb kiíratása

System.out.println("\nA rendezett tömb elemei:");

lista(tomb);

}

// a tömb feltöltése sztringekkel

public static void feltolt(String[] t){

Scanner be = new Scanner(System.in);

for(int i = 0; i < t.length; i++){

System.out.print("Szöveg: ");

t[i] = be.nextLine();

}

}

// a tömb elemeinek listázása

public static void lista(String[] t){

for(int i = 0; i < t.length; i++)

System.out.print(t[i]+", ");

System.out.println("");

}

// a rendezettség megállapítása függvénnyel

public static boolean rendezett(String str1, String str2){

// a következő esetben ad vissza igazat

// ha str1 <= str2

return str1.compareTo(str2) <= 0;

}

// a csere eljárás megvalósítása

public static void csere(String[] t, int mit, int mivel){

String temp = t[mit];

t[mit] = t[mivel];

t[mivel] = temp;

}

// a tömb elemeinek rendezése minimum-kiválasztásos

rendezéssel

public static void rendez(String[] t){

int minIndex;

for(int i = 0; i < t.length-1; i++){

minIndex = i;

for(int j = i+1; j < t.length; j++){

Page 37: Programozási tételekipari118-szerencs.sulinet.hu/jegyzet/info/Programozási...Programozási tételek 10 – 11. évfolyam 3. oldal Programozási tételek, algoritmusok Az algoritmus

Programozási tételek 10 – 11. évfolyam

36. oldal

if(!rendezett(t[minIndex], t[j]))

minIndex = j;

}

if(minIndex != i){

csere(t, i, minIndex);

}

}

}

}

Futási kép:

Szöveg: alma

Szöveg: körte

Szöveg: banán

Szöveg: eper

Szöveg: málna

Szöveg: szamóca

Szöveg: ribizli

Szöveg: szőlő

Szöveg: cseresznye

Szöveg: meggy

A tömb elemei:

alma, körte, banán, eper, málna, szamóca, ribizli, szőlő,

cseresznye, meggy,

A rendezett tömb elemei:

alma, banán, cseresznye, eper, körte, meggy, málna, ribizli,

szamóca, szőlő,

BUILD SUCCESSFUL (total time: 1 minute 2 seconds)

Feladat:

Töltsünk fel egy 10 elemű tömböt téglalapokkal (osztály létrehozása). Majd rendezzük

terület szerint csökkenő sorrendbe.

Java-kód:

A RendezTeglalapMinKival osztály forráskódja package rendezteglalapminkival;

import java.util.Random;

public class RendezTeglalapMinKival {

public static void main(String[] args) {

// deklarációk

Random rnd = new Random();

Teglalap[] tomb = new Teglalap[10];

int a;

int b;

// tömb feltöltése ciklusban véletlenszám generálással

// 1..100 közötti oldal hosszúságok

for(int i = 0; i < tomb.length; i++){

a = rnd.nextInt(100)+1;

b = rnd.nextInt(100)+1;

// téglalap létrehozása konstruktorral

tomb[i] = new Teglalap(a, b);

}

Page 38: Programozási tételekipari118-szerencs.sulinet.hu/jegyzet/info/Programozási...Programozási tételek 10 – 11. évfolyam 3. oldal Programozási tételek, algoritmusok Az algoritmus

Programozási tételek 10 – 11. évfolyam

37. oldal

// listázás

System.out.println("Rendezés előtt:");

lista(tomb);

// rendezés terület szerint növekvően

rendez(tomb);

// rendezés után listázás

System.out.println("\nRendezés után:");

lista(tomb);

}

// a téglalapok adatainak listázása

public static void lista(Teglalap[] t){

for(int i = 0; i < t.length; i++)

System.out.println((i+1)+". "+t[i].toString());

}

// minimum-kiválasztásos rendezés

public static void rendez(Teglalap[] t){

int minIndex;

for(int i = 0; i < t.length-1; i++){

minIndex = i;

for(int j = i+1; j < t.length; j++){

if(!rendezett(t[minIndex], t[j])){

minIndex = j;

}

}

if(minIndex != i){

csere(t, minIndex, i);

}

}

}

// terület alapján a rendezettséget mutató metódus

private static boolean rendezett(Teglalap a, Teglalap b){

return a.terulet() < b.terulet();

}

// csere metódus

private static void csere(Teglalap[] t, int i, int j){

Teglalap temp;

temp = t[i];

t[i] = t[j];

t[j] = temp;

}

}

A rendezés a Teglalap osztály egy primitív típusú tulajdonsága (adattagja) alapján történik,

ezért nem kell compareTo() metódus.

A Teglalap osztaly forraskódja package rendezteglalapminkival;

public class Teglalap {

// példány adattagok

private int a;

private int b;

// statikus adattag - a létrehozott téglalap példányok

száma

private static int db = 0;

// konstruktor

Page 39: Programozási tételekipari118-szerencs.sulinet.hu/jegyzet/info/Programozási...Programozási tételek 10 – 11. évfolyam 3. oldal Programozási tételek, algoritmusok Az algoritmus

Programozási tételek 10 – 11. évfolyam

38. oldal

public Teglalap(int _a, int _b){

a = _a;

b = _b;

db++;

}

// adatlekérdező (getter) példány metódusok

public int getA() {

return a;

}

public int getB() {

return b;

}

// adatlekérdező statikus metódus

public static int getDb() {

return db;

}

// terület számítás

public int terulet(){

return a *b;

}

// kerület számítás

public int kerulet(){

return 2 * (a + b);

}

// toString() metódus

@Override // az Object osztály felülírt metódusa

public String toString(){

return "téglalap:\n"+

" a = "+a+" cm"+"\n"+

" b = "+b+" cm"+"\n"+

" terület = "+this.terulet()+" cm2"+"\n"+

" kerület = "+this.kerulet()+" cm"+"\n";

}

}

Futási kép részlet:

run:

Rendezés előtt:

1. téglalap:

a = 2 cm

b = 19 cm

terület = 38 cm2

kerület = 42 cm

2. téglalap:

a = 68 cm

b = 81 cm

terület = 5508 cm2

kerület = 298 cm

3. téglalap:

a = 5 cm

b = 32 cm

terület = 160 cm2

kerület = 74 cm

Page 40: Programozási tételekipari118-szerencs.sulinet.hu/jegyzet/info/Programozási...Programozási tételek 10 – 11. évfolyam 3. oldal Programozási tételek, algoritmusok Az algoritmus

Programozási tételek 10 – 11. évfolyam

39. oldal

4. téglalap:

a = 24 cm

b = 49 cm

terület = 1176 cm2

kerület = 146 cm

Téglalap objektumok száma: 10 db

Rendezés után:

1. téglalap:

a = 2 cm

b = 19 cm

terület = 38 cm2

kerület = 42 cm

2. téglalap:

a = 53 cm

b = 3 cm

terület = 159 cm2

kerület = 112 cm

3. téglalap:

a = 5 cm

b = 32 cm

terület = 160 cm2

kerület = 74 cm

4. téglalap:

a = 46 cm

b = 11 cm

terület = 506 cm2

kerület = 114 cm

Rendezés compareTo() metódussal:

A rendezéskor objektumokat hasonlítunk össze, nem egy primitív értékű résztulajdonságot.

Java-kód:

package rendezteglalapminkival_compareTo;

import java.util.Random;

public class RendezTeglalapMinKival_compareTo {

public static void main(String[] args) {

// deklarációk

Random rnd = new Random();

Teglalap[] tomb = new Teglalap[10];

int a;

int b;

// tömb feltöltése ciklusban véletlenszám generálással

// 1..100 közötti oldal hosszúságok

for(int i = 0; i < tomb.length; i++){

a = rnd.nextInt(100)+1;

b = rnd.nextInt(100)+1;

// téglalap létrehozása konstruktorral

tomb[i] = new Teglalap(a, b);

}

Page 41: Programozási tételekipari118-szerencs.sulinet.hu/jegyzet/info/Programozási...Programozási tételek 10 – 11. évfolyam 3. oldal Programozási tételek, algoritmusok Az algoritmus

Programozási tételek 10 – 11. évfolyam

40. oldal

// listázás

System.out.println("Rendezés előtt:");

lista(tomb);

// létrehozott téglalpok száma

System.out.println("Téglalap objektumok száma:

"+Teglalap.getDb()+" db");

// rendezés terület szerint növekvőleg

rendez(tomb);

// rendezés után listázás

System.out.println("\nRendezés után:");

lista(tomb);

}

// a téglalapok adatainak listázása

public static void lista(Teglalap[] t){

for(int i = 0; i < t.length; i++)

System.out.println((i+1)+". "+t[i].toString());

}

// minimum-kiválasztásos rendezés

public static void rendez(Teglalap[] t){

int minIndex;

for(int i = 0; i < t.length-1; i++){

minIndex = i;

for(int j = i+1; j < t.length; j++){

// ha a j. elem kisebb mint a minIndex., akkor

csere

if(t[j].compareTo(t[minIndex]) < 0){

minIndex = j;

}

}

if(minIndex != i){

csere(t, minIndex, i);

}

}

}

// csere metódus

private static void csere(Teglalap[] t, int i, int j){

Teglalap temp;

temp = t[i];

t[i] = t[j];

t[j] = temp;

}

}

package rendezteglalapminkival_compareTo;

public class Teglalap {

// példány adattagok

private int a;

private int b;

// statikus adattag - a létrehozott téglalap példányok

száma

private static int db = 0;

// konstruktor

public Teglalap(int _a, int _b){

a = _a;

b = _b;

Page 42: Programozási tételekipari118-szerencs.sulinet.hu/jegyzet/info/Programozási...Programozási tételek 10 – 11. évfolyam 3. oldal Programozási tételek, algoritmusok Az algoritmus

Programozási tételek 10 – 11. évfolyam

41. oldal

db++;

}

// adatlekérdező (getter) példány metódusok

public int getA() {

return a;

}

public int getB() {

return b;

}

// adatlekérdező statikus metódus

public static int getDb() {

return db;

}

// terület számítás

public int terulet(){

return a *b;

}

// kerület számítás

public int kerulet(){

return 2 * (a + b);

}

// toString() metódus

@Override

public String toString(){

return "téglalap:\n"+

" a = "+a+" cm"+"\n"+

" b = "+b+" cm"+"\n"+

" terület = "+this.terulet()+" cm2"+"\n"+

" kerület = "+this.kerulet()+" cm"+"\n";

}

/*

* összehasonlításhoz a compareTo() metódus

* ha a megszólított objektum területe kisebb, mint a

* paraméterül kapott objektum területe, akkor a

* visszatérési érték negatív, ha egyenlő a két érték,

* akkor az eredmény nulla, ha nagyobb a paraméter

* értéke, akkor pedig pozitív

*/

public int compareTo(Teglalap t){

return this.terulet() - t.terulet();

}

}

Buborék rendezés

A buborék rendezés a szomszédos elemeket cseréli, ha a sorrend nem megfelelő. Kezdetben

az első két elemet hasonlítjuk össze, és szükség esetén felcseréljük őket. A második lépésben

a 2. és a 3. elemet hasonlítjuk, és ha kell, cseréljük. Ezt így folytatjuk a sorozat végéig. Ekkor

növekvő rendezettséget feltételezve a sorozat végén lesz a legnagyobb elem. A második

ciklusban, már csak az utolsó előtti elemig végezzük a hasonlítást és szükség esetén a cserét.

Ha a második ciklus lefutott, a sorozat utolsó két eleme már a helyén van. A harmadik, és az

Page 43: Programozási tételekipari118-szerencs.sulinet.hu/jegyzet/info/Programozási...Programozási tételek 10 – 11. évfolyam 3. oldal Programozási tételek, algoritmusok Az algoritmus

Programozási tételek 10 – 11. évfolyam

42. oldal

azt követő ciklusokban egyre kisebb része marad rendezetlenül a sorozatnak. Utolsó ciklus az

első két elemet rendezi.

Algoritmus:

Buborék(T: tömb[1..N] egész)

Deklaráció

i, j: egész

Buborék_kezd

Ciklus i:= N-1-től 1-ig -1-esével

Ciklus j:= 1-től i-ig 1-esével

Ha A[j] > A[j+1] akkor

csere(A[j], A[j+1])

Elágazás vége

Ciklus vége

Ciklus vége

Buborék vége

Példa:

Ez a megvalósítás a legegyszerűbb, viszont egy rendezett tömbön is a (külső ciklus) * (belső

ciklus) számszor fut le, és végzi az összehasonlításokat. Javíthatunk az algoritmuson, ha

Page 44: Programozási tételekipari118-szerencs.sulinet.hu/jegyzet/info/Programozási...Programozási tételek 10 – 11. évfolyam 3. oldal Programozási tételek, algoritmusok Az algoritmus

Programozási tételek 10 – 11. évfolyam

43. oldal

figyeljük, hogy a belső ciklusban történt-e csere. Ha nem, akkor a következő külső ciklusban

sem fog. Így abba lehet hagyni a rendezést. Ezt mutatja be a következő megvalósítás.

Algoritmus:

Buborék2(T: tömb[1..N] egész)

Deklaráció

i, j: egész

vége: logikai

Buborék2 kezdet

i:= N-1

vége:= HAMIS

Ciklus amíg i >= 1 ÉS NEM vége

vége:= IGAZ

Ciklus j:= 1-től i-ig 1-esével

Ha T[j] > T[j+1] akkor

csere(T[j], T[j+1])

vége:= HAMIS

Ha vége

Ciklus vége

i:= i-1

Ciklus vége

Buborék2 vége

Példa:

Page 45: Programozási tételekipari118-szerencs.sulinet.hu/jegyzet/info/Programozási...Programozási tételek 10 – 11. évfolyam 3. oldal Programozási tételek, algoritmusok Az algoritmus

Programozási tételek 10 – 11. évfolyam

44. oldal

Ha a belső ciklusban kiderül, hogy a sorozat már rendezett, akkor kilép. Viszont a külső

ciklus csak egyet lép, pedig a rendezettség többet is megengedne. Ezen segíthetünk, ha

megjegyezzük azt a sorszámot, ahol utoljára kellett cserélni. E fölött a sorozat rendezett, így

felesleges újra végigjárni. A harmadik algoritmus ezt mutatja be.

Algoritmus:

Buborék3(T: tömb[1..N] egész)

Deklaráció

i, j: egész

utolsó_csere

Buborék3 kezdet

i:= N-1

Ciklus amíg i >= 1

utolsó_csere:= 0

Ciklus j:= 1-től i-ig 1-esével

Ha T[j] > T[j+1] akkor

csere(T[j], T[j+1])

utolsó_csere:= j

Ha vége

Ciklus vége

i:= utolsó_csere-1

Ciklus vége

Buborék3 vége

Példa:

Page 46: Programozási tételekipari118-szerencs.sulinet.hu/jegyzet/info/Programozási...Programozási tételek 10 – 11. évfolyam 3. oldal Programozási tételek, algoritmusok Az algoritmus

Programozási tételek 10 – 11. évfolyam

45. oldal

A második és a harmadik buborékrendezés akkor hatékony, ha a sorozat nagy része rendezett.

Feladat:

Készítsünk programot, amely az iskolai sportnap eredményeit tárolja és dolgozza fel!

A sportnapon egyéni számok vannak (futás, gerelyhajítás, kislabdadobás,

kosárbadobás). Vigyük fel az adatokat 5 diákra, és listázzuk ki csökkenő sorrendben

az eredményeket számonként, és összesítésben is. Az összesítésben a sorrendet az

határozza meg, hogy ki nyert többször.

Feladat:

Tároljuk el egy hónap napi középhőmérsékleti értékeit! Majd menüből engedje meg az

adatok módosítását, adjon listát a bevitt adatokról akár nap szerinti sorrendben, akár

hőméréskelt szerint növekvően, vagy csökkenően. A naphoz írjuk ki a hőmérsékletet,

és a hőmérséklethez a napot.

Beszúrásos rendezés

A beszúrásos, vagy pókerrendezés hasonlít arra, ahogy az ember kártyaosztás után elrendezi a

lapokat a kezében. Felvesszük az első lapot, majd a másodikat, és helyére tesszük. A helyét,

egy adott rendező elv határozza meg. Minden újabb lapnál megkeressük és elkészítjük a

helyét, majd betesszük a lapot.

Algoritmus:

Beszúrásos(T: tömb[1..N] egész)

Deklaráció

x, i, j: egész

Beszúrásos kezdet

Ciklus i:= 2-től N-ig

j:= i-1

x:= T[i]

Ciklus amíg j >= 1 ÉS x < T[j]

T[j+1]:= T[j]

j:= j-1

Ciklus vége

T[j+1]:= x

Ciklus vége

Beszúrásos vége

Előnyök:

Hatékony kis adatsorok esetén

Hatékony, ha az adatsorok már részben rendezettek

Gyakorlatban hatékonyabb a többi O(n2)-es rendezésnél

Online algoritmus, képes rendezni egy listát az új elemek felvételekor

Page 47: Programozási tételekipari118-szerencs.sulinet.hu/jegyzet/info/Programozási...Programozási tételek 10 – 11. évfolyam 3. oldal Programozási tételek, algoritmusok Az algoritmus

Programozási tételek 10 – 11. évfolyam

46. oldal

Rendezések összehasonlítása4

A rendezések hatékonyságát általában a szükséges összehasonlítások, cserék átlagos és

maximális száma és az extra tárigény alapján végezzük.

„A nagy ordó jelölés egy olyan, matematikában használt jelölésmód, amely tömören fejezi ki

egy adott függvény növekedésének mértékét. Informatikában általában egy algoritmus

futásidejének jellemzésére használjuk: a vizsgált függvény a futáshoz szükséges időt adja meg

a bemenet hosszának függvényében. Leegyszerűsítve, egy O(n^2) futásidejű algoritmus kétszer

akkora méretű bemenetre négyszer annyi ideig fog futni, háromszor akkora bemenetre

kilencszer annyi ideig. Míg maga a futásidőt leíró függvény függ az implementáció részleteitől

és a futtatáshoz használt architektúrától, az algoritmus nagy ordója csak az algoritmus

alapelvétől függ.”5

Minimum-kiválasztásos rendezés

Helyfoglalás: N+1, azaz O(N)

Hasonlítások száma: N*(N-1)/2, azaz O(N2)

Mozgatások száma: 3*(N-1)/2, azaz O(N)

Buborék rendezés

Helyfoglalás: N+1, azaz O(N)

Hasonlítások száma: N*(N-1)/2, azaz O(N2)

Mozgatások száma: 0 – 3*N*(N-1)/2, azaz O(N2)

Javított Buborékos rendezés

Helyfoglalás: N+1, azaz O(N)

Hasonlítások száma: N-1 – N*(N-1)/2, azaz O(N2)

Mozgatások száma: 0 – 3*N*(N-1)/2, azaz O(N2)

Beszúró rendezés

Helyfoglalás: N+1, azaz O(N)

Hasonlítások száma: N-1 – N*(N-1)/2, azaz O(N2)

Mozgatások száma: 0 – 3*N*(N-1)/2, azaz O(N2)

4 https://hu.wikipedia.org/wiki/Rendezés_(programozás) 5 http://wiki.prog.hu/wiki/Nagy_ordó_jelölés

Page 48: Programozási tételekipari118-szerencs.sulinet.hu/jegyzet/info/Programozási...Programozási tételek 10 – 11. évfolyam 3. oldal Programozási tételek, algoritmusok Az algoritmus

Programozási tételek 10 – 11. évfolyam

47. oldal

Gyorsrendezés

Rekurzív algoritmus, kettéosztja a rendezendő listát egy kiemelt elemnél kisebb és nagyobb

elemekre, majd a részekre külön-külön alkalmazza a gyorsrendezést.

Átlagos eset: 𝑂(𝑛 lg 𝑛)

Legrosszabb eset:

Tárigénye:

Kupacrendezés

A kupacrendezés a használt adatszerkezetről kapta a nevét, a kupacról. Működése során

felépíti a kupacot, majd egyesével kiemeli a gyökérelemet, ami a kupac definíciója miatt a

legnagyobb/legkisebb elem lesz.

Átlagos eset:

Legrosszabb eset:

Tárigénye:

Rendezések animációit bemutató oldal: http://tenger.web.elte.hu/flash/index.htm

Halmazműveletek A halmaz a matematika egyik legalapvetőbb fogalma, melyet leginkább az „összesség”,

„sokaság” szavakkal tudunk körülírni, de mivel igazából alapfogalom; így nem tartjuk

definiálandónak. A naiv halmazelméletben egy halmaz meghatározott, egymástól különböző

objektumok gyűjteménye, összessége. Ezeket az objektumokat a halmaz elemeinek

nevezzük. Azt, hogy eleme az halmaznak, így jelöljük: . Azt pedig, hogy nem

eleme, így: 𝑎 ∉ 𝐴

Tulajdonságok:

Legyenek és tetszőleges halmazok. Akkor mondjuk, hogy az és halmazok

egyenlőek, ha ugyanazok az elemeik, és ezt így jelöljük: .

Azt mondjuk, hogy az halmaz részhalmaza a halmaznak (vagy más szavakkal:

a halmaz tartalmazza az halmazt), ha az minden eleme a halmaznak is

Page 49: Programozási tételekipari118-szerencs.sulinet.hu/jegyzet/info/Programozási...Programozási tételek 10 – 11. évfolyam 3. oldal Programozási tételek, algoritmusok Az algoritmus

Programozási tételek 10 – 11. évfolyam

48. oldal

eleme. Ezt így jelöljük: . Az halmazt a halmaz valódi részhalmazának

nevezzük, ha , és . A valódi részhalmaz jele: 𝐴 ⊂ 𝐵

Azt a halmazt, amelynek minden elemére teljesül, hogy és/vagy , az

és halmazok egyesítésének (más szóval uniójának) nevezzük, és így jelöljük:

.

Azt a halmazt, amelynek minden elemére teljesül, hogy és is, az

és halmazok metszetének nevezzük, és így jelöljük: .

Azt a halmazt, amelynek minden elemére teljesül, hogy , de , az

és halmazok különbségének nevezzük, és így jelöljük: .6

6 Forrás: http://hu.wikipedia.org/wiki/Halmaz

Page 50: Programozási tételekipari118-szerencs.sulinet.hu/jegyzet/info/Programozási...Programozási tételek 10 – 11. évfolyam 3. oldal Programozási tételek, algoritmusok Az algoritmus

Programozási tételek 10 – 11. évfolyam

49. oldal

Metszetképzés tétele

A programozási feladatoknál a halmazokat többnyire tömb adatszerkezettel ábrázoljuk

(reprezentáljuk), így elemek sorozataival dolgozunk.

A metszet, vagy közös rész meghatározása során két vagy több sorozat azon elemeit

válogatjuk ki, amelyek minden sorozatban benne vannak. A sorozatok nincsenek rendezve, és

feltételezzük, hogy minden elem csak egyszer fordul elő az egyes sorozatokban. A képződő

sorozat elemszáma kisebb vagy egyenlő, mint a legkisebb elemszámú bemenő sorozat

elemszáma.

A feladatot úgy oldjuk meg, hogy végigmegyünk az egyik sorozaton, és az aktuális elemet

keressük a többi sorozatban. Ha mindegyikben benne van, akkor betesszük a közös rész

sorozatába.

Pl. adott két halmaz:

A = {4, 7, 3, 9, 0, 8} és elemszám: 6

B = {1, 5, 4, 3, 0, 2, 6, 9} halmazok közös része elemszám: 8

𝐴 ∩ 𝐵 = {4, 3, 9, 0} elemszám: 4.

Algoritmus:

//H1 és H2 halmazok, K azok közös része,

//N, M N természetes számok halmazának, beleértve a 0-át

//feltételezzük, hogy N <= M

Metszet(H1: tömb[N], H2: tömb[M], K: tömb[N])

Deklaráció:

i, j: egész

Metszet kezdet

//A közös rész (K) indexváltozójának inicializálása.

j:=0

//A H1 sorozaton megyünk végig egyesével. - eleme

Ciklus i := 1-től N-ig

Ha H1[i] H2-nek, akkor j := j+1

K[j] := H1[i]

Ha vége

Ciklus vége

Metszet vége

A „H1[i] H2-nek” tartalmazás vizsgálatot érdemes egy külön alprogramban megvalósítani.

Az alprogram függvényszerűen hívódik, és logikai igaz/hamis értéket ad vissza attól függően,

hogy a keresett elem benne van-e a sorozatban.

Page 51: Programozási tételekipari118-szerencs.sulinet.hu/jegyzet/info/Programozási...Programozási tételek 10 – 11. évfolyam 3. oldal Programozási tételek, algoritmusok Az algoritmus

Programozási tételek 10 – 11. évfolyam

50. oldal

Algoritmus:

Eleme(elem: típus, sorozat: tömb[N]): logikai

Deklaráció:

i : egész

Eleme kezdet

//Végigmegyünk a sorozaton

Ciklus i := 1-től N-ig

Ha elem = sorozat[i], akkor

//Ha megtaláltuk, akkor igazzal térünk vissza.

return true

Ciklus vége

//Ha végigmentünk a sorozaton, akkor nincs benne.

Ha i > N, akkor

return false

Eleme vége

Vizsgáljuk meg azt az esetet, amikor három bemenő sorozatunk van.

Ekkor is végigmegyünk az egyik sorozaton, és sorban megvizsgáljuk az aktuális elemet, hogy

benne van-e a másik két sorozatban. A tartalmazás vizsgálatot szintén alprogrammal

valósítjuk meg, egy összetett feltételben.

Algoritmus:

Metszet(H1: tömb[N], H2: tömb[M], H3: tömb[L], K: tömb[N])

Deklaráció:

i, j: egész

Metszet kezdet

//A közös rész (K) indexváltozójának inicializálása.

j:=0

//A H1 sorozaton megyünk végig egyesével. - eleme

Ciklus i := 1-től N-ig

Ha H1[i] H2-nek és H1[i] H3-nak akkor j := j+1

K[j] := H1[i]

Ha vége

Ciklus vége

Metszet vége

Feladat:

Határozzuk meg két 20 elemű egészeket tartalmazó sorozat közös elemeit! A

sorozatok elemeit véletlen generátorral adjuk meg, ahol az egyes elemek 1..99 közül

kerülhetnek ki.

Java-kód:

package metszet;

import java.util.Random;

public class Metszet {

public static void main(String[] args) {

// sorozatok (halmazok) deklarációi

int[] h1 = new int[20];

int[] h2 = new int[30];

Page 52: Programozási tételekipari118-szerencs.sulinet.hu/jegyzet/info/Programozási...Programozási tételek 10 – 11. évfolyam 3. oldal Programozási tételek, algoritmusok Az algoritmus

Programozási tételek 10 – 11. évfolyam

51. oldal

int[] kozos = new int[20];

// tömbök feltöltése véletlen elemekkel 1..99

feltolt(h1);

feltolt(h2);

// elemek listázása

System.out.println("Első sorozat elemei:");

lista(h1);

System.out.println("Második sorozat elemei:");

lista(h2);

// közös rész meghatározása

kozosResz(kozos, h1, h2);

// a metszet elemeinek listázása

System.out.println("A közös elemek:");

lista(kozos);

}

// a feltöltést végző metódus,

// minden elem csak egyszer fordul elő

public static void feltolt(int[] t){

Random rnd = new Random();

int vel;

for(int i = 0; i < t.length; i++){

do{

vel = rnd.nextInt(99)+1;

}while(benneVan(t, vel));

// ha előállítottunk egy olyat ami nics benne

t[i] = vel;

}

}

// elemet keresünk egy sorozatban

public static boolean benneVan(int[] t, int v){

int i = 0;

// a feltételek sorrendje nem mindegy

while((i < t.length) && (t[i] != v))

i++;

// az index értékétől függ, hogy megtaláltuk-e

return i < t.length;

}

// a listázást végző metódus

public static void lista(int[] t){

for(int i = 0; i < t.length; i++)

System.out.print(t[i]+", ");

System.out.println("");

}

// a metszetet meghatározó metódus

public static void kozosResz(int[] k, int[] t1, int[] t2){

int kIndex = -1;

// a rövidebb sorozaton végigmegyünk

for(int i = 0; i < t1.length; i++){

// megnézzük, hogy benne van-e

// az adott elem a másik sorozazban

// ha benn van beletesszük a közösbe

if(benneVan(t2, t1[i])){

kIndex++;

k[kIndex] = t1[i];

}

}

Page 53: Programozási tételekipari118-szerencs.sulinet.hu/jegyzet/info/Programozási...Programozási tételek 10 – 11. évfolyam 3. oldal Programozási tételek, algoritmusok Az algoritmus

Programozási tételek 10 – 11. évfolyam

52. oldal

}

}

Futási kép:

run:

Első sorozat elemei:

72, 45, 69, 14, 63, 96, 51, 56, 64, 36, 29, 59, 89, 71, 90, 82,

93, 37, 11, 98,

Második sorozat elemei:

5, 69, 34, 85, 3, 88, 90, 27, 4, 41, 82, 39, 63, 71, 91, 67, 6,

22, 15, 57, 58, 24, 66, 76, 40, 61, 38, 89, 42, 86,

A közös elemek:

69, 63, 89, 71, 90, 82, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,

0,

BUILD SUCCESSFUL (total time: 0 seconds)

A megvalósítás szépséghibája, hogy a közös sorozat elemeit a tömb teljes hosszáig kiírja. Egy

megoldás lehet, ha a listázást a kozosResz() metóduson belül végezzük.

Feladat:

Készítsük el a fenti feladatot három bemeneti sorozatra.

Unióképzés tétele

A bemenő sorozatokból készítünk egy kimenő sorozatot. Itt a bemenő sorozatok egyesítését

(unióját) keressük. Az unióba bekerül az elem, ha része valamelyik kiindulási sorozatnak. A

unió elemszáma maximálisan a kiindulási sorozatok elemszámainak az összege lehet. Itt is

követelmény, hogy az egyes sorozatokban minden elem csak egyszer szerepel.

A feladatot úgy oldjuk meg, hogy az első sorozatot teljes egészében beletesszük a kimenő

sorozatba. Majd a többi sorozatot megvizsgáljuk, hogy van-e olyan elemük, amely még nincs

benne az unió sorozatában és, ha van, akkor beletesszük.

Algoritmus:

//H1 és H2 halmazok, elemszámuk N, M N

//U azok egyesítése, elemszáma L = N+M

Unio(H1: tömb[N], H2: tömb[M], U: tömb[L])

Deklaráció:

i, j: egész

Unio kezdet

//Első sorozat átmásolása a kimenő (U) sorozatba.

//i értékére szükségünk van

i := 0

Ciklus, amíg i <= N

i := i + 1

U[i] := H1[i]

Ciklus vége

//U feltöltése H2-es sorozat azon elemeivel,

//amelyeket még nem tartalmaz.

Page 54: Programozási tételekipari118-szerencs.sulinet.hu/jegyzet/info/Programozási...Programozási tételek 10 – 11. évfolyam 3. oldal Programozási tételek, algoritmusok Az algoritmus

Programozási tételek 10 – 11. évfolyam

53. oldal

//A ciklus a H2 elemein megy végig.

Ciklus j := 1-től M-ig

//Ha az aktuális elem nincs benne, akkor beletesszük.

Ha H2[j] U-nak, akkor //Az U sorozat indexének (i) értékét léptetni kell.

i := i+1

U[i] := H2[j]

Ha vége

Ciklus vége

Metszet vége

Az elemvizsgálat algoritmusa a metszetképzés tételénél található.

Feladat:

Az előző feladatot bővítve, készítsük el a két sorozat unióját.

Java-kód:

package metszetUnio;

import java.util.Random;

public class MetszetUnio {

public static void main(String[] args) {

// sorozatok (halmazok) deklarációi

int[] h1 = new int[20];

int[] h2 = new int[30];

int[] kozos = new int[20];

int[] unio = new int[20+30];

// tömbök feltöltése véletlen elemekkel 1..99

feltolt(h1);

feltolt(h2);

// elemek listázása

System.out.println("Első sorozat elemei:");

lista(h1);

System.out.println("Második sorozat elemei:");

lista(h2);

// közös rész meghatározása

kozosResz(kozos, h1, h2);

// a metszet elemeinek listázása

System.out.println("A közös elemek:");

lista(kozos);

// unió meghatározása

unioKepzes(unio, h1, h2);

System.out.println("Az egyesítés elemei:");

lista(unio);

}

// a feltöltést végző metódus,

// minden elem csak egyszer fordul elő

public static void feltolt(int[] t){

Random rnd = new Random();

int vel;

for(int i = 0; i < t.length; i++){

do{

vel = rnd.nextInt(99)+1;

}while(benneVan(t, vel));

// ha előállítottunk egy olyat ami nics benne

Page 55: Programozási tételekipari118-szerencs.sulinet.hu/jegyzet/info/Programozási...Programozási tételek 10 – 11. évfolyam 3. oldal Programozási tételek, algoritmusok Az algoritmus

Programozási tételek 10 – 11. évfolyam

54. oldal

t[i] = vel;

}

}

// elemet keresünk egy sorozatban

public static boolean benneVan(int[] t, int v){

int i = 0;

// a feltételek sorrendje nem mindegy

while((i < t.length) && (t[i] != v))

i++;

// az index értékétől függ, hogy megtaláltuk-e

return i < t.length;

}

// a listázást végző metódus

public static void lista(int[] t){

for(int i = 0; i < t.length; i++)

System.out.print(t[i]+", ");

System.out.println("");

}

// a metszetet meghatározó metódus

public static void kozosResz(int[] k, int[] t1, int[] t2){

int kIndex = -1;

// a rövidebb sorozaton végigmegyünk

for(int i = 0; i < t1.length; i++){

// megnézzük, hogy benne van-e

// az adott elem a másik sorozazban

// ha benn van beletesszük a közösbe

if(benneVan(t2, t1[i])){

kIndex++;

k[kIndex] = t1[i];

}

}

}

// Az uniót meghatározó metódus

public static void unioKepzes(int[] u, int[] t1, int[] t2){

// az első sorozatot teljes egészében

// beletesszük az unió sorozatába

int i;

for(i = 0; i < t1.length; i++)

u[i] = t1[i];

// az i értéke kilépve a ciklusból egyel nő!!!

// végigmegyünk a második tömbön

for(int j = 0; j < t2.length; j++)

// ha még nincs benne a t1-ben a t2 aktuális eleme

if(!benneVan(t1, t2[j])){

// akkor beletesszük az unióba

u[i] = t2[j];

i++;

}

}

}

Különbség-képzés tétele

Egy A és B halmaz különbségén érjük azt az A\B-vel jelölt halmazt, amelynek elemei A-nak

elmei, de B-nek nem.

Page 56: Programozási tételekipari118-szerencs.sulinet.hu/jegyzet/info/Programozási...Programozási tételek 10 – 11. évfolyam 3. oldal Programozási tételek, algoritmusok Az algoritmus

Programozási tételek 10 – 11. évfolyam

55. oldal

A feladat megoldása: a kisebbítendő „A” sorozaton végigmegyünk, és ha az aktuális elem

nincs benne a B sorozatban, akkor beletesszük a kimeneti (különbség) sorozatba.

Algoritmus:

//K = H1 \ H2

Különbség(H1: tömb[N], H2: tömb[M], K: tömb[L])

Deklaráció:

i, j: egész

Különbség kezdet

j := 0

Ciklus i := 1-től N-ig

Ha H1[i] H2, akkor j := j + 1

K[j] := H1[i]

Ha vége

Ciklus vége

Különbség vége

A „H1[i] H2” (nem eleme) elemvizsgálat a tagadása a fentebb (unióképzésnél)

megfogalmazott tartalmazás vizsgálatot megvalósító függvénynek.

Feladat:

Az előző feladatokat bővítve, készítsük el a sorozatok különbségét. (első \ második)

Java-kód (program részlet):

public static void main(String[] args) {

int[] minus = new int[20]; // a méret a kisebbítendő

elemszáma

// különbség meghatározása

kulonbsegKepzes(minus, h1, h2);

System.out.println("A különbség képzés elemei:");

lista(minus);

}

// h1 - h2 különbség képzése

public static void kulonbsegKepzes(int[] m, int[] h1, int[]

h2){

int j = 0;

for(int i = 0; i < h1.length; i++)

if(!benneVan(h2, h1[i])){

m[j] = h1[i];

j++;

}

}

Page 57: Programozási tételekipari118-szerencs.sulinet.hu/jegyzet/info/Programozási...Programozási tételek 10 – 11. évfolyam 3. oldal Programozási tételek, algoritmusok Az algoritmus

Programozási tételek 10 – 11. évfolyam

56. oldal

Rekurzió A rekurzió során a feladat megoldásához úgy jutunk el, hogy találunk egy ismételt

egyszerűsítési folyamatot. Ennek a folyamatnak olyannak kell lennie, hogy véges sok

lépésben eljussunk egy olyan állapotba, amelynél a megoldás már magától értetődő. Tehát, a

problémát visszavezetjük egy egyszerűbb problémára, majd ezt az egyszerűsítést addig

végezzük, amíg eljutunk a legegyszerűbb (triviális) esethez. Ezt megoldva, már az eggyel

bonyolultabb eset is megoldható, míg végül eljutunk a teljes probléma megoldásához.

Például az első N természetes szám összegének kiszámítása, visszavezethető az N-1 össze-

gének meghatározására, amelyhez még hozzáadjuk az N értékét.

összeg(N) = összeg(N-1) + N

összeg(N-1) = összeg(N-2) + (N-1)

Ezt az egyszerűsítést addig folytatjuk, amíg N=0 legegyszerűbb esetet meg nem találjuk. Ha

ezt ismerjük, akkor meg tudjuk oldani az N=1 esetet is.

összeg(1) = összeg(0) + 1

Nézzük meg egy példán keresztül, legyen N = 5:

összeg(5) = összeg(4) + 5

összeg(4) = összeg(3) + 4

összeg(3) = összeg(2) + 3

összeg(2) = összeg(1) + 2

összeg(1) = összeg(0) + 1

összeg(0) = 0

Ez a triviális eset, innen fokozatosan megoldhatók a bonyolultabb esetek is.

összeg(1) = 0 +1

összeg(2) = 1+2

összeg(3) = 3 +3

összeg(4) = 6 +4

összeg(5) = 10 +5 = 15

Rekurzív függvények

A rekurzív feladatokat, rekurzív alprogramokkal (eljárás, függvény) oldjuk meg.

Beszélhetünk,

közvetlen rekurzióról, amikor az alprogram saját magát hívja meg, illetve

közvetett rekurzióról, amikor az alprogram, egy másik alprogram által hívódik meg.

Az „A” alprogram hívja „B” alprogramot, és „B” hívja „A”-t.

A rekurzív alprogramban szerepelnie kell:

Page 58: Programozási tételekipari118-szerencs.sulinet.hu/jegyzet/info/Programozási...Programozási tételek 10 – 11. évfolyam 3. oldal Programozási tételek, algoritmusok Az algoritmus

Programozási tételek 10 – 11. évfolyam

57. oldal

egy egyszerűsítési folyamatnak, amely lépésről-lépésre változik és a triviális esetben

végződik,

egy küszöbfeltételnek, amely leállítja az egyszerűsítést.

Az alprogramok hívása során felépül egy hívási lánc, a triviális eset megtalálásáig. Majd

ezután a lánc utolsó tagja (triviális eset) visszaadja a vezérlést a hívási lánc utolsó előtti

tagjának. Miután megoldotta a saját részproblémáját, az ezt megelőző alprogramra kerül a

vezérlés. A részproblémák megoldása a hívási lánc első eleméig folytatódik, amelynek

végrehajtása során a teljes feladat megoldódik.7

Minden alprogram hívása során a verembe kerülnek a lokális változók, a paraméterek, és a

visszatérési cím. A hívási láncon való visszajutást ez az adatszerkezet segíti. A rekurzió

hátránya, hogy a verem egy véges adatszerkezet, ezért a rekurzió mélysége korlátozott. Illetve

az alprogramok hívása lassítja a feldolgozást. Előnye viszont az átláthatóbb

programszerkezet.

Feladat:

Határozzuk meg 1..20 intervallumból választott 10 véletlen egész szám összegét

rekurzív algoritmussal.

Java-kód:

package rekurzivosszegzes;

import java.util.Random;

public class RekurzivOsszegzes {

public static void main(String[] args) {

Random rnd = new Random();

int szam;

System.out.println("A program megadja 10 véletlenül

választott "

+ "egész szám összegét.");

for(int i = 1; i <= 10; i++){

//véletlen szám előállítása 1..20 között

szam = rnd.nextInt(20)+1;

System.out.print(i+". véletlen szám: "+szam);

//rekurzív összegző függvény eredményének kiíratása

System.out.println(" -- összege:

"+osszegRek(szam));

}

}

//Az összegzést megvalósító rekurzív algoritmus

public static int osszegRek(int n){

if(n == 0)

return 0;

7 Juhász István – Programozási nyelvek 1 – Debreceni Egyetem, egyetemi jegyzet, 2001

Page 59: Programozási tételekipari118-szerencs.sulinet.hu/jegyzet/info/Programozási...Programozási tételek 10 – 11. évfolyam 3. oldal Programozási tételek, algoritmusok Az algoritmus

Programozási tételek 10 – 11. évfolyam

58. oldal

else

return osszegRek(n - 1) + n;

}

}

A rekurzív összegző függvény az első N természetes szám összegzését végzi. Leállító feltétele

az (n==1) eset, ekkor az eredmény 1, egyébként újra hívja magát egyel kisebb értékkel (N-1.

Így kialakul egy programhívási lánc, amely az N = 1 esetben leáll. Majd ezek után a

függvényhívások fordított sorrendben kiértékelődnek, hozzáadódik az „N.” elem, és végül

előáll az eredmény.

Rekurzív és iteratív forma

Minden rekurzív feladatnak, van iteratív párja.

Feladat:

Számítsuk ki egy adott n nemnegatív egész szám összegét iteratív módon.

Java-kód:

package iterativosszegzes;

import java.util.Random;

public class IterativOsszegzes {

public static void main(String[] args) {

Random rnd = new Random();

int szam;

System.out.println("A program megadja 10 véletlenül

választott "

+ "egész szám összegét.");

for(int i = 1; i <= 10; i++){

//véletlen szám előállítása 1..20 között

szam = rnd.nextInt(20)+1;

System.out.print(i+". véletlen szám: "+szam);

//iteratív összegző függvény eredményének kiíratása

System.out.println(" -- összege:

"+osszegIter(szam));

}

}

//Az összegzést megvalósító iteratív algoritmus

public static int osszegIter(int n){

int szum = 0;

for(int i = 0; i <= n; i++)

szum += i;

return szum;

}

}

Iteratív formánál az összegzést végző metódus ciklust használ.

Page 60: Programozási tételekipari118-szerencs.sulinet.hu/jegyzet/info/Programozási...Programozási tételek 10 – 11. évfolyam 3. oldal Programozási tételek, algoritmusok Az algoritmus

Programozási tételek 10 – 11. évfolyam

59. oldal

Feladat:

Számítsuk ki egy adott n nemnegatív egész szám faktoriálisát (n!).

Java-kód:

package faktorialis;

import java.util.Scanner;

public class Faktorialis {

public static void main(String[] args) {

Scanner be = new Scanner(System.in);

System.out.println("Faktoriális");

System.out.print("Szám: ");

int szam = be.nextInt();

int n;

//-1 végjelig folytatjuk

while(szam != -1){

if(szam < 0)

System.out.println("Csak nemnegatív számnak van

faktoriálisa!");

else {

n = faktRek(szam);

System.out.println(szam+" faktoriálisa: "+n);

}

System.out.print("Szám: ");

szam = be.nextInt();

}

}

//Faktoriálist számító metódus iteratív alak

public static int fakt(int sz){

int n = 1;

if(sz == 0)

return 1;

else{

while(sz > 0){

n *= sz;

sz--;

}

return n;

}

}

//Faktoriálist számító metódus rekurzív alak

public static int faktRek(int sz){

if(sz == 0)

return 1;

else

return sz * fakt(sz-1);

}

}

Page 61: Programozási tételekipari118-szerencs.sulinet.hu/jegyzet/info/Programozási...Programozási tételek 10 – 11. évfolyam 3. oldal Programozási tételek, algoritmusok Az algoritmus

Programozási tételek 10 – 11. évfolyam

60. oldal

Gyorsrendezés (QuickSort)

„Osztd meg és uralkodj” elve

A gyorsrendezés (quicksort) az egyik leghatékonyabb rendező algoritmus, amely a rekurzióra

épül. A rendezés alapja, hogy a sorozatot az elemek cserélgetésével két olyan részre osztjuk,

amelynek elemei a sorozat egy kitüntetett eleménél kisebbek, illetve nagyobbak. Majd ezt a

módszert alkalmazva a két részsorozatra, végül 1 elemű részsorozatokat kapunk, amelyek már

önmagukban rendezettek. A kitüntetett elem lehet például a sorozat középső eleme.

Rendezendő:

1. 6, 2, 5, 8, 4, 9, 3

Rendezés:

2. 6, 2, 5, 8, 4, 9, 3 3. 6, 2, 5, 3, 4, 9, 8 4. 4, 2, 5, 3, 6, 8, 9 5. 4, 2, 3, 5, 6 6. 2, 4, 3 7. 2, 3, 4

A rendezett sorozat:

2, 3, 4, 5, 6, 8, 9

A sárgával kiemelt elemek felcserélődnek. Aláhúzással lett jelölve az a kezdeti sorozat,

illetve később a részsorozatok, amelyeken belül történik az elemek felcserélése. Az első

sorban látható a rendezetlen sorozat. A második sorban a kitüntetett (középső) elem a 8-as.

Megvizsgáljuk, hogy tőle balra csak kisebbek vannak-e, illetve jobbra csak nagyobbak. A

nem megfelelő elemeket kicseréljük csere(8, 3). A harmadik sorban a 4, 9 egymáshoz képest

jó helyen van. Ezután, mivel i > j kilépünk a ciklusból. Két részsorozat (6, 2, 5, 3, 4) és (9, 8)

képződik, amelyet az első alapján elkezdünk rendezni. A rendezett számoknál nincs aláhúzás.

A 6. sorban újra két sorozat van (2), és (4, 3), a 2 önmagában rendezett, így csak a (4, 3)

sorozatot kell rendezni. Az utóbbi két számot felcserélve a sorozat rendezetté válik. A

rendezéshez 6 cserére volt szükség.

Algoritmus:

Gyorsrendezés(Cím T: tömb[1..N] egész, alsó, felső: egész)

i, j: egész

középső: egész

Gyorsrendezés kezdet

i:= alsó

j:= felső

középső:= (alsó + felső) DIV 2

Ciklus

Ciklus amíg T[i] < T[középső]

Page 62: Programozási tételekipari118-szerencs.sulinet.hu/jegyzet/info/Programozási...Programozási tételek 10 – 11. évfolyam 3. oldal Programozási tételek, algoritmusok Az algoritmus

Programozási tételek 10 – 11. évfolyam

61. oldal

i:= i + 1

Ciklus vége

Ciklus amíg T[j] > T[középső]

j:= j – 1

Ciklus vége

Ha i < j akkor

Csere(T[i], T[j])

Ha vége

Ha i <= j akkor

i:= i + 1

j:= j – 1

Ha vége

Ciklus vége Ha i > j

Ha alsó < j akkor

Gyorsrendezés(T, alsó, j)

Ha vége

Ha felső > i akkor

Gyorsrendezés(T, i, felső)

Ha vége

Gyorsrendezés vége

Page 63: Programozási tételekipari118-szerencs.sulinet.hu/jegyzet/info/Programozási...Programozási tételek 10 – 11. évfolyam 3. oldal Programozási tételek, algoritmusok Az algoritmus

Programozási tételek 10 – 11. évfolyam

62. oldal

Felhasznált és ajánlott irodalom 1. Angster Erzsébet – Objektumorientált tervezés és programozás – Java – 2002, 4KÖR

Bt.

2. http://wiki.vmg.sulinet.hu/doku.php?id=informatika:programozas:tetelek – 2015.02.

3. Nagy Gusztáv – Java programozás – v1.3 – 2007

4. Nagy Zsolt – Középiskolai programozás oktatás Pascal nyelven – 2012, saját jegyzet