| ZER DAKIDAN: 3. jarduera (I) | Errusiar Biderketaren Metodoa zertan den artikuluan ikasi nuen Errusiar Biderketa zertan den eta programatu nuen ere. ZER IKASIKO DUDAN: 3. jarduera (III) | Errusiar Biderketaren Metodoa programatzen artikuluan idatzitako kodea arrayak erabiliz programatuko dut. |
3. jarduera (I) | Errusiar Biderketaren Metodoa zertan den izenburuko artikulua gogoratuz, ariketa honetan bi zenbakiren arteko biderkadura kalkulatzen duen programa egingo dugu, baina biderketa burutzeko taulak arrayetan gordez.
Jakinik biderkagai biak int datu-motakoak direla (biak 0 eta 46000 artekoak), biderkadura long datu-motakoa izango da. Gogora ekar dezagun 3. jarduera (III) | Errusiar Biderketaren Metodoa programatzen artikulua eta bertan ematen den kodea, programa hori exekutatzean biderkagai handienak sartuko bagenitu ondoko emaitza eskuratuko genuke:
Horregatik, taularen datu-mota holako zerbait izango da, non zutabeak bi diren eta errenkaden kopurua iLUZERA oraindik ez dugun zehaztu:
type taliTaula = array[0..iLUZERA, 1..2] of longint ;
Errenkaden behemuga 0 izatea komeniko zaigu eta errenkaden goimuga den iLUZERA zehazteko jakin behar dugu "erdiak ematen dituen sekuentzia" segida logaritmiko bat dela, lehen biderkagaiaren baliorik handiena aukeratuko bagenu iBiderkagai1 =46000 mailak 14 izango lirateke:
2fMailak = iBiderkagai1 = 46000
log2(2fMailak) = log2(46000)
fMailak·log2(2) = log2(46000)
fMailak = log2(46000)/log2(2)
fMailak = ln(46000)/ln(2) = 10.736397/0.693147 = 15,48935
iMailak = 15
Mailak 15 izango dira gehienez, baina biderkagai biak taulak bildu nahi ditugunez, errenkaden behemuga 0 izan dadila eta errenkada horretan datuak diren biderkagai biak kokatuko ditugu. Ondorioz, taularen datu-mota hau izango da:
#define iHANDIENA 46000
#define iLUZERA 15
// errenkaden kopuru maximoa: iLUZERA
typedef long taliTaula[iLUZERA + 1][2]; // biderkagai biak 0. errenkadan
// zutaben kopurua beti: 2
Jakinik biderkagai biak integer datu-motakoak direla (biak 0 eta 46000 artekoak), biderkadura longint datu-motakoa izango da eta, gehienez, taularen neurria 15x2 izango da (0 errenkada barne). Baina, exekuzio jakin batean ez da zertan taula osoa bete behar; adibidez, biderkagaiak 34 eta 7 badira taularen neurri efektiboa honako ha izango da:
Erdiak Dobleak
------ -------
0. maila 34 7
1. maila 17 14
2. maila 8 28
3. maila 4 56
4. maila 2 112
5. maila 1 224
Argi dago zutabeak beti 2 izango direla eta taularen neurri efektikoa errenkada baliagarriak kopuruak finkatuko duela (goiko adibidean 5).Laburbilduz: Aurreko azpiataleko goiko taula hori memorian gordetzeko, bi dimentsiotako array bat beharko dugu, hots, zenbaki osoen taula bat beharko dugu. Orokorrean, bi dimentsiotako arrayaren indizeak 0-tik 15-ra joango dira errenkadetan eta zutabeak izendatzeko 1 eta 2 indizeak erabiliko ditugu. Baina adibidera etorriz, taularen neurria 5x2 izango da (non 2 beti konstantea den), horregatik iLuzeraEfek aldagaian 5 gordeko da.
iBiderkagai1 aldagaian 34 hartu bada, eta iBiderkagai2 aldagaian 7 hartu bada, aliTaula arrayaren itxura honako hau izango da, non iMailak = iLuzeraEfek = 5 izango den:
| aliTaula | ||
| 1 |
2 | |
| 0 | 34 | 7 |
| 1 | 17 |
14 |
| 2 | 8 | 28 |
| 3 | 4 | 56 |
| 4 | 2 | 112 |
| 5 | 1 | 224 |
| 6 | ||
| 7 | ||
| ... | ||
| 13 | ||
| 14 | ||
3. jarduera (I) | Errusiar Biderketaren Metodoa zertan den aplikatuz, lehen zutabeko bikoitien errenkadak kenduko ditugu eta aliTaula arraya abiapuntuz harturik aliTaulaLaburra arraya eskuratuko dugu:
| aliTaula | ||
| 1 |
2 | |
| 0 | ||
| 1 | 17 |
14 |
| 2 | ||
| 3 | ||
| 4 | ||
| 5 | 1 | 224 |
| 6 | ||
| 7 | ||
| ... | ||
| 13 | ||
| 14 | ||
aliTaulaLaburra array berriaren itxura honako hau izango da, non adibide honetan errenkadak bi direlako iLuzeraEfek = 1 izango den:
| aliTaulaLaburra | ||
| 1 |
2 | |
| 0 | 17 |
14 |
| 1 | 1 | 224 |
| 2 | ||
| 3 | ||
| ... | ||
| 13 | ||
| 14 | ||
Eskumako zutabean geratu diren zenbakien batuketa eginez, lortu den 14+224=238 batura bilatzen dugun emaitza da, hots, lortutako batura helburuko 34x7=238 biderkadura bezalakoa da.
/* Ariketa-61_ErrusiarBiderketa: arrayekin */
// "Errusiar Biderketaren Metodoa" aplikatzen duen programa bat idatzi nahi da.
// DATUAK:
// Sarrerako datuak bi biderkagaiak izango dira, biak positiboak eta osoak.
// EMAITZA:
// Irteera biderkadura izango da, bere datu-mota LONGINT izango da.
// Arrayaren neurria zehazteko, suposatuko dugu sarrerako biderkagairik handiena
// iHANDIENA (46000) izango dela. Horregatik: 2^fLUZERA = iHANDIENA
// fLUZERA·ln(2) = ln(iHANDIENA) >>> fLUZERA
// fLUZERA = ln(iHANDIENA) / ln(2) = 14.99995
// iLUZERA = trunc(ln(iHANDIENA) / ln(2) = 15
#include <stdio.h>
#include <conio.h> // getch() funtziorako
#include <math.h> // trunc() eta log() funtzioetarako
#define iHANDIENA 46000
#define iLUZERA 15
typedef long taliTaula[iLUZERA + 1][2];
int iZenbakiarenMailakKalkulatu(int iZenbakia);
long liBatuketakEgin(const taliTaula aliTaulaLaburra, int iLuzeraLaburra);
void ErrenkadaBikoitiakKendu( const taliTaula aliTaula, int iLuzeraEfek,
taliTaula aliTaulaLaburra, int *iLuzeraLaburra);
void TaulaBete(taliTaula aliTaula, int iLuzeraEfek, int iZenbaki_1, int iZenbaki_2);
void TaulaIkusi(const taliTaula aliTaula, int iLuzeraEfek);
int main()
{
int iZenbaki_1, iZenbaki_2, iMailak, iLuzeraEfek, iLuzeraLaburra;
taliTaula aliTaula, aliTaulaLaburra;
long liBiderkadura;
printf("\niHANDIENA ----> %d\n", iHANDIENA);
printf("iLUZERA = trunc(ln(iHANDIENA) / ln(2)) ----> %d\n\n", (int)trunc(log(iHANDIENA) / log(2)));
printf(" -------------------------------\n");
printf("| Errusiar Biderketaren Metodoa =============\n");
printf("| ----------------------------- |\n");
printf("| |\n");
printf("| Kopuru positiboekin lan eginez, bi zenbaki |\n");
printf("| irakurri eta haien biderkadura kalkulatu. |\n");
printf(" ============================================\n\n");
do
{
printf(" Lehen biderkagaia eman (1 eta %d artekoa), 39 adibidez: ", iHANDIENA);
scanf("%d", &iZenbaki_1);
} while (iZenbaki_1 <= 0 || iZenbaki_1 > iHANDIENA);
do
{
printf("Bigarren biderkagaia eman (0 eta %d artekoa), 7 adibidez: ", iHANDIENA);
scanf("%d", &iZenbaki_2);
} while (iZenbaki_2 < 0 || iZenbaki_2 > iHANDIENA);
iMailak = iZenbakiarenMailakKalkulatu(iZenbaki_1);
printf("\n%d biderkagaiari dagokion maila kopurua %d da:\n", iZenbaki_1, iMailak);
iLuzeraEfek = iMailak;
TaulaBete(aliTaula, iLuzeraEfek, iZenbaki_1, iZenbaki_2);
printf("\n");
TaulaIkusi(aliTaula, iLuzeraEfek);
printf("\n");
ErrenkadaBikoitiakKendu(aliTaula, iLuzeraEfek, aliTaulaLaburra, &iLuzeraLaburra);
TaulaIkusi(aliTaulaLaburra, iLuzeraLaburra);
printf("\n");
liBiderkadura = liBatuketakEgin(aliTaulaLaburra, iLuzeraLaburra);
printf("\"Errusiar Biderketaren Metodoa\" aplikatuz: %d x %d = %ld\n", iZenbaki_1, iZenbaki_2, liBiderkadura);
printf("Biderkadura ohiko * operadorearen bitartez: %d * %d = %d\n", iZenbaki_1, iZenbaki_2, iZenbaki_1 * iZenbaki_2);
printf("\n====================================================\n");
printf(" Edozein tekla sakatu amaitzeko\n");
printf("====================================================\n");
getch(); // karaktere bati itxaron
return 0;
}
int iZenbakiarenMailakKalkulatu(int iZenbakia)
{
return (int)trunc(log(iZenbakia) / log(2));
}
void TaulaBete(taliTaula aliTaula, int iLuzeraEfek, int iZenbaki_1, int iZenbaki_2)
{
aliTaula[0][0] = iZenbaki_1;
aliTaula[0][1] = iZenbaki_2;
long liErdia = iZenbaki_1;
long liDoblea = iZenbaki_2;
for (int iErrenkada = 1; iErrenkada <= iLuzeraEfek; iErrenkada++) {
liErdia /= 2;
liDoblea *= 2;
aliTaula[iErrenkada][0] = liErdia;
aliTaula[iErrenkada][1] = liDoblea;
}
}
void TaulaIkusi(const taliTaula aliTaula, int iLuzeraEfek)
{
printf("%32s %15s\n", "Erdiak", "Dobleak");
printf("%32s %15s\n", "------", "-------");
for (int iErrenkada = 0; iErrenkada <= iLuzeraEfek; iErrenkada++)
{
printf("%10d. maila%15ld%15ld\n", iErrenkada, aliTaula[iErrenkada][0], aliTaula[iErrenkada][1]);
}
}
void ErrenkadaBikoitiakKendu( const taliTaula aliTaula, int iLuzeraEfek,
taliTaula aliTaulaLaburra, int *iLuzeraLaburra)
{
*iLuzeraLaburra = -1; // La primera fila del array es 0
for (int iErrenkada = 0; iErrenkada <= iLuzeraEfek; iErrenkada++)
{
if (aliTaula[iErrenkada][0] % 2 == 1)
{
(*iLuzeraLaburra)++;
aliTaulaLaburra[*iLuzeraLaburra][0] = aliTaula[iErrenkada][0];
aliTaulaLaburra[*iLuzeraLaburra][1] = aliTaula[iErrenkada][1];
}
}
}
long liBatuketakEgin(const taliTaula aliTaulaLaburra, int iLuzeraLaburra)
{
long liBatura = 0;
for (int iErrenkada = 0; iErrenkada <= iLuzeraLaburra; iErrenkada++)
{
liBatura += aliTaulaLaburra[iErrenkada][1];
}
return liBatura;
}

iruzkinik ez:
Argitaratu iruzkina