Az informatika érettségi harmadik tételsora tartalmaz egy feladatot, melyet hatékonyan kell megoldani. A program megírása mellett követelmény a megoldásban használt módszer rövid leírása, kitérve a módszer hatékonyságára. A továbbiakban lássunk néhány ilyen feladatot. 1. A numere.txt szövegállomány első sora egy n (1 n 10000) természetes számot tárol, második sora egy n természetes számból álló növekvő sorozatot. A sorozat elemeit szóköz választja el egymástól és legtöbb kilencjegyűek. a) Írjatok a futási idő és a memória helyfoglalásfüggvényében hatékony Pascal/C++ programot, amely kiírja a képernyőre az állomány második sorában tárolt sorozat egymástól különböző elemeit! Például: ha a NUMERE.TXT állománytartalma: 7 111 111 111 2111 4111 71111 71111 akkor a program által kiírt értékek: 111 2111 4111 71111 b) Írja le röviden, saját szavaival, az a pontban használt módszert, kifejtve annak hatékonyságát! unsigned short n,i; unsigned int x,y; ifstream in("numere.txt"); in>>n>>x; cout<<x<<" "; for (i=1;i<n;i++) in>>y; if (y!=x) cout<<y<<" "; x=y; in.close(); var n,i: word; x,y:longint; assign(f,'numere.txt'); readln(f,n); write(x,' '); for i:=2 to n do read(f,y); if y<>x then write(y,' '); x:=y; b. I. A sorozat első tagját kiolvasva az állományból kiíratjuk a képernyőre és megőrizzük egy x változóban. II. A soron következő tagot kiolvassuk az állományból egy y változóba, majd hasonlítjuk az x változóban lévő értékhez. Amennyiben eltér x értékétől kiíratjuk, x felveszi az y értékét, hogy a következőkben a soron következő elemet már ehhez az értékhez hasonlítsuk. III. A II- at n- 1- szer ismételjük. A módszer futási idő szempontjából hatékony, mivel a sorozat elemeit csak egyszer futjuk végig, vagyis az állományból kiolvasva az értékeket megvizsgáljuk, és szükség esetén ki is íratjuk őket.
Memória szempontjából hatékony, mivel a sorozat elemeinek tárolására nem használtunk tömb adatszerkezetet, hanem csak két egész típusú változót. 2. A numere.txt szöveges állomány első sorában egy n (0<n<10000) természetes szám található, a következő sorban pedig egy- egy szóközzel elválasztva n darab legtöbb kétjegyű természetes szám. a) Írjon a futási idő szempontjából hatékony Pascal/C++ programot, amely meghatározza,hogy az állomány második sorában levő számokból melyek fordulnak elő legalább kétszer! Írasson ki minden ilyen számot, csak egyszer, növekvő sorrendben, ugyanabba a sorba, egy- egy szóközzel elválasztva. Példa: Ha a numere.txt állomány tartalma: 8 44 2 54 74 2 44 9 2 akkor a program a következő értékeket írja ki: 2 44. b) Írja le saját szavaival tömören a használt megoldási módszert, és magyarázza meg, hogy miben rejlik a hatékonysága! unsigned int a[99],i,n; unsigned short x; ifstream in("numere.txt"); in>>n; for (i=0;i<100;a[i]=0,i++); for (i=0;i<n;i++) a[x]++; for (i=0;i<100;i++) if (a[i]>=2) cout<<i<<" "; var a: array[0..99] of word; i,n:longint; x:byte; assign(f,'numere.txt'); readln(f,n); for i:=1 to n do inc(a[x]); for i:=0 to 99 do if a[i]>=2 then write(i,' '); b. Figyelembe véve, hogy a szöveges állományban lévő természetes számok legtöbb kétjegyűek, a feladat megoldására egy százelemű egydimenziós tömböt használunk, mely indexei 0- tól 99- ig tartanak. A tömb elemeinek értéke kezdetben 0. A szöveges állományból rendre kiolvassuk a számokat egy x változóba, majd növeljük a tömbünk x- ik elemét 1- el. Miután a szöveges állományból kiolvastunk minden értéket, a tömb x- ik eleme megadja, hogy az x érték hányszor fordult elő az állományban. Így bejárva a százelemű tömbünket és megvizsgálva az elemek értékét kiírathatjuk növekvő rendben a megadott feltételnek megfelelő értékeket. A módszer hatékonysága abban rejlik, hogy a szöveges állományból való kiolvasáskor megszámoljuk, mindegyik érték hányszor szerepel, utólagos rendezésre nincs szükség. Majd
végigfutva a 100 elemű tömböt ki is írathatjuk azokat az értékeket, melyek legalább kétszer szerepeltek az állományban. 3. a) A date.in állomány legtöbb két számjegyből álló, legtöbb 1000 természetes számot tárol (amelyek közt van legalább egy páros és egy páratlan szám), egy- egy szóközzel elválasztva egymástól. Írjon Pascal/C++ programot, amely beolvassa a számokat a date.in állományból, és a date.out állományba írja, a különböző beolvasott értékeket egy hellyel elválasztva egymástól a következő szabályt betartva: az első sorba legyenek beírva a páratlan számok növekvő sorrendben, majd a második sorba a páros számok csökkenő sorrendben. Válasszon egy hatékony módszert a futási idő függvényében! Példa: Ha a date.in állomány első sorában tárolt számok: 75 12 3 3 18 75 1 3 akkor a date.out állomány tartalma: 1 3 75 18 12 lesz. b) Írja le röviden, saját szavaivall a megoldásra használt módszert, kifejtve, hogy miben áll a hatékonysága! unsigned short x,a[99]; int i; ifstream in("date.in"); for (i=0;i<100;a[i]=0,i++); while (!in.eof()) a[x]++; in.close(); ofstream out("date.out"); for (i=1;i<100;i=i+2) if (a[i]!=0) out<<i<<" "; out<<endl; for (i=98;i>=0;i=i- 2) if (a[i]!=0) out<<i<<" "; out.close(); var a: array[0..99] of word; i, x:shortint; assign(f,'date.in'); while not eof(f) do inc(a[x]); assign(f,'date.out'); rewrite(f); i:=1; while i<100 do if a[i]<>0 then write(f,i,' '); inc(i,2); writeln(f); i:=98; while i>=0 do if a[i]<>0 then write(f,i,' '); dec(i,2); b. Figyelembe véve, hogy a szöveges állományban lévő természetes számok legtöbb kétjegyűek, a feladat megoldására egy 100 elemű egydimenziós tömböt használunk, mely indexei 0- tól 99- ig tartanak. A tömb elemeinek értéke kezdetben 0.
A szöveges állományból rendre kiolvassuk a számokat egy x változóba, majd növeljük a tömbünk x- ik elemét 1- el. Miután a szöveges állományból kiolvastunk minden értéket, a tömb x- ik eleme megadja, hogy, az x érték hányszor fordult elő az állományban. Bejárjuk a tömböt, a tömb második, vagyis az egyes indexű elemétől kiindulva, kettesével haladva. Vizsgáljuk az elemek értékét, és kiíratjuk azon indexeket, ahol a tömb elemének értéke nullától eltér. Ezáltal kiíratjuk a szöveges állományba a páratlan, legfeljebb kétjegyű természetes számokat növekvő sorrendben. Újra bejárjuk a tömböt, ez alkalommal a 98- as indexű elemtől indulunk, és visszafele haladunk ugyancsak kettesével lépve. Hasonló módon járunk el, vizsgáljuk az elemek értékét, és kiíratjuk azon indexeket, ahol a tömb elemének értéke nullától eltér. Ezáltal kiíratjuk a szöveges állományba a páros, legfeljebb kétjegyű természetes számokat csökkenő sorrendben. A módszer hatékonysága abban rejlik, hogy a szöveges állományból való kiolvasáskor megszámoljuk, mindegyik érték hányszor szerepel, utólagos rendezésre nincs szükség. Majd végigfutva a 100 elemű tömböt, kettőket lépve először elölről, majd a tömb végéről indulva kiíratjuk a megadott feltételnek megfelelő értékeket. 4. A BAC.TXT állomány tartalmaz 10 000 darab természetes számot (melyek közül legkevesebb kettő páratlan), mindegyik legtöbb 9 jegyű szám. A számok egy- egy szóközzel vannak elválasztva egymástól. a) Írjon a memória helyfoglalás és a végrehajtási idő szempontjából hatékony Pascal/C++ programot, mely meghatározza és megjeleníti a képernyőn az utolsó előtti páratlan értéket és annak pozícióját! Példa: ha az állomány a mellékelt értékeket tartalmazza, akkora 49 9998 értékek lesznek kiírva (a 49 az utolsó előtti páratlanérték és ő a 9998- ik a sorozatban). b) Írja le a választott módszert, és magyarázza meg, minek tulajdonítható a hatékonysága! unsigned int x,y,z; unsigned short pozx, pozy; ifstream in("bac.txt"); for (unsigned short i=0;i<10000;i++) in>>z; if (z%2!=0) x=y;pozx=pozy; y=z;pozy=i; in.close(); cout<<x<<""<<pozx; var x,y,z:longint; i, pozx, pozy:word; assign(f,'bac.txt'); for i:=1 to 10000 do read(f,z); if z mod 2=1 then x:=y;pozx:=pozy; y:=z;pozy=i; write(x,'', pozx);
b. Kiolvassuk a szöveges állományból a 10 000 darab természetes számot, két változóban megőrizzük az utolsó két páratlan számot, illetve másik két változóban ezek pozícióit. Miután minden számot kiolvasunk az állományból, kiíratjuk az utolsó előtti páratlan szám értékét és helyét a sorozatban. A módszer futási idő szempontjából hatékony, mivel a sorozat elemeit csak egyszer futjuk végig, amikor az állományból kiolvassuk az értékeket. Memória szempontjából hatékony, mivel nem használunk tömb adatszerkezetet, hanem csak három egész típusú változót, az egyik változóba az állományban soron következő elemet olvassuk ki, illetve a másik két változóba az utolsó két páratlan szám értékét tároljuk. Az utolsó két páratlan szám pozíciójának értékét két másik egész típusú változóban őrizzük meg. 5. A date.in szövegállomány első sora legtöbb 1000 szóközzel elválasztott természetes számot tárol, mindegyikük maximum 9 számjegyből áll. a) Írjon egy Pascal/C++ programot, amely beolvassa a számokat a date.txt állományból, meghatározza és kiírja a képernyőre a leghosszabb csökkenő sorrendben lévő részsorozat hosszát, amelyet az állományból beolvasott egymás utáni értékek alkotnak! Válasszon egy hatékony megoldási módszert a futási idő függvényében! Például: Ha a date.in állomány tartalma: 5 2 19 4 3 6 3 2 1 0 8 A program által kiírt érték: 5 #include <iostream> #include <fstream> ifstream in("date.txt"); unsigned int x,y; unsigned short max=0,nr=1; while (!in.eof()) in>>y; if (y<=x) nr++; else if (nr>max) max=nr; nr=1; x=y; in.close(); cout<<max; var x,y:longint; max,nr:word; assign(f,'date.txt'); max:=0; nr:=1; while not eof(f) do read(f,y); if y<=x then inc(nr) else if nr>max then max:=nr; nr:=1; x:=y; write(max);