Expedíció
Érettségi feladat - 2015. május 12.
Valamikor a távközlés hőskorában egy ritka farkasfaj tudományos megfigyelésére expedíciót szerveztek a sarkkörön túlra. A magukkal vitt rádió csak napi egy adásra volt alkalmas, arra is csak 90 időegységig, időegységenként egy karaktert továbbítva. Az expedíció rádiósának üzeneteit több rádióamatőr is igyekezett lejegyezni. A feladatban a rádióamatőrök által lejegyzett üzeneteket kell feldolgoznia.
A veetel.txt fájl tartalmazza a rádióamatőrök által feljegyzett üzeneteket. Minden sorpár egy-egy feljegyzést tartalmaz.
- A sorpár első sorában két szám áll, az első a nap sorszáma, a második pedig – az előzőtől egy szóközzel elválasztva – a rádióamatőré.
- A sorpár második sorában a feljegyzéshez tartozó pontosan 90 karakter áll. A vett karakter az angol ábécé kisbetűje, számjegy, / jel vagy szóköz lehet. Ha az adott időegységben nem volt egyértelműen azonosítható a vett jel, akkor # karakter szerepel. Ha a tényleges üzenet befejeződött, az adó a fennmaradó időegységekben $ jelet küld.
- A napok sorszáma 1 és 11, a rádióamatőrök sorszáma 1 és 20 közötti egész szám lehet.
- Ha a megfigyelés során láttak farkasokat, akkor az üzenet két, / jellel elválasztott egész számmal, a látott kifejlett és kölyök egyedek számával kezdődik, amelyet szóköz követ. Más esetben nem szám az első karakter.
Például:
2 15
1/0 #gy#domb##l fig###tu# f#i#s ho#a##dalyoz$$...
A fenti sorpár első sora mutatja, hogy az üzenet a 2. napon érkezett és a 15-ös rádióamatőr rögzítette. 1 felnőtt és 0 kölyök farkast figyeltek meg. Mivel a második sorban a 45. karakter $ jel, és előtte nem # jel szerepel, ezért az üzenet biztosan 44 karakter hosszú.
Készítsünk programot, amely a veetel.txt állomány adatait felhasználva az alábbi kérdésekre válaszol! A program forráskódját mentsük radio néven! (A program megírásakor a felhasználó által megadott adatok helyességét, érvényességét nem kell ellenőriznie, feltételezheti, hogy a rendelkezésre álló adatok a leírtaknak megfelelnek.)
A képernyőre írást igénylő részfeladatok eredményének megjelenítése előtt írjuk a képernyőre a feladat sorszámát (például: 3. feladat:)! Ha a felhasználótól kérünk be adatot, jelenítsük meg a képernyőn, hogy milyen értéket vár! Az ékezetmentes kiírás is elfogadott.
Olvassuk be és tároljuk a veetel.txt fájl tartalmát! (4 pont)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | int main(void){ /* ... */ printf("1. feladat:\n"); if((fp=fopen("veetel.txt","r"))==NULL){ printf("A veetel.txt nem talalhato, ezert a program kilep!\n"); return 1; } while(fgets(sor,N-1,fp)){ token=strtok(sor,elv); adatok[index].nap=atoi(token); token=strtok(NULL,elv); adatok[index].amator=atoi(token); fgets(sor,N-1,fp); token=strtok(sor,"\n"); strcpy(adatok[index].uzenet,token); index++; } fclose(fp); printf("A fajl beolvasasa sikeresen megtortent!\n"); } |
Olvassuk be a veetel.txt fájl adatait, és tároljuk le őket egy struktúrában.
Írjuk a képernyőre, hogy melyik rádióamatőr rögzítette az állományban szereplő első és melyik az utolsó üzenetet! (2 pont)
1 2 3 4 | int main(void){ /* ... */ printf("\n2. feladat: \nAz elso uzenet rogzitoje: %d\nAz utolso uzenet rogzitoje: %d\n",adatok[0].amator,adatok[index-1].amator); } |
Írassuk ki a képernyőre a struktúra első és utolsó elemében tárolt üzeneteket.
Adjuk meg az összes olyan feljegyzés napját és a rádióamatőr sorszámát, amelynek szövegében a "farkas" karaktersorozat szerepel! (5 pont)
1 2 3 4 5 6 7 8 9 | int main(void){ /* ... */ printf("\n3. feladat: \n"); for(i=0;i<index;i++){ if(strstr(adatok[i].uzenet,"farkas")!=NULL){ printf("%2d nap, %d radioamator\n",adatok[i].nap,adatok[i].amator); } } } |
Indítsunk ciklust, és keressük meg a "farkas" karakterlánc előfordulásait.
Készítsünk statisztikát, amely megadja, hogy melyik napon hány rádióamatőr készített feljegyzést. Azok a napok 0 értékkel szerepeljenek, amikor nem született feljegyzés! Az eredmény a képernyőn jelenjen meg a napok sorszáma szerint növekvően! A megjelenítést a feladat végén látható minta szerint alakítsuk ki! (7 pont)
1 2 3 4 5 6 7 8 9 10 | int main(void){ /* ... */ printf("\n4. feladat: \n"); for(i=0;i<index;i++){ stat[adatok[i].nap]++; } for(i=1;i<S;i++){ printf("%2d. nap: %d radioamator\n",i,stat[i]); } } |
Deklaráljunk egy 12 elemű tömböt, amely szimbolizálja a napokat. Ciklus segítségével haladjunk végig az adatokon, és növeljük meg a statisztika tömbünk azon elemeit eggyel, amikor feljegyzték az üzeneteket. A folyamat végén megkapjuk, hogy melyik nap hány rádióamatőr dolgozott.
A rögzített üzenetek alapján kíséreljük meg helyreállítani az expedíció által küldött üzenetet! Készítsük el az adaas.txt fájlt, amely napok szerinti sorrendben tartalmazza a küldött üzeneteket! Ha egy időpontban senkinél nem volt vétel, akkor azon a ponton a # jel szerepeljen! (Feltételezhetjük, hogy az azonos üzenethez tartozó feljegyzések között nincs ellentmondás.) (7 pont)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | int main(void){ /* ... */ printf("\n5. feladat: \n"); for(i=0;i<index;i++){ strcpy(adasok[adatok[i].nap].uzenet,adatok[i].uzenet); } for(i=0;i<S;i++){ for(j=0;adasok[i].uzenet[j];j++){ if(adasok[i].uzenet[j]=='#'){ for(k=0;k<index;k++){ if(adatok[k].nap==i && adatok[k].uzenet[j]!='#'){ adasok[i].uzenet[j]=adatok[k].uzenet[j]; } } } } } if((fp=fopen("adaas.txt","w"))==NULL){ printf("Az adaas.txt letrehozasa sikertelen, ezert a program kilep!\n"); return 1; } for(i=1;i<S;i++){ fprintf(fp,"%s\n",adasok[i].uzenet); } fclose(fp); printf("Az adaas.txt letrehozasa sikeresen megtortent!\n"); } |
A helyreállításához másoljuk át az üzeneteket egy másik struktúrába, mivel itt fogjuk visszafejteni őket. A másolást úgy végezzük el, hogy egy naphoz csak egy üzenet legyen rendelve. Ez lesz a kiinduló állapota a helyreállításnak (hogy melyik üzenet lesz ez, az szinte lényegtelen).
Az elv a következő: keressük meg a kiinduló üzenet ismeretlen karaktereit a többi üzenetben, és ha valahol megtaláljuk, akkor az alapján állítsuk helyre.
Ezt követően készítsük el a kimeneti fájlt, és írjuk bele soronként a helyreállított üzeneteket.
Készítsünk függvényt szame néven az alábbi algoritmus alapján! A függvény egy karaktersorozathoz hozzárendeli az igaz vagy a hamis értéket. A függvény elkészítésekor az algoritmusban megadott változóneveket használjuk! Az elkészített függvényt a következő feladat megoldásánál felhasználhatjuk. (7 pont)
Olvassuk be egy nap és egy rádióamatőr sorszámát, majd írjuk a képernyőre a megfigyelt egyedek számát (a kifejlett és kölyök egyedek számának összegét)! Ha nem volt ilyen feljegyzés, a "Nincs ilyen feljegyzés" szöveget jelenítsük meg! Ha nem volt megfigyelt egyed vagy számuk nem állapítható meg, a "Nincs információ" szöveget jelenítsük meg! Amennyiben egy számot közvetlenül # jel követ, akkor a számot tekintsük nem megállapíthatónak! (9 pont)
A főprogram
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | #include <stdio.h> #include <string.h> #include <stdlib.h> #define N 93 #define M 200 #define S 12 struct vetel{ int nap,amator; char uzenet[N]; }; struct adas{ char uzenet[N]; }; int main(void){ FILE *fp; struct vetel adatok[M]; struct adas adasok[S-1]; char sor[N],*token,elv[]={" \n"}; int index=0,i,j,k,stat[S]={0}; printf("1. feladat:\n"); if((fp=fopen("veetel.txt","r"))==NULL){ printf("A veetel.txt nem talalhato, ezert a program kilep!\n"); return 1; } while(fgets(sor,N-1,fp)){ token=strtok(sor,elv); adatok[index].nap=atoi(token); token=strtok(NULL,elv); adatok[index].amator=atoi(token); fgets(sor,N-1,fp); token=strtok(sor,"\n"); strcpy(adatok[index].uzenet,token); index++; } fclose(fp); printf("A fajl beolvasasa sikeresen megtortent!\n"); printf("\n2. feladat: \nAz elso uzenet rogzitoje: %d\nAz utolso uzenet rogzitoje: %d\n",adatok[0].amator,adatok[index-1].amator); printf("\n3. feladat: \n"); for(i=0;i<index;i++){ if(strstr(adatok[i].uzenet,"farkas")!=NULL){ printf("%2d nap, %d radioamator\n",adatok[i].nap,adatok[i].amator); } } printf("\n4. feladat: \n"); for(i=0;i<index;i++){ stat[adatok[i].nap]++; } for(i=1;i<S;i++){ printf("%2d. nap: %d radioamator\n",i,stat[i]); } printf("\n5. feladat: \n"); for(i=0;i<index;i++){ strcpy(adasok[adatok[i].nap].uzenet,adatok[i].uzenet); } for(i=0;i<S;i++){ for(j=0;adasok[i].uzenet[j];j++){ if(adasok[i].uzenet[j]=='#'){ for(k=0;k<index;k++){ if(adatok[k].nap==i && adatok[k].uzenet[j]!='#'){ adasok[i].uzenet[j]=adatok[k].uzenet[j]; } } } } } if((fp=fopen("adaas.txt","w"))==NULL){ printf("Az adaas.txt letrehozasa sikertelen, ezert a program kilep!\n"); return 1; } for(i=1;i<S;i++){ fprintf(fp,"%s\n",adasok[i].uzenet); } fclose(fp); printf("Az adaas.txt letrehozasa sikeresen megtortent!\n"); return 0; } |
A program egy lehetséges kimenete
1. feladat: A fajl beolvasasa sikeresen megtortent! 2. feladat: Az elso uzenet rogzitoje: 13 Az utolso uzenet rogziotje: 18 3. feladat: 10 nap, 16 radioamator 5 nap, 15 radioamator 4. feladat: 1. nap: 13 radioamator 2. nap: 14 radioamator 3. nap: 15 radioamator 4. nap: 15 radioamator 5. nap: 14 radioamator 6. nap: 15 radioamator 7. nap: 12 radioamator 8. nap: 14 radioamator 9. nap: 13 radioamator 10. nap: 14 radioamator 11. nap: 14 radioamator 5. feladat: Az adaas.txt letrehozasa sikeresen megtortent!
A képernyőre írt megfelelő formátumú üzenetekért további 4 pont kapható.
Az itt található érettségi feladat megoldása nem az Oktatási Minisztérium által kiadott hivatalos megoldás. A feladatokat azért dolgoztam ki C nyelven is, hogy segítsem a diákjaim sikeres emelt szintű érettségi felkészülését. A megoldások irányadó jellegűek, a feladatok többféleképpen is megoldhatóak.
Ha a lakattal jelölt feladatok megoldásaira is kíváncsi vagy, keress bizalommal!