6. gyakorlat Egydimenziós numerikus tömbök kezelése, tömbi algoritmusok 1. feladat: Az EURO árfolyamát egy negyedéven keresztül hetente nyilvántartjuk (HUF / EUR). Írjon C programokat az alábbi kérdések megválaszolására. 1a) Hányszor volt a negyedévben 300 Ft alatt az árfolyam értéke? Alkalmazzon ellenőrzött adatbeolvasást. 1b) Monoton nőtt-e az árfolyam a negyedév során? A válasz kiírását feltételes operátorral valósítsa meg. A feladat megoldása során alkalmazzon először tömb inicializálást, majd ellenőrzött adatbeolvasást. 1c) Melyik héten volt a legmagasabb, és melyiken a legalacsonyabb az árfolyam? Melyek voltak ezek a szélsőértékek? 1d) Mennyi az adott negyedévre vonatkozó átlagos árfolyam érték? Előjelhelyesen írja ki, hogy az egyes adatok mennyivel térnek el az átlagtól. Ezt a feladatot pointer használatával is oldja meg. 1a) Hányszor volt a negyedévben 300 Ft alatt az árfolyam értéke? A tömböt inicializálja. int i, db=0; /* Tömb létrehozása inicializációs listával */ double tomb[ ] = {289.5, 292.6, 290.2, 295.5, 300.4, 300.3, 302.5, 303.3, 303.5, 299.9; double limit=300.0; for (i=0; i<sizeof(tomb); i+=1) { printf("%d. érték: ", i+1, tomb[i]); /* Feltételt kielégítő elemek megszámlálása */ if (tomb[i] < limit) db++; printf("az árfolyam értéke %d-szer volt %.2f alatt.", db, limit); 1b) Monoton nőtt-e az árfolyam a negyedév során? A válasz kiírását feltételes operátorral valósítsa meg. Ellenőrzött adatbeolvasással. int i, monoton=1; double tomb[n]; //Feltesszük, h. monoton növő a sorozat /* Tömbelemek ellenőrzött beolvasása */ do { printf("%d. érték: ", i+1); if (scanf("%lf", &tomb[i])!=1) printf("hibás adat. Adja meg újra:\n"); while ((c = getchar())!= '\n');
/* Monotonitás vizsgálat */ if (i!=0 && tomb[i] < tomb[i-1]) monoton=0; printf("a sorozat monoton növő: %s", monoton?"igaz":"hamis"); 1c) Melyik héten volt a legmagasabb, és melyiken a legalacsonyabb az árfolyam? Melyek voltak ezek a szélsőértékek? int i, minindex=0, maxindex=0; double tomb[n], min, max; /* Tömbelemek ellenőrzött beolvasása */ do { printf("%d. érték: ", i+1); if (scanf("%lf", &tomb[i])!=1) printf("hibás adat. Adja meg újra:\n"); while ((c = getchar())!= '\n'); /* Minimum kiválasztás */ min=tomb[0]; for(i=0; i<n; i++) if(tomb[i]<min) { min=tomb[i]; minindex=i; printf("\na sorozat legkisebb eleme: %lf, sorszáma: %d", tomb[minindex], minindex+1); /* Maximum kiválasztás */ max=tomb[0]; for(i=0; i<n; i++) if(tomb[i]>max) { max=tomb[i]; maxindex=i; printf("\na sorozat legnagyobb eleme: %lf, sorszáma: %d", tomb[maxindex], maxindex+1); Megjegyzés: a sorozatból a legnagyobb és legkisebb elem kiválasztása megvalósítható egy cikluson belül. 1d) Mennyi az adott negyedévre vonatkozó átlagos árfolyam érték? Előjelhelyesen írja ki, hogy az egyes adatok mennyivel térnek el az átlagtól. Ezt a feladatot pointer használatával is oldja meg. A tömböt véletlenszámokkal töltse fel.
#include <stdlib.h> //srand(), rand() #include <time.h> //time() int i; double tomb[n], *p, atlag=0.0; /* Tömb feltöltése véletlenszámokkal */ srand(time(0)); tomb[i]=rand()%31+280; /* alsóhatár: 280 ; felsőhatár: 311 */ /* Tömbelemek összegzése */ atlag += tomb[i]; /* Átlag kiszámítása */ atlag /= N; printf("\naz atlag: %.2f\n", atlag); /* Tömbelemek átlagtól való eltérésének kiírása */ for (i=0; i<n; i++) printf("%d. \t %.2f \t %.2f\n", i+1, tomb[i], tomb[i]-atlag); Tömbelemek átlagtól való eltérésének kiírása mutató használatával 1. verzió: // A p pointer mindvégig a tömb első elemére mutat; i a ciklusváltozó. for (p=tomb, i=0; i<n; i++) printf("%d. \t %.2f \t %.2f\n", i+1, *(p+i), p[i]-atlag); 2. verzió: // A p pointer mindig a tömb feldolgozás alatt álló elemére mutat; // az i sorszám csak a kiíratáshoz kell. for (p=tomb, i=0; p<=&tomb[n-1]; i++, p++) printf("%d. \t %.2f \t %.2f\n", i+1, *p, (*p)-atlag); 2. feladat: -1000 és 1000 közé eső véletlenszámokkal töltsön fel egy 20 elemű integer tömböt, majd végezze el az alábbi feladatokat: 2a) Válogassa szét a tömb elemeit pozitív és negatív számokra. // Tömbelemek szétválogatása p_i = n_i = 0; if (tomb[i]>=0) { poz_tomb[p_i] = tomb[i]; p_i++; else { neg_tomb[n_i] = tomb[i]; n_i++; // A pozitív, ill. negatív tömb indexe
2b) Rendezze mindkét részhalmazt. Az egyiket a standard qsort() függvény használatával, a másikra implementálja a minimum/maximum kiválasztásos rendező eljárást. // Pozitív tömb rendezése, qsort() qsort(poz_tomb, p_i, sizeof(int), cmpfunc); A cmpfunc() összehasonlító függvény, ami a rendezés irányát határozza meg. A main függvény előtt kell elhelyezni. Az a és b felcserélésével a rendezés iránya megfordul. int cmpfunc (const void * a, const void * b) { return ( *(int*)a - *(int*)b ); // Negatív tömb rendezése, minimum kiválasztással int min = 0, minindex = 0; for (i=0; i<n_i-1; i++) { //n_i a negatív tömb elemszáma minindex = i; min = neg_tomb[i]; for (j=i+1; j<n_i; j++) { if (neg_tomb[j] < min) { min = neg_tomb[j]; minindex = j; //Helycsere, ha szükséges if (neg_tomb[i]!=min) { neg_tomb[minindex] = neg_tomb[i]; neg_tomb[i] = min; 2c) Eleme-e a rendezett pozitív tömbnek az 500? Használja a C standard bsearch() függvényét. // Keresés, bsearch() int searchkey; // keresett elem int *item; // megtalált elemre mutató pointer printf("\n\nadd meg a keresett pozitív számot: "); scanf("%d", &searchkey); // bináris kereséshez ugyanaz az összehasonlító függvény, mint a rendezéshez // p_i a pozitív tömb mérete item = (int*)bsearch (&searchkey, poz_tomb, p_i, sizeof (int), cmpfunc); if( item!= NULL ) { printf("megtaláltam: %d\n", *item); else { printf("\n\n%d nincs a pozitív számok között\n", searchkey);
Házi feladat: 1. Az első feladathoz készítsen olyan kiírást, amelyben az első adatot követően a többi listaelem a megelőzőhöz képest számított relatív érték. Például: 301.1, 2.3, -0.4, 0.6, -0.2, stb. Használja fel ezt a listát a monotonitás vizsgálathoz. 2. A második feladathoz implementálja a logaritmikus keresés algoritmusát, és a megtalált elem sorszámát adja vissza. 3. Írjon C programot az ötöslottó számainak véletlenszerű előállítására. Ügyeljen, hogy ne ismétlődjenek a számok! 4. Az egyetemi hallgatóknak félévente 6 vizsgájuk van. Félév végén az elért tanulmányi átlag alapján ki szeretnénk számolni a hallgató ösztöndíját a következő félévre: 3,5 alatt 0 Ft/hó, 3,6-4,0 között 5eFt/hó, 4,1-4,5 között 10eFt/hó és 4,6-5,0 között 15eFt/hó. Írjon C programot, amely beolvassa egy hallgató vizsgajegyeit és eltárolja, kiszámítja a tanulmányi átlagot és kiírja az ösztöndíj havi összegét. 5. Implementálja a 6. előadás metszet, unió és különbség példa algoritmusait.