Errusiar Biderketaren Metodoa izenburuko artikulua gogoratuz, ariketa honetan bi zenbakiren arteko biderkadura kalkulatzen duen programa egingo dugu, baina biderketa burutzeko taulak arrayetan gordez.
Jakinik biderkagai biak integer datu-motakoak direla (biak 0 eta MAXINT artekoak), biderkadura longint datu-motakoa izango da. Gogora ekar dezagun 4. astea | Errusiar Biderketaren Metodoa programatzen artikulua eta bertan ematen den ErrusiarBiderketarenMetodoaProgramatzen.pas 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 = MAXINT = 32767 mailak 14 izango lirateke:
2rMailak = iBiderkagai1 = 32767
log2(2rMailak) = log2(32767)
rMailak·log2(2) = log2(32767)
rMailak = log2(32767)/log2(2)
rMailak = ln(32767)/ln(2) = 14.99995
iMailak = 14
Mailak 14 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:
program ErrusiarBiderketarenMetodoa_ARRAY ; const iLUZERA = 14 ; type taliTaula = array[0..iLUZERA, 1..2] of longint ; (* errenkaden kopuru maximoa: iLUZERA *) (* biderkagai biak 0. errenkadan *) (* zutaben kopurua beti: 2 *) ...
Jakinik biderkagai biak integer datu-motakoak direla (biak 0 eta MAXINT 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 224Argi 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 14-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 |
Errusiar Biderketaren Metodoa 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.
Arrayak darabilen Errusiar Biderketaren Metodoaren programa bat jarraian erakusten da:
{ "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 } { MAXINT izango dela. Horregatik: 2^rLUZERA = MAXINT } { rLUZERA·ln(2) = ln(MAXINT) >>> rLUZERA } { rLUZERA = ln(MAXINT) / ln(2) = 14.99995 } { iLUZERA = trunc(ln(MAXINT) / ln(2) = 14 } program ErrusiarBiderketarenMetodoa_ARRAY ; const iLUZERA = 14 ; HANDIENA = MAXINT ; (* MAXINT bada daturik garaiena iLUZERA 14 izan beharko da *) type taliTaula = array[0..iLUZERA, 1..2] of longint ; (* errenkaden kopuru maximoa: iLUZERA *) (* biderkagai biak 0. errenkadan *) (* zutaben kopurua beti: 2 *) function ifnZenbakiarenMailakKalkulatu(iZenbakia: integer): integer ; var rMailak: real ; iMailak: integer ; begin //writeln('Adibidea --> 2^X=63 ekuazioaren ebazpena 5,98 da eta mailak 5 dira.') ; //writeln('Adibidea --> 2^X=64 ekuazioaren ebazpena 6,00 da eta mailak 6 dira.') ; //writeln('Adibidea --> 2^X=65 ekuazioaren ebazpena 6,02 da eta mailak 6 dira.') ; (* 2^x = 65 *) rMailak := ln(iZenbakia) / ln(2) ; (* x·ln(2) = ln(65) *) iMailak := trunc(rMailak) ; //writeln(iOINARRIA:15, '^X=', iZenbakia, ' ekuazioaren ebazpena ', rMailak:0:2, ' da. Mailak ', iMailak, ' dira.') ; ifnZenbakiarenMailakKalkulatu := iMailak ; end ; procedure TaulaBete(var aliTaula: taliTaula; iLuzeraEfek: integer; iZenbaki_1: integer; iZenbaki_2: integer) ; var iErrenkada: integer ; liErdia, liDoblea: LongInt ; begin aliTaula[0, 1] := iZenbaki_1 ; aliTaula[0, 2] := iZenbaki_2 ; liErdia := iZenbaki_1 ; liDoblea := iZenbaki_2 ; for iErrenkada:=1 to iLuzeraEfek do begin liErdia := liErdia div 2 ; liDoblea := liDoblea * 2 ; aliTaula[iErrenkada, 1] := liErdia ; aliTaula[iErrenkada, 2] := liDoblea ; end ; end ; procedure TaulaIkusi(const aliTaula: taliTaula; iLuzeraEfek: integer) ; var iErrenkada: integer ; begin writeln('Erdiak':32, 'Dobleak':15) ; writeln('------':32, '-------':15) ; for iErrenkada:=0 to iLuzeraEfek do begin write(iErrenkada:10, '. maila') ; write(aliTaula[iErrenkada, 1]:15) ; writeln(aliTaula[iErrenkada, 2]:15) ; end ; end ; procedure ErrenkadaBikoitiakKendu( const aliTaula: taliTaula; iLuzeraEfek: integer; var aliTaulaLaburra: taliTaula; var iLuzeraLaburra: integer) ; var iErrenkada: integer ; begin iLuzeraLaburra := -1 ; (* taularen lehen errenkada 0 delako *) for iErrenkada:=0 to iLuzeraEfek do begin if aliTaula[iErrenkada, 1] mod 2 = 1 then begin iLuzeraLaburra := iLuzeraLaburra + 1 ; aliTaulaLaburra[iLuzeraLaburra, 1] := aliTaula[iErrenkada, 1] ; aliTaulaLaburra[iLuzeraLaburra, 2] := aliTaula[iErrenkada, 2] ; end ; end ; end ; function fnliBatuketakEgin(const aliTaulaLaburra: taliTaula; iLuzeraLaburra: integer): longint ; var iErrenkada: integer ; liBatura: longint ; begin liBatura := 0 ; for iErrenkada:=0 to iLuzeraLaburra do begin liBatura := liBatura + aliTaulaLaburra[iErrenkada, 2] ; //writeln(iErrenkada, '. batura = ', liBatura:0:2) ; end ; fnliBatuketakEgin := liBatura ; end ; { ----------------------------------------------------------------------------- } var iZenbaki_1, iZenbaki_2, iMailak, iLuzeraEfek, iLuzeraLaburra: integer ; aliTaula, aliTaulaLaburra: taliTaula ; liBiderkadura: longint ; begin writeln ; writeln('MAXINT ----> ', MAXINT) ; writeln('iLUZERA = trunc(ln(MAXINT) / ln(2)) ----> ', trunc(ln(MAXINT) / ln(2))) ; writeln ; writeln ; writeln(' -------------------------------') ; writeln('| Errusiar Biderketaren Metodoa =============') ; writeln('| ----------------------------- |') ; writeln('| |') ; writeln('| Kopuru positiboekin lan eginez, bi zenbaki |') ; writeln('| irakurri eta haien biderkadura kalkulatu. |') ; writeln(' ============================================') ; writeln ; repeat write(' Lehen biderkagaia eman (1 eta ', HANDIENA, ' artekoa), 39 adibidez: ') ; readln(iZenbaki_1) ; until (iZenbaki_1 > 0) and (iZenbaki_1 <= HANDIENA) ; repeat write('Bigarren biderkagaia eman (0 eta ', HANDIENA, ' artekoa), 7 adibidez: ') ; readln(iZenbaki_2) ; until (iZenbaki_2 >= 0) and (iZenbaki_2 <= HANDIENA) ; iMailak := ifnZenbakiarenMailakKalkulatu(iZenbaki_1) ; writeln ; writeln(iZenbaki_1, ' biderkagaiari dagokion maila kopurua ', iMailak, ' da:') ; iLuzeraEfek := iMailak ; TaulaBete(aliTaula, iLuzeraEfek, iZenbaki_1, iZenbaki_2) ; (* taularen bigarren dimentsioa ez da behar beti 2 delako *) writeln ; TaulaIkusi(aliTaula, iLuzeraEfek) ; (* taularen bigarren dimentsioa ez da behar beti 2 delako *) writeln ; ErrenkadaBikoitiakKendu(aliTaula, iLuzeraEfek, aliTaulaLaburra, iLuzeraLaburra) ; TaulaIkusi(aliTaulaLaburra, iLuzeraLaburra) ; (* taularen bigarren dimentsioa ez da behar beti 2 delako *) writeln ; liBiderkadura := fnliBatuketakEgin(aliTaulaLaburra, iLuzeraLaburra) ; writeln('"Errusiar Biderketaren Metodoa" aplikatuz: ', iZenbaki_1, ' x ', iZenbaki_2, ' = ', liBiderkadura) ; writeln('Biderkadura ohiko * operadorearen bitartez: ', iZenbaki_1, ' * ', iZenbaki_2, ' = ', iZenbaki_1 * iZenbaki_2) ; writeln ; writeln('====================================================') ; writeln(' RETURN sakatu amaitzeko') ; writeln('====================================================') ; readln ; end.
iruzkinik ez:
Argitaratu iruzkina
Iruzkinen bat idazteko Google-ko kontu bat behar duzu. Iruzkin guztien moderazio-ardura blogeko administratzaileari dagokio.