Errusiar Biderketaren Metodoa izenburuko artikulua gogoratuz, ariketa honetan bi zenbakiren arteko biderkadura kalkulatzen duen programa egingo dugu, baina biderketa burutzeko taulak arrayetan gordez.
TAULAREN NEURRIA ETA DATU-MOTA
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:
1 2 3 | 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:
1 2 3 4 5 6 7 8 9 10 11 | 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 *) ... |
TAULAREN JAKIN BATEN NEURRI EFEKTIBOA
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 224
Argi dago zutabeak beti 2 izango direla eta taularen neurri efektikoa errenkada baliagarriak kopuruak finkatuko duela (goiko adibidean 5).
ADIBIDE BAT
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.
PROGRAMAREN ITURBURU-KODEA
Arrayak darabilen Errusiar Biderketaren Metodoaren programa bat jarraian erakusten da:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 | { "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