2025(e)ko martxoaren 21(a), ostirala

9. jarduera | Ezabaketa array batean

ZER DAKIDAN:
Arrayekin lan egiteko hainbat algoritmo ezagutzen dut.



ZER IKASIKO DUDAN:
Orain ikasiko dut arrayaren elementu bat nola kendu arraytik. Ondoren, elementu batzuk arraytik kentzeko algoritmoak ikasiko ditut.


Irudian zenbaki errealen afNotak array bat daukagu, bere luzera efektiboa iLuzera aldagaiak adierazten du eta 5 balio du. Demagun 2 posizioan dagoen 17.1 balioa arraytik kendu nahi dugula, hots, arrayaren bigarren elementua ezabatu nahi dugula. Azkenean, noski, iLuzera aldagaiaren edukia 4 izango da.

Irudia handiago ikusteko bere gainean klik egin, non ezabaketaren
algoritmo bera bi lengoaietan ematen den: C eta Pascal

Programa nagusiak hiru parametro pasatzen dizkio Ezabatu() funtzioari, lehenengo biak sarrera/irteerakoak eta azkena sarrerakoa. for kontrol-egiturari esker hiru iterazi emango dira adibide honetan:
  1. iterazioan: iIndizea=2 delako 17.1 datua zapalduta geratuko da, izan ere afNotak[2] posizioan afNotak[3] balioa kopiatzen delako eta 72.9 datua bikoiztuta geratzen da
  2. iterazioan: iIndizea=3 delako 72.9 datua zapalduta geratuko da, izan ere afNotak[3] posizioan afNotak[4] balioa kopiatzen delako eta 56.8 datua bikoiztuta geratzen da
  3. iterazioan: iIndizea=4 delako 56.8 datua zapalduta geratuko da, izan ere afNotak[4] posizioan afNotak[5] balioa kopiatzen delako eta 66.6 datua bikoiztuta geratzen da
Adibide honetan 3. iterazioarekin bukatzen da prozesu errepikakorra, eta ezabaketa benetan gauzatzeko arrayaren luzera dekrementatu beharra dago: arrayaren luzera efektiboa 4 izan dadila, horregatik iLuzera=4 jarri behar da (bigarren parametroa irteerakoa izatearen arrazoia hauxe da).
// ----------- Elementu bat arraytik ezabatu -------------
// afNotak: sarrera/irteerako parametroa, zenbaki errealen
//          array bat da
// iLuzera: sarrera/irteerako parametroa, arrayaren luzera
//          logikoa adierazten du (irtetean bat gutxiago)
// iNon:    sarrerako parametroa, arraytik ezabatu behar
//          den elementuaren posizioa adierazten du
void Ezabaketa(tafZerrenda afNotak,
               int *iLuzera,
               int iNon)
{
    for (int iIndizea = iNon; iIndizea < *iLuzera; iIndizea++)
    {
        afNotak[iIndizea] = afNotak[iIndizea + 1];
    }
    (*iLuzera)--;
}

Array bateko elementu bat ezabatzeko algoritmoa ulertuz gero, erraza da ulertzea array batean elementu bakar berri bat nola sar daitekeen (ikusi 10. jarduera | txertaketa array batean irudia eta azalpena).

Eta arrayaren elementu bat baino gehiago ezabatu behar baditugu? Arrayaren elementu bat baino gehiago ezabatu behar baditugu bi aukera ditugu:

  1. Goiko algoritmoa hainbat aldiz errepikatzea (ikusi 9b-Ezabaketa-HainbatElementu.cbp programa)
  2. Array laguntzaile bat erabiltzea (ikusi 9c-Ezabaketa-ArrayLaguntzailez.cbp programa). Adibidez, balio txikiak array batetik kendu: Datuak ez dira ezabatuko; horren ordez, datu onargarriekin (ezabatuko ez direnekin) array berri bat sortuko da, emaitza izango den array berria sortuko da

Arraya auzaz bete ondoren, ezaguna den iNon posizioko elementua arraytik kendu. Baliteke ezabatu nahi den elementuaren balioa ezagutzen dela eta ez bere iNon posizioa, kasu horretan bilaketa bat egingo litzateke arrayan elementuaren iNon posizioa zehazteko.

/* 9a-Ezabaketa-ElementuBakarra: Ezabaketaren algoritmoa elementu bakar bati aplikatuta. */

// Arraya auzaz bete ondoren, ezabatuko den elementuaren posizioa ematen da teklatuz.
// Beste egoera batean, baliteke ezabatu nahi den elementuaren balioa ezagutzen dela,
// kasu horretan bilaketa bat egingo litzateke arrayan eta elementuaren posizioa
// zehaztu beharko litzateke. Edozein kasutan, Ezabaketa() delako funtzioan for bati
// esker elementua ezabatzen da eta arrayaren luzerari dekrementu bat egiten zaio.

#include <stdio.h>
#include <stdlib.h>   // rand() eta srand() funtzioetarako
#include <time.h>     // time() funtzioarako

#define BEHEMUGA 0
#define GOIMUGA 19

typedef float tafZerrenda[GOIMUGA];   // gehienez 20 zenbakiren arrayak, indizeak 0-tik 19-ra

void ArrayaBete(tafZerrenda afNotak, int *iLuzera);
void ArrayaIkusi(const tafZerrenda afNotak, int iLuzera);
void Ezabaketa(tafZerrenda afNotak,
               int *iLuzera,
               int iNon);

int main()
{
    tafZerrenda afNotak;
    int iLuzera, iNon;
    float rElemKopia;

    ArrayaBete(afNotak, &iLuzera);
    ArrayaIkusi(afNotak, iLuzera);

    // Ezabatu nahi den elementuaren posizioa eskatu
    do
    {
        printf("Ezabatuko den zenbakiaren posizioa arrayan (%d eta %d artekoa): ", BEHEMUGA, iLuzera);
        scanf("%d", &iNon);
    } while (iNon < BEHEMUGA || iNon > iLuzera);

    // Ezabatuko den datua gordeko dugu
    rElemKopia = afNotak[iNon];

    // Elementua ezabatu eta arraya berriz ikusi
    Ezabaketa(afNotak, &iLuzera, iNon);
    ArrayaIkusi(afNotak, iLuzera);

    printf("Hona hemen arraytik ezabatu den zenbakia: %.3f\n", rElemKopia);

    return 0;
}


// Arraya ausazko balioekin bete
void ArrayaBete(tafZerrenda afNotak, int *iLuzera)
{
    srand(time(NULL));
    *iLuzera = rand() % GOIMUGA + 1;    // 0 eta 19 arteko balioak
    printf("Arrayan %d datu gordetzen...\n", *iLuzera + 1);
    for (int i = BEHEMUGA; i <= *iLuzera; i++)
    {
        afNotak[i] = (float)rand() / RAND_MAX * 10; // 0.00 eta 9.99 arteko balioak
    }
}


// Arrayaren edukia pantailaratu
void ArrayaIkusi(const tafZerrenda afNotak, int iLuzera)
{
    printf("Arrayaren edukia:\n");
    for (int i = BEHEMUGA; i <= iLuzera; i++)
    {
        printf("%2d. nota = %.3f\n", i, afNotak[i]);
    }
    printf("\n");
}


// ----------- Elementu bat arraytik ezabatu -------------
// afNotak: sarrera/irteerako parametroa, zenbaki errealen
//          array bat da
// iLuzera: sarrera/irteerako parametroa, arrayaren luzera
//          logikoa adierazten du (irtetean bat gutxiago)
// iNon:    sarrerako parametroa, arraytik ezabatu behar
//          den elementuaren posizioa adierazten du        
void Ezabaketa(tafZerrenda afNotak,
               int *iLuzera,
               int iNon)
{
    for (int iIndizea = iNon; iIndizea < *iLuzera; iIndizea++)
    {
        afNotak[iIndizea] = afNotak[iIndizea + 1];
    }
    (*iLuzera)--;
}


Erreferentzia bat hartuz txikiagoak diren elementu guztiak kendu nahi dira. Arraya auzaz bete ondoren eta jakinik elementuak onartzeko fMuga balioa zein den, arraya hasieratik bukaeraino prozesatzen da Ezabaketak() funtzioan bere elementuak banan-banan alderatuz fMuga balioarekin eta dagokionean elementua ezabatuz den ElementuBatEzabatu() funtzioan.

Ikusi nola ElementuBatEzabatu() funtzioak dekrementatzen duen arrayaren luzera adierazten duen iLuzera aldagaia. Horrexegatik, iLuzera alda daitekeelako, Ezabaketak() funtzioan ezin daiteke for kontrol-egitura erabili eta bere ordez while agindu errepikakorra erabili da.

/* 9b-Ezabaketa-HainbatElementu: Ezabaketaren algoritmoa hainbat elementui aplikatuta. */

// Arraya auzaz bete ondoren eta jakinik elementuak onartzeko fMuga balioa zein
// den, arraya hasieratik bukaeraino prozesatzen da Ezabaketak() funtzioan bere
// elementuak banan-banan alderatuz fMuga balioarekin eta dagokionean elementua
// ezabatuz den ElementuBatEzabatu() funtzioan.

// Ikusi nola ElementuBatEzabatu() funtzioak dekrementatzen duen arrayaren luzera
// adierazten duen iLuzera aldagaia. Horrexegatik, iLuzera alda daitekeelako,
// Ezabaketak() funtzioan ezin daiteke for kontrol-egitura erabili eta bere ordez
// while agindu errepikakorra erabili da.

#include <stdio.h>
#include <stdlib.h>   // rand() eta srand() funtzioetarako
#include <time.h>     // time() funtzioarako

#define BEHEMUGA 0
#define GOIMUGA 19

typedef float tafZerrenda[GOIMUGA];   // gehienez 20 zenbakiren arrayak, indizeak 0-tik 19-ra

void ArrayaBete(tafZerrenda afNotak, int *iLuzera);
void ArrayaIkusi(const tafZerrenda afNotak, int iLuzera);
void ElementuBatEzabatu(tafZerrenda afNotak,
                        int *iLuzera,
                        int iNon);
void Ezabaketak(tafZerrenda afNotak,
                int *iLuzera,
                float fMuga);

int main()
{
    tafZerrenda afNotak;
    int iLuzera;
    float fMuga;

    ArrayaBete(afNotak, &iLuzera);
    ArrayaIkusi(afNotak, iLuzera);

    do  // Muga eskatu erabiltzaileari
    {
        printf("Zenbakiak ezabatzeko muga eman 0.00 eta 9.99 artekoa: ");
        scanf("%f", &fMuga);
    } while (fMuga <= 0.00 || fMuga >= 9.99);

    Ezabaketak(afNotak, &iLuzera, fMuga);
    ArrayaIkusi(afNotak, iLuzera);

    return 0;
}


// Arraya ausazko balioekin bete
void ArrayaBete(tafZerrenda afNotak, int *iLuzera)
{
    srand(time(NULL));
    *iLuzera = rand() % GOIMUGA + 1;    // 0 eta 19 arteko balioak
    printf("Arrayan %d datu gordetzen...\n", *iLuzera + 1);
    for (int i = BEHEMUGA; i <= *iLuzera; i++)
    {
        afNotak[i] = (float)rand() / RAND_MAX * 10; // 0.00 eta 9.99 arteko balioak
    }
}

// Arrayaren edukia pantailaratu
void ArrayaIkusi(const tafZerrenda afNotak, int iLuzera)
{
    printf("Arrayaren edukia:\n");
    for (int i = BEHEMUGA; i <= iLuzera; i++)
    {
        printf("%2d. nota = %.3f\n", i, afNotak[i]);
    }
    printf("\n");
}

// Elementu bat arraytik ezabatu
void ElementuBatEzabatu(tafZerrenda afNotak,
                        int *iLuzera,
                        int iNon)
{
    for (int iIndizea = iNon; iIndizea < *iLuzera; iIndizea++)
    {
        afNotak[iIndizea] = afNotak[iIndizea + 1];
    }
    (*iLuzera)--;
}


// Elementu guztiak banan-banan aztertu eta txikiak direnak ezabatu
void Ezabaketak(tafZerrenda afNotak,
                int *iLuzera,
                float fMuga)
{
    int k = 0;
    while (k <= *iLuzera)
    {
        if (afNotak[k] < fMuga)
            ElementuBatEzabatu(afNotak, iLuzera, k);
        else
            k++;
    }
}


Erreferentzia bat hartuz txikiagoak diren elementu guztiak kendu nahi dira. Arraya auzaz bete ondoren eta jakinik elementuak onartzeko fErreferentzia balioa zein den, arraya hasieratik bukaeraino prozesatzen da ArrayarenTxikiakEzabatu() funtzioan bere elementuak banan-banan alderatuz fErreferentzia balioarekin eta dagokienean elementuak afNotaHandiak[] arrayan gordetzen dira.

Azkenean, interesatzen den informazioa k elementuko afNotaHandiak[] funtzioan dagoelako, helburu den afNotak[i] arrayara ekarri beharko da (noski, iLuzera aldagaiak k balioa hartuko du).

/* 9c-Ezabaketa-ArrayLaguntzailez: Algoritmo hau egitan ez da ezabaketa bat
                                   prozesaketa bat baizik bektore laguntzaile
                                   bat erabiltzen da emaitza lortzeko. */

// Jatorrizko afNotak[] arrayaren intesatzen zaizkigun elementuak afNotaHandiak[]
// izeneko arrayan gordetzen dira, ondoren afNotaHandiak[] elementu guzti horiek
// fNotak[] helburuko arrayara eramango dira.

#include <stdio.h>
#include <stdlib.h>     // rand() eta srand() funtzioetarako
#include <time.h>       // time() funtzioarako

#define BEHEMUGA 0
#define GOIMUGA 19

typedef float tafZerrenda[GOIMUGA];   // gehienez 20 zenbakiren arrayak, indizeak 0-tik 19-ra

void ArrayaBete(tafZerrenda afNotak, int *iLuzera);
void ArrayaIkusi(const tafZerrenda afNotak, int iLuzera);
void ArrayarenTxikiakEzabatu(tafZerrenda afNotak,
                             int *iLuzera,
                             float fErreferentzia);

int main()
{
    tafZerrenda afNotak;
    int iLuzera;
    float fErreferentzia;

    ArrayaBete(afNotak, &iLuzera);
    ArrayaIkusi(afNotak, iLuzera);

    printf("Elementu txikiak arrayetik ezabatu\n");
    printf("Eman erreferentziaren balioa: ");
    scanf("%f", &fErreferentzia);

    ArrayarenTxikiakEzabatu(afNotak, &iLuzera, fErreferentzia);
    ArrayaIkusi(afNotak, iLuzera);

    return 0;
}


// Arraya ausazko balioekin bete
void ArrayaBete(tafZerrenda afNotak, int *iLuzera)
{
    srand(time(NULL));
    *iLuzera = rand() % GOIMUGA + 1;    // 0 eta 19 arteko balioak
    printf("Arrayan %d datu gordetzen...\n", *iLuzera + 1);
    for (int i = BEHEMUGA; i <= *iLuzera; i++)
    {
        afNotak[i] = (float)rand() / RAND_MAX * 10; // 0.00 eta 9.99 arteko balioak
    }
}


// Arrayaren edukia pantailaratu
void ArrayaIkusi(const tafZerrenda afNotak, int iLuzera)
{
    printf("Arrayaren edukia:\n");
    for (int i = BEHEMUGA; i <= iLuzera; i++)
    {
        printf("%2d. nota = %.3f\n", i, afNotak[i]);
    }
    printf("\n");
}


// Array laguntzaile batean zenbaki handiak gorde eta emaitza den arraya hasierakora eraman
void ArrayarenTxikiakEzabatu(tafZerrenda afNotak, int *iLuzera, float fErreferentzia)
{
    tafZerrenda afNotaHandiak;
    int k = -1;   // if barruan sartzean k++ eginez k=0 izango da

    for (int i = BEHEMUGA; i <= *iLuzera; i++)
    {
        if (afNotak[i] > fErreferentzia)
        {
            k++;
            afNotaHandiak[k] = afNotak[i];
        }
    }

    for (int i = BEHEMUGA; i <= k; i++)
    {
        afNotak[i] = afNotaHandiak[i];
    }
    *iLuzera = k;
}






  • 9a-Ezabaketa-ElementuBakarra.cbp | main.c  
  • 9b-Ezabaketa-HainbatElementu.cbp | main.c  
  • 9c-Ezabaketa-ArrayLaguntzailez.cbp | main.c  


 

iruzkinik ez:

Argitaratu iruzkina