C programozás oktatás kezdőknek
Kérdésed van? +36 70 410 1763 info@c-programozas.hu

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!