2025(e)ko martxoaren 9(a), igandea

8. jarduera (II) | Bilaketa sekuentzialaren aplikazio bat

ZER DAKIDAN:
Bilaketa linealaren algoritmoari dagozkion programa, parametroak eta eskema ezagutzen ditut.



ZER IKASIKO DUDAN:
Bilaketa linealaren aplikazio bat ikusiko dut orain.



Demagun zenbaki errealak gordetzen dituen array bat bete behar dugula, baina arrayaren datuak ezin direla errepikaturik egon. Hori dela eta, teklatuz irakurritako datu bat arrayean gorde baino lehen datuaren bilaketa egin beharko da dagoeneko arrayean ez dagoela frogatze aldera.

Ariketaren bi bertsio erakutsiko ditugu. Batean bilaketa do-while egituraren bitartez gauzatzen da. Bigarrenean berriz, bilaketa egiteko while egitura erabiltzen da. Bertsio bietan algoritmo bera aplikatzen da:

  • Arrayan sartuko diren zenbakien kopurua irakurri
  • Irakurritako lehen zenbakia onartu eta arrayan gorde
  • Lehena ez den hurrengo zenbakietarako:
    • Zenbaki berria teklatuz irakurri
    • Zenbaki berria arrayan bilatu eta...
      1. Zenbaki berria arrayan ez badago, zenbaki hori onartu eta arrayan gorde
      2. Zenbaki berria arrayan dagoeneko badago, ez onartu eta irakurketa errepikatu
  • Bukatzeko, arrayaren edukia pantailaratzen da

Emandako zenbaki berria aurkitzen ez bada -1 marka bidaltzen du bilaketaren funtzioak. Bertsio batean eta besten modu besberdinez programatu da emaitzaren kanporaketa: lehen bertsioan if-else bitartez eta bigarrenean baldintzazko ? operadorearen bitartez. Honela:

  
    // emaitza itzultzeko if-else baldintzazko agindua erabiltzen da:
    // gakoa den zenbakia aurkitzen bada bere iIndizea itzuli
    // ez bada gako hori aurkitzen -1 gezurrezko posizioa itzuli
    if (afNotak[iIndizea] == fZbk)
        return iIndizea;  // aurkitzen bada dagokion indizea itzuli
    else
        return -1;       // ez bada aurkitzen -1 gezurrezko posizioa itzuli
  
    // emaiztza itzultzeko baldintzazko operadorea erabiltzen da:
    // gakoa den zenbakia aurkitzen bada bere iIndizea itzuli
    // ez bada gako hori aurkitzen -1 gezurrezko posizioa itzuli
    return boAurkitua ? iIndizea : -1;
[Baldintzako ? operadorea ez dugu ikasiko]

fZbk elementu berria arrayean iIndizea posizioan gorde aurretik, froga hau egiten zaio: arraya arakatu BEHEMUGA eta iIndizea-1 artean fZbk elementua bilatuz. Hona hemen lehen bertsioaren programa:

/* 8b1-Jarduera_BalioDesberdinakDO-WHILE: Zenbaki errealean array bat bete */

// Algoritmoa:
// Arrayan sartuko diren zenbakien kopurua irakurri
// Teklatuz ematen den lehen zenbakia onartu eta hurrengoak onartzeko
// urratsak hauek dira:
//    - Zenbaki berria teklatuz irakurri
//    - Zenbaki berria arrayan bilatu
//    - Zenbaki berria arrayan ez badago, zenbaki hori onartu
//    - Zenbaki berria arrayan dagoeneko badago,
//      ez onartu eta irakurketa errepikatu

#include <stdio.h>

#define BEHEMUGA 0
#define GOIMUGA 11
#define LUZERA  12

int iBilaketaLinealaDOWHILE(const float afNotak[], int iZenbat, float fZbk);
void ArrayaDesberdinekinBete(float afNotak[], int iLuzera);
void ArrayaIkusi(const float afNotak[], int iLuzera);


int main()  // Programaren sarrera-puntua
{
    float afNotak[LUZERA]; // 12 zenbaki gordetzeko arraya, 0-tik 11-ra
    int iLuzera;

    do
    {
        printf("Zenbat elementu izango dira (%d eta %d arteko balioa): ", BEHEMUGA+1, LUZERA);
        scanf("%d", &iLuzera);
        fflush(stdin);
    } while (iLuzera < BEHEMUGA+1 || iLuzera > LUZERA);

    ArrayaDesberdinekinBete(afNotak, iLuzera);
    ArrayaIkusi(afNotak, iLuzera);

    return 0;
}


// iBilaketaLinealaDOWHILE funtzioa
int iBilaketaLinealaDOWHILE(const float afNotak[], int iZenbat, float fZbk)
{
    int iIndizea = -1;  // -1 gezurrezko posizioa litzateke, ikusi BEHEMUGA = 0 dela
    do
    {
        iIndizea++;
    } while ((afNotak[iIndizea] != fZbk) && (iIndizea < iZenbat));

    // emaitza itzultzeko if-else baldintzazko agindua erabiltzen da:
    // gakoa den zenbakia aurkitzen bada bere iIndizea itzuli
    // ez bada gako hori aurkitzen -1 gezurrezko posizioa itzuli
    if (afNotak[iIndizea] == fZbk)
        return iIndizea;  // aurkitzen bada dagokion indizea itzuli
    else
        return -1;        // ez bada aurkitzen -1 gezurrezko posizioa itzuli
}


// ArrayaDesberdinekinBete funtzioa
void ArrayaDesberdinekinBete(float afNotak[], int iLuzera)
{
    int iIndizea, iPosizioa;
    float fZbk;

    printf("Sartu arrayaren %d. datua: ", BEHEMUGA);
    scanf("%f", &afNotak[BEHEMUGA]);
    fflush(stdin);

    for (iIndizea = BEHEMUGA + 1; iIndizea < iLuzera; iIndizea++)
    {
        do
        {
            printf(" Eman arrayaren %d. datua: ", iIndizea);
            scanf("%f", &fZbk);
            fflush(stdin);

            iPosizioa = iBilaketaLinealaDOWHILE(afNotak, iIndizea, fZbk);

            if (iPosizioa != -1)
                printf("%.2lf balioa %d. posizioan dago, beste balio bat aukeratu!\n", fZbk, iPosizioa);
            else
                afNotak[iIndizea] = fZbk;
        } while (iPosizioa != -1);  // zenbakia aurkitzen den bitartean jarraitu
    }
}


// ArrayaIkusi funtzioa
void ArrayaIkusi(const float afNotak[], int iLuzera)
{
    int iIndizea;

    printf("\nArrayaren edukia:\n");
    for (iIndizea = BEHEMUGA; iIndizea < iLuzera; iIndizea++)
    {
        printf("%2d. nota = %.1lf\n", iIndizea, afNotak[iIndizea]);
    }
    printf("\n");
}
Aipatzekoa da iLuzera programa nagusian irakurtzen dela eta horregatik parametro hori sarrerakoa dela bi prozeduretan, bai ArrayaDesberdinekinBete prozeduran eta bai ArrayaIkusi prozeduran.


Lehen bezala orain ere, fZbk elementu berria arrayean iIndizea posizioan gorde aurretik, froga hau egiten zaio: arraya arakatu BEHEMUGA eta iIndizea-1 artean fZbk elementua bilatuz. Hona hemen lehen bertsioaren programa:

/* 8b2-BalioDesberdinakWHILE: Zenbaki errealean array bat bete */

// Algoritmoa:
// Arrayan sartuko diren zenbakien kopurua irakurri ondoren, teklatuz ematen den
// lehen zenbakia onartzen da eta hurrengoak onartzeko urratsak hauek dira:
//    - Zenbaki berria teklatuz irakurri
//    - Zenbaki berria arrayan bilatu
//    - Zenbaki berria arrayan ez badago, zenbaki hori onartu
//    - Zenbaki berria arrayan dagoeneko badago,
//      ez onartu eta irakurketa errepikatu

#include <stdio.h>

#define TRUE 1   // iAurkitua aldagairako
#define FALSE 0  // iAurkitua aldagairako
#define BEHEMUGA 0
#define GOIMUGA 11
#define LUZERA  12

typedef float tafZerrenda[GOIMUGA + 1];    // 12 elementuko arraya

int iBilaketaLinealaWHILE(const float afNotak[], int iZenbat, float fZbk);
void ArrayaIkusi(const float afNotak[], int iLuzera);
void ArrayaDesberdinekinBete(float afNotak[], int iLuzera);


int main()  // programaren sarrera-puntua
{
    float afNotak[LUZERA]; // 12 zenbaki gordetzeko arraya, 0-tik 11-ra
    int iLuzera;

    do
    {
        printf("Zenbat elementu izango dira (%d eta %d arteko balioa): ", BEHEMUGA+1, LUZERA);
        scanf("%d", &iLuzera);
        fflush(stdin);
    } while (iLuzera < BEHEMUGA+1 || iLuzera > LUZERA);

    ArrayaDesberdinekinBete(afNotak, iLuzera);
    ArrayaIkusi(afNotak, iLuzera);

    return 0;
}


// iBilaketaLinealaWHILE funtzioa
int iBilaketaLinealaWHILE(const float afNotak[], int iZenbat, float fZbk)
{
    int iIndizea = BEHEMUGA;
    int iAurkitua = FALSE;

    while ((iIndizea < iZenbat) && iAurkitua == FALSE)  // edo honela ere bai...
    {  // ((iIndizea < iZenbat) && !iAurkitua)
        printf("%2d. elementua prozesatzen...   afNotak[%d]=%.2f eta fZbk=%.2f\n", iIndizea, iIndizea, afNotak[iIndizea], fZbk);

        if (afNotak[iIndizea] == fZbk)
            iAurkitua = TRUE;
        else
            iIndizea++;
    }

    // emaitza itzultzeko baldintzazko operadorea erabiltzen da:
    // gakoa den zenbakia aurkitzen bada bere iIndizea itzuli
    // ez bada gako hori aurkitzen -1 gezurrezko posizioa itzuli
    return iAurkitua ? iIndizea : -1;
    // ? horren ordez if agindua erabiltzea gomendatzen da
}


// ArrayaDesberdinekinBete funtzioa
void ArrayaDesberdinekinBete(float afNotak[], int iLuzera)
{
    int iIndizea, iPosizioa;
    float fZbk;

    printf("Sartu arrayaren %d. datua: ", BEHEMUGA);
    scanf("%f", &afNotak[BEHEMUGA]);
    fflush(stdin);

    for (iIndizea = BEHEMUGA + 1; iIndizea < iLuzera; iIndizea++)
    {
        do
        {
            printf(" Eman arrayaren %d. datua: ", iIndizea);
            scanf("%f", &fZbk);
            fflush(stdin);

            iPosizioa = iBilaketaLinealaWHILE(afNotak, iIndizea, fZbk);

            if (iPosizioa != -1)
                printf(" %.2lf balioa %d. posizioan dago, beste balio bat aukeratu!\n", fZbk, iPosizioa);
            else
                afNotak[iIndizea] = fZbk;
        } while (iPosizioa != -1);  // zenbakia aurkitzen den bitartean jarraitu
    }
}


// ArrayaIkusi() funtzioa
void ArrayaIkusi(const float afNotak[], int iLuzera)
{
    int iIndizea;

    printf("\nArrayaren edukia:\n");
    for (iIndizea = BEHEMUGA; iIndizea < iLuzera; iIndizea++)
    {
        printf("%2d. posizioko nota: %.1lf\n", iIndizea, afNotak[iIndizea]);
    }
    printf("\n");
}






  • 8b-Jarduera_BalioDesberdinakDO-WHILE.cbp | main.c  
  • 8b-Jarduera_BalioDesberdinakWHILE.cbp | main.c  


 

iruzkinik ez:

Argitaratu iruzkina