| ZER DAKIDAN: Ariketa 47 | Algoritmoak arrayetan (3) artikuluan ikusitako algoritmoen artean gogoratzen dut bilaketa lineala egiteko bi adibide ikasi nituela. ZER IKASIKO DUDAN: Bilaketa linealaren algoritmoan sakonduko dut, ondoko hau ikusiz: programa, parametroak, eskema eta aplikazioak. |
Zenbakien array bat osatu eta pantailan erakutsi. Ondoren, gakoa den zenbaki jakin bat teklatuaren bitartez aukeratu eta zenbaki hori arrayean bilatu. Gakoa den zenbakia aurkituz gero, array barruan dagokion bere indizea pantailaratu. Gakoa den zenbakia aurkitzen ez bada, gertaera hori adierazi pantailako mezu egoki baten bitartez.
Hona hemen iturburu-programa:
/* 8a1-BilaketaWHILE: elementu bat bilatu arrayan */
// Array baten hasieraketa. Datuak dituen array batean elementu baten
// posizioa bilatu elementuaren balioaren arabera.
#include <stdio.h>
#include <stdlib.h> // rand() eta srand() funtzioetarako
#include <time.h> // time() funtzioarako
#include <conio.h> // getche() funtziorako
#define BEHEMUGA 0
#define GOIMUGA 99
#define LUZMAX 40 // 40 elementu gehienez: 0. posiziotik 39. posizionarino
#define FALSE 0 // iAurkitua aldagairako
#define TRUE 1 // iAurkitua aldagairako
void BektoreaAleatoriokiBete(float[], int *);
void BektoreaIkusi(const float[], int);
int iBilatu_While(const float[], int, float);
int main()
{
float afZenbakiak[LUZMAX];
int iLuzera;
float fDatua;
int iPosizioa;
char cErantzuna;
do
{
printf("\n");
printf("\n\t Arrayaren luzera efektiboa eta bere balioak aleatorioki hartuz");
printf("\n\t --------------------------------------------------------------\n");
BektoreaAleatoriokiBete(afZenbakiak, &iLuzera);
printf("\n\t Arrayan iLuzera=%d elementu bete ondoren: \n", iLuzera);
BektoreaIkusi(afZenbakiak, iLuzera);
printf("\n");
do
{
printf("\t Bilatu nahi den elementuaren balioa [%.1f, %.1f] artekoa: ", -GOIMUGA*0.1, GOIMUGA*0.1);
scanf("%f", &fDatua);
} while (fDatua < -GOIMUGA*0.1 || fDatua > GOIMUGA*0.1); // -9.9 eta +9.9 artekoa
iPosizioa = iBilatu_While(afZenbakiak, iLuzera, fDatua);
if (iPosizioa == -1)
printf("\n\t %.1f balioko elementurik ez dago arrayan! \n", fDatua);
else
{
printf("\n\t %.1f balioko elementuaren lehen agerpena arrayan", fDatua);
printf("\n\t %d. posizioan ematen da. \n", iPosizioa);
}
do
{
printf("\n\t Beste array bat sortu eta bilaketa berri bat? (B/E): ");
cErantzuna = getche();
} while ((cErantzuna != 'b') && (cErantzuna != 'B') &&
(cErantzuna != 'e') && (cErantzuna != 'E'));
} while ((cErantzuna != 'e') && (cErantzuna != 'E'));
printf("\n\n");
return 0;
}
void BektoreaAleatoriokiBete(float afZenbakiak[], int *iLuzera) // lehen parametroa irterakoa da
{ // bigarren parametroa irteerakoa da
int iKont;
int iZbk;
int iZeinua;
// printf("\n");
srand(time(NULL)); // srand() zenbaki aleatorioak berriro hasiarazteko, hazia behar du
// time(NULL) funtzioak igarotako segundoak itzultzen ditu 1970-01-01 datatik hasita
*iLuzera = (rand() % (LUZMAX - 1)) + 1 ; // 0 eta 38 arteko balioari +1 eginez, gutxienez
// printf("\n *iLuzera=%d", *iLuzera); // elementu bat arrayan, balioak 1 eta 39 artekoak
for (iKont=0; iKont < *iLuzera; iKont++)
{
iZbk = (rand() % (GOIMUGA - BEHEMUGA + 1)) + BEHEMUGA; // 0 eta 99 artekoa
// printf("\n \t %2d (%d eta %d artekoa, biak barne)", iZbk, BEHEMUGA, GOIMUGA);
iZeinua = rand() % 2;
if (iZeinua == 0)
afZenbakiak[iKont] = 0.1*iZbk*(-1); // -9.9 eta 0 artekoa
else
afZenbakiak[iKont] = 0.1*iZbk; // 0 eta 9.9 artekoa
}
// printf("\n");
}
void BektoreaIkusi(const float afZenbakiak[], int iLuzera) // bi parametroak sarrerakoak
{
int iKont;
// afZenbakiak[3] = 3.33; babestuta dago
printf("\n");
printf("\t Posizioa Balioa\n");
printf("\t -------- ------\n");
for (iKont=0; iKont < iLuzera; iKont++)
{
printf("\t %9d \t %4.1f\n", iKont, afZenbakiak[iKont]);
}
}
int iBilatu_While(const float afZenbakiak[], int iZenbatElementu, float fDatua)
{
int iAurkitua; // bere balioak FALSE(0) eta TRUE(1)
int iKont;
iAurkitua = FALSE; // ez, oraindik ez da aurkitu
iKont = 0;
while ((iAurkitua == FALSE) && (iKont <= iZenbatElementu)) // edo honela ere bai...
{ // (!iAurkitua && (iKont <= iZenbatElementu))
if (afZenbakiak[iKont] == fDatua)
iAurkitua = TRUE; // bai, aurkitu da
else
iKont++;
}
if (iAurkitua == TRUE) // edo honela ere bai...
// if (iAurkitua)
return iKont;
else
return -1;
}
Adibide-ariketa honetan aztertuko dugu bereziki azpiprogramen parametroak nola pasatu behar diren. Parametro pasatze jardueran, kontzeptu bi hartzen zen aintzakotzat:
- Parametroaren jokamoldea: Sarrerako parametroa den ala irteerako parametroa den. Sarrerako parametroa bada, balioz pasatuko da; aldiz, irteerako parametroa bada, erreferentziaz pasatuko da.
- Parametroaren izaera: Array bat den ala bestelako datu-motakoa den. Array bada beti erreferentziaz pasatuko da, hori bai, sarrerako array bati const marka jarriko zaio aurretik.
Beraz, ikus dezagun astiro hiru funtzio hauetan parametroak nola pasatu diren:
void BektoreaIkusi(const float afZenbakiak[], int iLuzera);
int iBilatu(const float afZenbakiak[], int iZenbatElementu, float fDatua);
void BektoreaAleatoriokiBete(float afZenbakiak[], int *iLuzera);
BektoreaIkusi() funtzioa
Funtzio honek ez du ezer itzultzen eta dituen bi parametroak sarrerakoak dira, bat arraya denez const marka jarri zaio
- void itzultzen du
- afZenbakiak sarrerakoa parametroa array delako const marka
- iLuzera sarrerakoa, bestelako datu-motakoa delako balioz pasatzen da
iBilatu() funtzioa
Funtzio honek kopuru osoa itzultzen du eta dituen hiru parametroak sarrerakoak dira, bat arraya denez const marka jarri zaio
- int itzultzen du
- afZenbakiak sarrerakoa parametroa array delako const marka
- iLuzera sarrerakoa, bestelako datu-motakoa delako balioz pasatzen da
- fDatua sarrerakoa, bestelako datu-motakoa delako balioz pasatzen da
BektoreaAleatoriokiBete() funtzioa
Funtzio honek ez du ezer itzultzen eta dituen bi parametroak irteerakoak dira, eta erreferentziaz pasatzen dira. Bat arraya delako berez doa erreferentziaz, baina beste parametroari * marka jarri zaio
- void itzultzen du
- afZenbakiak irteerakoa parametroa array delako ez zaio ezer gehitzen
- iLuzera irteerakoa, bestelako datu-motakoa delako erreferentziaz pasatzean * jartzen zaio
Hurrengo irudian zenbaki errealen arNotak array bat daukagu, bere luzera efektiboa iLuzera aldagaiak adierazten du eta 5 balio du. Demagun 72.9 balioa bilatu nahi dugula arrayan, hau, balio horren indizea baldin eta arrayan badago.
Bilaketa ezin daiteke FOR baten bitartez egin, horregatik WHILE edo REPEAT kontrol-egituraren bat erabiliko dugu. WHILE erabiliz irudia honela ulertzen da:
![]() |
| Irudia handiago ikusteko bere gainean klik egin |
Irudiko lauki gorrian funtzioaren hiru parametroak eta gris kolorean funtzioaren bertako aldagaiak, aldagai laguntzaileak. WHILE-DO kontrol-egituraren baldintza lehendabizi ebaluatu aurretik bi hasierakieta egiten dira: iIndizea=1 eta boAurkitua=FALSE. Horrela ziurtatzen dugu WHILE-DO kontrol-egituraren barrura sartuko garela.
- iterazioan: iIndizea=1 eta boAurkitua=FALSE direlako while barrura sartu eta balioen konparaketa egiten da: arrayaren 1. elementua (22.3) eta bilatzen dugun rGakoa) desberdinak direnez iIndizea=2 eta berriro ebaluatzen da while barrura sartzea ala ez
- iterazioan: iIndizea=2 eta boAurkitua=FALSE direlako while barrura sartu eta balioen konparaketa egiten da: arrayaren 2. elementua (17.1) eta bilatzen dugun rGakoa), desberdinak direnez iIndizea=3 eta berriro ebaluatzen da while barrura sartzea ala ez
- iterazioan: iIndizea=3 eta boAurkitua=FALSE direlako while barrura sartu eta balioen konparaketa egiten da: arrayaren 3. elementua (72.9) eta bilatzen dugun rGakoa), berdinak direnez iIndizea=3 mantentzen da (emaitza izango dena) eta boAurkitua=TRUE jartzen da, eta oaingoan while aginduaren baldintza berriro ebaluatzen ez da barrura sartuko
Adibideko 3. iterazioa bukatzean prozesu errepikakorra eteten da boAurkitua=TRUE delako eta IF-THE-ELSE bati esker funtzioak erabakitzen du zer itzuli programa nagusiari:
- Adibidearen zenbakiekin azpiprogramak 3 itzuliko dio programa nagusiari
- Beste zenbaki batzuekin, baliteke bilatzen ari garen nota ez egotea arrayan, kasu horretan prozesu errepikakorra eteten da iIndizea=6 izatean, eta funtzioak 0 itzuliko lioke programa nagusiari
Array bateko bilaketaren aplikazio-adibideak hauek izan daitezke. Non arrayaren elementuak elkarrekiko desberdinak izan daitezen, elementu berria arrayan gorde aurretik, elementu berri horri froga bat egiten zaion:
- 8. jarduera (II) | Bilaketa sekuentzialaren aplikazio bat (arrayaren elementu guztiak desberdinak elkarrekiko)
- 8. jarduera (III) | Mediana eta batezbestekoa (arrayaren elementu guztiak desberdinak elkarrekiko eta ordenaturik)
|



iruzkinik ez:
Argitaratu iruzkina