ZER DAKIDAN: Zenbaki errealen array datu-motako aldagai batekin lan eginez, oinarrizko algoritmo batzuk programatzen ikasi dut. ZER IKASIKO DUDAN: Zenbaki errealen array datu-motako aldagai batekin lanean jarraituz, beste algoritmo batzuk programatzen ikasiko dut. |
Ezagutzen dugun zarekin jarraituz. Gogora ekar dezagun zenbaki errealen afBektorea izeneko array-aldagiak gehienez LUZMAX=20 elementu izan ditzakeela, eta bektore horrek 0.0 eta 99.9 zenbaki errealak gordetzen dituela. Adibidez, une jakin batean 5 elementu dituen afBektorea array horren edukia hau izan daiteke, non iLuzera aldagaiak bektorearen luzera efektiboa gordetzen duen:
afBektorea
62.7
|
17.68
| 32.21
|
98.41
|
9.82
| ||
0
|
1
|
2
|
3
|
4
|
...
|
19
|
5
|
Gogoratu ere iLuzera aldagaiak bektorearen luzera efektiboa gordetzen duela, hots, zenbat elementu dituen une horretan, bere mugak 0 eta LUZMAX=20 dira. Beraz, bektorea beterik izatean iLuzera aldagaian LUZMAX=20 balioa gordeko da, eta, aldiz, bektorea hutsik izatean iLuzera aldagaian 0 marka gordeko da.
Array baten balioak hasieraketa batean finkatu ondoren, arrayaren elementu baten bilaketa burutuko da. Bilaketa bat gauzatzeko egiturarik eraginkorrena while da, bilaketa egiteko do-while agindu errepikakorraa erabil daiteke ere, baina ez da komeni for agindua erabiltzea. Hurrengo programan ikusi nola definitu diren TRUE eta FALSE konstante boolearrak (funtsean 1 eta 0 balioak dira). Ikusi ere bilaketak huts egiten duenean iBilatu() funtzioak -1 marka itzultzen diola modulu deitzaileari, hots, gezurrezko posizio bat itzultzen dio adieraziz bilatutako balioa ez dagoela arrayan:
/* Ariketa-47a1_BilaketaWHILE: elementu bat bilatu arrayan */ // Array baten hasieraketa. Datuak dituen array batean elementu baten // posizioa bilatu elementuaren balioaren arabera. #include <stdio.h> #define BEHEMUGA 0.0 #define GOIMUGA 99.9 #define LUZMAX 20 // 20 elementu gehienez: 0. posiziotik 19. posizionarino #define FALSE 0 // iAurkitua aldagairako #define TRUE 1 // iAurkitua aldagairako void BektoreaIkusi(const float[], int); int iBilatu(const float[], int, float); int main() { static float afBektorea[LUZMAX] = { 67.34, 2.17, 89.37, 15.08, 16.16, 72.44, 5.09, 16.16, 90.09 }; int iLuzera = 9; float fDatua; int iPosizioa; printf("\n"); printf("\n\t Arrayaren eta bere luzera efektiboaren hasieraketak"); printf("\n\t ---------------------------------------------------\n"); printf("\n\t Arrayaren elementuak hasieraketa ondoren: (iLuzera=%d) \n", iLuzera); printf("\n\t 4. eta 7. posizioko balioak errepikaturaik dauden: \n"); BektoreaIkusi(afBektorea, iLuzera); printf("\n"); do { printf(" Bilatu nahi den elementuaren balioa (0.0 eta 99.9 artekoa): "); scanf("%f", &fDatua); } while (fDatua < 0.0 || fDatua >= 100); iPosizioa = iBilatu(afBektorea, iLuzera, fDatua); if (iPosizioa == -1) printf("\n %.2f balioko elementurik ez dago arrayan! \n", fDatua); else { printf("\n Arrayaren elementuetan, %.2f balioko lehen", fDatua); printf("\n agerpena arrayan %d. posizioan ematen da.\n", iPosizioa); } printf("\n"); return 0; } void BektoreaIkusi(const float afBektorea[], int iLuzera) // bi parametroak sarrerakoak { int iKont; // afBektorea[3] = 3.33; babestuta dago printf("\n"); printf("\t Posizioa Balioa\n"); printf("\t -------- ------\n"); for (iKont=0; iKont < iLuzera; iKont++) { printf("\t %9d %13.2f\n", iKont, afBektorea[iKont]); } } int iBilatu(const float afBektorea[], int iZenbatElementu, float fDatua) { int iAurkitua; int iKont; iAurkitua = FALSE; iKont = 0; while ((iAurkitua == FALSE) && (iKont <= iZenbatElementu)) // edo honela ere bai... { // (!iAurkitua && (iKont <= iZenbatElementu)) if (afBektorea[iKont] == fDatua) iAurkitua = TRUE; else iKont++; } if (iAurkitua == TRUE) return iKont; else return -1; }
Array baten balioak hasieraketa batean finkatu ondoren, arrayaren elementu baten bilaketa burutuko da. Bilaketa bat gauzatzeko egiturarik eraginkorrena while da, bilaketa egiteko do-while agindu errepikakorraa erabil daiteke ere, baina ez da komeni for agindua erabiltzea. Hurrengo programan ikusi nola definitu diren TRUE eta FALSE konstante boolearrak (funtsean 1 eta 0 balioak dira). Ikusi ere bilaketak huts egiten duenean iBilatu() funtzioak -1 marka itzultzen diola modulu deitzaileari, hots, gezurrezko posizio bat itzultzen dio adieraziz bilatutako balioa ez dagoela arrayan:
/* Ariketa-47a2_BilaketaDO-WHILE: elementu bat bilatu arrayan */ // Array baten hasieraketa. Datuak dituen array batean elementu baten // posizioa bilatu elementuaren balioaren arabera. #include <stdio.h> #define BEHEMUGA 0.0 #define GOIMUGA 99.9 #define LUZMAX 20 // 20 elementu gehienez: 0. posiziotik 19. posizionarino #define FALSE 0 // iAurkitua aldagairako #define TRUE 1 // iAurkitua aldagairako void BektoreaIkusi(const float[], int); int iBilatu(const float[], int, float); int main() { static float afBektorea[LUZMAX] = { 67.34, 2.17, 89.37, 15.08, 16.16, 72.44, 5.09, 16.16, 90.09 }; int iLuzera = 9; float fDatua; int iPosizioa; printf("\n"); printf("\n\t Arrayaren eta bere luzera efektiboaren hasieraketak"); printf("\n\t ---------------------------------------------------\n"); printf("\n\t Arrayaren iLuzera=%d elementuak hasieraketa ondoren, non", iLuzera); printf("\n\t 4. eta 7. posizioko balioak errepikaturaik dauden: \n"); BektoreaIkusi(afBektorea, iLuzera); printf("\n"); do { printf(" Bilatu nahi den elementuaren balioa (0.0 eta 99.9 artekoa): "); scanf("%f", &fDatua); } while (fDatua < 0.0 || fDatua >= 100); iPosizioa = iBilatu(afBektorea, iLuzera, fDatua); if (iPosizioa == -1) printf("\n %.2f balioko elementurik ez dago arrayan! \n", fDatua); else { printf("\n Arrayaren elementuetan, %.2f balioko lehen", fDatua); printf("\n agerpena arrayan %d. posizioan ematen da.\n", iPosizioa); } printf("\n"); return 0; } void BektoreaIkusi(const float afBektorea[], int iLuzera) // bi parametroak sarrerakoak { int iKont; // afBektorea[3] = 3.33; babestuta dago printf("\n"); printf("\t Posizioa Balioa\n"); printf("\t -------- ------\n"); for (iKont=0; iKont < iLuzera; iKont++) { printf("\t %9d %13.2f\n", iKont, afBektorea[iKont]); } } int iBilatu(const float afBektorea[], int iZenbatElementu, float fDatua) { int iAurkitua; int iKont; iAurkitua = FALSE; iKont = 0; do { if (afBektorea[iKont] == fDatua) iAurkitua = TRUE; else iKont++; } while ((iAurkitua == FALSE) && (iKont <= iZenbatElementu)); // edo honela ere bai... // (!iAurkitua && (iKont <= iZenbatElementu)) if (iAurkitua == TRUE) return iKont; else return -1; }
Bilaketa do-while aginduz programatzean, goiko iBilatu() funtzioa laburrago idatz daiteke hau eginez: iKont inkrementatu baldin eta balioa aurkitu ez bada eta oraindik arraya bukatu ez bada. Honelaxe:
/* Bilatu DO-WHILE bitartez: fDatua balioa afZenbakiak|iZenbatElementu arrayan */ int iBilatu(const float afZenbakiak[], int iZenbatElementu, float fDatua) { int iKont = -1; // -1 gezurrezko posizioa litzateke, posizio txikiena 0 baita do { iKont++; } while ((afZenbakiak[iKont] != fDatua) && (iKont < iZenbatElementu)); if (afZenbakiak[iKont] == fDatua) return iKont; // aurkitzen bada dagokion indizea itzuli else return -1; // ez bada aurkitzen -1 gezurrezko posizioa itzuli }
Arrayaren posizio bat den funtzioaren emaitza itzultzeko if-else baldintzazko agindua erabiltzen da ondoko bi egoera hauek desberdintzeko:
- Bilatu nahi den fDatua aldagaiak gordetzen duen balioa arrayan aurkitzean, bere posizioari dagokion iKont indizea itzuli modulu deitzaileari
- Bilatu nahi den fDatua aldagaiaren balioa arrayan ez bada aurkitzean, -1 gezurrezko posizioa itzuli modulu deitzaileari
Array baten balioak hasieraketa batean finkatu ondoren, arrayaren elementu baten bilaketa burutuko da.
Bilaketa bat gauzatzeko, beste lengoaia batzuetan, ez da komeni for agindua erabiltzea bere iterazio guztiak burutzen direlako, baina C lengoaian for aginduaren exekuzioa eten daiteke (return bitartez edo baita ere break bitartez).
Hurrengo programan ikusten da bilaketaren algoritmoa oso erraz programa daitekeela for agindu errepikakorra erabiliz. Lehen bezala, iBilatu() funtzioak -1 marka itzultzen diola modulu deitzaileari, hots, gezurrezko posizio bat itzultzen dio adieraziz bilatutako balioa ez dagoela arrayan, edo, bestela, aurkitutako elementuaren posizioa itzuliko du:
/* Ariketa-47a3_BilaketaFOR: elementu bat bilatu arrayan */ // Array baten hasieraketa. Datuak dituen array batean elementu baten // posizioa bilatu elementuaren balioaren arabera. #include <stdio.h> #define BEHEMUGA 0.0 #define GOIMUGA 99.9 #define LUZMAX 20 // 20 elementu gehienez: 0. posiziotik 19. posizionarino void BektoreaIkusi(const float[], int); int iBilatu(const float[], int, float); int main() { static float afBektorea[LUZMAX] = { 67.34, 2.17, 89.37, 15.08, 16.16, 72.44, 5.09, 16.16, 90.09 }; int iLuzera = 9; float fDatua; int iPosizioa; printf("\n"); printf("\n\t Arrayaren eta bere luzera efektiboaren hasieraketak"); printf("\n\t ---------------------------------------------------\n"); printf("\n\t Arrayaren iLuzera=%d elementuak hasieraketa ondoren, non", iLuzera); printf("\n\t 4. eta 7. posizioko balioak errepikaturaik dauden: \n"); BektoreaIkusi(afBektorea, iLuzera); printf("\n"); do { printf(" Bilatu nahi den elementuaren balioa (0.0 eta 99.9 artekoa): "); scanf("%f", &fDatua); } while (fDatua < 0.0 || fDatua >= 100); iPosizioa = iBilatu(afBektorea, iLuzera, fDatua); if (iPosizioa == -1) printf("\n %.2f balioko elementurik ez dago arrayan! \n", fDatua); else { printf("\n Arrayaren elementuetan, %.2f balioko lehen", fDatua); printf("\n agerpena arrayan %d. posizioan ematen da.\n", iPosizioa); } printf("\n"); return 0; } void BektoreaIkusi(const float afBektorea[], int iLuzera) // bi parametroak sarrerakoak { int iKont; // afBektorea[3] = 3.33; babestuta dago printf("\n"); printf("\t Posizioa Balioa\n"); printf("\t -------- ------\n"); for (iKont=0; iKont < iLuzera; iKont++) { printf("\t %9d %13.2f\n", iKont, afBektorea[iKont]); } } int iBilatu(const float afBektorea[], int iZenbatElementu, float fDatua) { int iKont; for (iKont = 0; iKont < iZenbatElementu; iKont++) { // printf("\n %2d. elementua prozesatzen... afBektorea[%2d]=%.2f", iKont, iKont, afBektorea[iKont]); if (afBektorea[iKont] == fDatua) return iKont; } return -1; }
Bilaketa for aginduz programatzean, goiko iBilatu() funtzioa oso laburra geratzen da: bilatutakoa aurkitzean for agindua eten egiten da eta uneko posizioa itzultzen da return bitartez. Iterazio guztiak burutzen badira, for agindua bukatuko da eta -1 marka itzuliko litzateke programa nagusiari edo, orokorrago hitz eginez, modulu deitzaileari.
Zenbaki errealen array baten hasieraketa egin ondoren, datuen array horretatik bi array berri eskuratu: zenbaki osoen array bat eta zenbaki errealen bigarren array bat; hasierako arrayaren elementu bakoitzeko, balioaren zati osoa osoen array batera eta zati hamartarra errealen beste array batera.
/* Ariketa-47b_BanaketaArrayetan: array bat bitan banatu */ // Array baten hasieraketa egin ondoren: Datuak dituen array bat bitan banatu. Hasierako // balioen zati osoa osoen array batera eta zati hamartarra errealen beste array batera. #include <stdio.h> #define BEHEMUGA 0.0 #define GOIMUGA 99.9 #define LUZMAX 20 // 20 elementu gehienez: 0. posiziotik 19. posizionarino void BektoreaIkusi(const float[], int); void BektoreaErakutsi(const int[], int); void Banatu1(const float[], int, int[], float[]); void Banatu2(const float[], int, float[], int *, float[], int *); int main() { static float afBektorea[LUZMAX] = { 67.34, 2.17, 89.37, 15.08, 16.16, 72.44, 5.02, 16.16, 90.09 }; int iLuzera = 9; // aldagai honek 3 arrayentzat balio du int aiBektore_1[LUZMAX]; float afBektore_2[LUZMAX]; int iZenbatAprobatu; int iZenbatSuspenditu; float afAprobatuak[LUZMAX]; float afSuspendituak[LUZMAX]; printf("\n"); printf("\n\t Arrayaren eta bere luzera efektiboaren hasieraketak"); printf("\n\t ---------------------------------------------------\n"); printf("\n\t Arrayaren elementuak hasieraketa ondoren: (iLuzera=%d) \n", iLuzera); BektoreaIkusi(afBektorea, iLuzera); Banatu1(afBektorea, iLuzera, aiBektore_1, afBektore_2); printf("\n\t Emaitza den array baten edukia: \n"); BektoreaErakutsi(aiBektore_1, iLuzera); printf("\n\t Emaitza den beste arrayaren edukia: \n"); BektoreaIkusi(afBektore_2, iLuzera); printf("\n\n"); Banatu2(afBektorea, iLuzera, afAprobatuak, &iZenbatAprobatu, afSuspendituak, &iZenbatSuspenditu); printf("\n\t Aprobatuen arrayaren edukia: \n"); BektoreaIkusi(afAprobatuak, iZenbatAprobatu); printf("\n\t Suspendituen arrayaren edukia: \n"); BektoreaIkusi(afSuspendituak, iZenbatSuspenditu); printf("\n"); return 0; } void BektoreaIkusi(const float afBektorea[], int iLuzera) // bi parametroak sarrerakoak { int iKont; // afBektorea[3] = 3.33; // babestuta dago printf("\n"); printf("\t Posizioa Balioa\n"); printf("\t -------- ------\n"); for (iKont=0; iKont < iLuzera; iKont++) { printf("\t %9d %13.2f\n", iKont, afBektorea[iKont]); } } void BektoreaErakutsi(const int aiBektorea[], int iLuzera) // bi parametroak sarrerakoak { int iKont; // afBektorea[3] = 3.33; babestuta dago printf("\n"); printf("\t Posizioa Balioa\n"); printf("\t -------- ------\n"); for (iKont=0; iKont < iLuzera; iKont++) { printf("\t %9d %13d\n", iKont, aiBektorea[iKont]); } } void Banatu1(const float afBektorea[], int iZenbatElementu, int aiBektore_1[], float afBektore_2[]) { int iKont; for (iKont = 0; iKont < iZenbatElementu; iKont++) { aiBektore_1[iKont] = (int)afBektorea[iKont]; afBektore_2[iKont] = afBektorea[iKont] - aiBektore_1[iKont]; } } void Banatu2(const float afBektorea[], int iZenbatElementu, float afAprob[], int *iZenbatAprob, float afSuspe[], int *iZenbatSuspe) { int iKont; int iZenbat_A, iZenbat_S; iZenbat_A = 0; // oraindik aprobaturik ez dago iZenbat_S = 0; // oraindik suspenditurik ez dago for (iKont = 0; iKont < iZenbatElementu; iKont++) { if (afBektorea[iKont] >= 50.0) { afAprob[iZenbat_A] = afBektorea[iKont]; iZenbat_A++; } else { afSuspe[iZenbat_S] = afBektorea[iKont]; iZenbat_S++; } } *iZenbatAprob = iZenbat_A; // aprobatuen kopurua kanporatu *iZenbatSuspe = iZenbat_S; // suspendituen kopurua kanporatu }
Bi array datuz bete hasieraketak eginez, bi arrayen datuak helburuko array batean gorde baldin eta toki nahikorik badago elementu guztiak biltegitzeko.
/* Ariketa-47c_BilketaArrayetan: bi array bildu array bakarrean */ // Array pare baten baten hasieraketa egin ondoren: Datu guztiak helburuko array // batean gorde baldin eta tokirik badago. #include <stdio.h> #define BEHEMUGA 0.0 #define GOIMUGA 99.9 #define LUZMAX 20 // 20 elementu gehienez: 0. posiziotik 19. posizionarino void BektoreaIkusi(const float[], int); void BektoreaErakutsi(const int[], int); void Batu(const float[], int, const float[], int, float[], int *); int main() { static float afBektore_1[LUZMAX] = { 67.34, 2.17, 89.37, 16.16, 72.44, 5.02, 90.09 }; int iLuzera_1 = 7; static float afBektore_2[LUZMAX] = { 88.67, 23.34, 62.17, 79.37 }; int iLuzera_2 = 4; float afBektorea[LUZMAX]; int iLuzera; printf("\n"); printf("\n\t Bi arrayen edukiak array bakarrean bildu"); printf("\n\t ----------------------------------------\n"); printf("\n\t Lehen arrayaren elementuak hasieraketa ondoren: (iLuzera_1=%d) \n", iLuzera_1); BektoreaIkusi(afBektore_1, iLuzera_1); printf("\n\t Bigarren arrayaren elementuak hasieraketa ondoren: (iLuzera_2=%d) \n", iLuzera_2); BektoreaIkusi(afBektore_2, iLuzera_2); if (iLuzera_1 + iLuzera_2 > LUZMAX) printf("\n\t Helburuko arrayak ez dauka toki nahikorik informazio guztia gordetzeko. \n"); else { Batu(afBektore_1, iLuzera_1, afBektore_2, iLuzera_2, afBektorea, &iLuzera); printf("\n\t Emaitza den arrayaren edukia: (iLuzera=%d)\n", iLuzera); BektoreaIkusi(afBektorea, iLuzera); } printf("\n"); return 0; } void BektoreaIkusi(const float afBektorea[], int iLuzera) // bi parametroak sarrerakoak { int iKont; // afBektorea[3] = 3.33; babestuta dago printf("\n"); printf("\t Posizioa Balioa\n"); printf("\t -------- ------\n"); for (iKont=0; iKont < iLuzera; iKont++) { printf("\t %9d %13.2f\n", iKont, afBektorea[iKont]); } } void Batu(const float afBektore_1[], int iLuzera_1, const float afBektore_2[], int iLuzera_2, float afBektorea[], int *iLuzera) { int iKont; *iLuzera = 0; // helburuko arraya hutsik dago, bere aldagaiaren hasierake for (iKont = 0; iKont < iLuzera_1; iKont++) { afBektorea[*iLuzera] = afBektore_1[iKont]; *iLuzera = *iLuzera + 1; } // for amaitzean *Luzera aldagaiaren balioa iLuzera_1 da for (iKont = 0; iKont < iLuzera_2; iKont++) { afBektorea[*iLuzera] = afBektore_2[iKont]; *iLuzera = *iLuzera + 1; } // for amaitzean *Luzera aldagaiaren balioa iLuzera_1+iLuzera_2 da }
Algoritmo ez da ikasi behar, baina bai jakin behar da nola aplikatu gure programetan. Zenbaki errealen array baten hasieraketa egin ondoren, bere elementuak ordenatu txikitik handira.
/* Ariketa-47d_ArrayBatenSailkatzea: elementuak txikitak handira ordenatu */ // Array baten hasieraketa egin ondoren, bere elementuak ordenatu. #include <stdio.h> #include <conio.h> #define BEHEMUGA 0.0 #define GOIMUGA 99.9 #define LUZMAX 10 // 20 elementu gehienez: 0. posiziotik 19. posizionarino void BektoreaIkusi(const float[], int); void BektoreaOrdenatu(float[], int); int main() { static float afBektorea[LUZMAX] = { 67.34, 2.17, 89.37, 15.08, 16.16, 72.44, 5.09, 16.16, 90.09 }; int iLuzera = 9; printf("\n"); printf("\n\t Arrayaren eta bere luzera efektiboaren hasieraketak"); printf("\n\t ---------------------------------------------------\n"); printf("\n\t Arrayaren elementuak hasieraketa ondoren: (iLuzera=%d ) \n", iLuzera); BektoreaIkusi(afBektorea, iLuzera); BektoreaOrdenatu(afBektorea, iLuzera); printf("\n\t Arrayaren elementuak sailkatu ondoren: (iLuzera=%d ) \n", iLuzera); BektoreaIkusi(afBektorea, iLuzera); printf("\n"); return 0; } void BektoreaIkusi(const float afBektorea[], int iLuzera) // bi parametroak sarrerakoak { int iKont; // afBektorea[3] = 3.33; babestuta dago printf("\n"); printf("\t Posizioa Balioa\n"); printf("\t -------- ------\n"); for (iKont=0; iKont < iLuzera; iKont++) { printf("\t %9d %13.2f\n", iKont, afBektorea[iKont]); } } void BektoreaOrdenatu(float afBektorea[], int iLuzera) { int iMinNon; int iKanpokoKont; int iBarrukoKont; float fMinimoa; for (iKanpokoKont = 0; iKanpokoKont < iLuzera-1; iKanpokoKont++) { fMinimoa = afBektorea[iKanpokoKont]; iMinNon = iKanpokoKont; for (iBarrukoKont = iKanpokoKont+1; iBarrukoKont < iLuzera; iBarrukoKont++) { if (fMinimoa > afBektorea[iBarrukoKont]) // ordentu gabekoen artean minimoa aurkitu { fMinimoa = afBektorea[iBarrukoKont]; iMinNon = iBarrukoKont; } } afBektorea[iMinNon] = afBektorea[iKanpokoKont]; afBektorea[iKanpokoKont] = fMinimoa; printf("\n %d. iterazioan... txikiena %.2f izan da eta %d. posizioan egon da", iKanpokoKont, fMinimoa, iMinNon); BektoreaIkusi(afBektorea, iLuzera); getch(); } }
Esan bezala, lehen bertsioa ikastea ezinbestekoa da, bigarren bertsioa ulertzea besterik ez da eskatzen:
|
iruzkinik ez:
Argitaratu iruzkina