2023(e)ko martxoaren 27(a), astelehena

10. astea | izen, abizen eta noten taula



asTaula hiru dimentsiotako taula bat da, kateak gorde ditzakeen asTaula arrayak 40 errenkada eta 3 zutabe ditu. Errenkada bakoitza ikasle bati dagokio: Errenkadaren lehen zutabean izena biltegitzen da, bigarrenean abizena eta hirugarren zutabean ikaslearen nota gordetzen da (hirurak string[19] datu-motakoak).



Taula baten dimentsioak zehazteko, bi indize behar dira: Indize bat lerro baliodunak zehazteko eta beste indize bat baliozko zutabeak adierazteko. Baina, asTaula arraya taula bat izan arren, array horren dimentsio efektiboa zenbaki oso batek adierazten du (hiru zutabeak beti beterik daudelako). Jarraian ematen den irudian, luzera efektiboaren lana errenkadak mugatzea dela ikusten da:



      iLuzeraTaula=5





































































asTaula
       1  
   2       3  
1    'Laura' 
   'Urioste' 
   '4.8'  
2     'Joseba'  
    'Salazar'  
   '6.333'  
3     'Irina'  
    'Belasko'  
   '5.666'  
4     'Patxi'  
    'Larrabe'  
  '9.1'  
5 'Jordi'
'Coll'
'4.25'
6      
7      
...
     
40      




Eskatzen da:



  • Nota guztien arteko batezbesteko aritmetikoa lortu: 



  • Noten batezbestekoarekin, desbideratze estandarra kalkulatu: 



  • Notarik txikiena eskuratu duen ikaslea nor da? 

  • Notarik handiena eskuratu duen ikaslea nor da? 

  • Aprobatuen array dimentsiobakar hau lortu: 



                iLuzeraAprob=3

































    asAprobatuak
1    'Salazar, Joseba' 
2     'Belasko, Irina'  
3     'Larrabe, Patxi'  
4
 
...
 
40  


 

10. astea | XYZ aretoaren tenperaturak

Demagun gela edo areto batean 22 gradu inguruko tenperatura dagoela, gelako puntu guztien tenperaturak ezagunak direla eta bektore batean gordeta daudela zenbaki erreal bezala. Puntu batetik besterako aldea txikia izanik, tenperatura guztiak 22 graduen inguruan daude. Hona hemen aretoaren eskema:



Datu-motak hauek izanik, ondoko bi eragiketak egin:


PROGRAM GelakoTenperaturak ;
CONST
X_MAX = 8 ;
Y_MAX = 8 ;
Z_MAX = 8 ;
TYPE
tarBolumena = ARRAY [1..X_MAX, 1..Y_MAX, 1..Z_MAX] OF Real ;


Bektorea aleatorioki datuz bete eta bektorearen edukia pantailaratu.



Aretoeren bolumen maximoa 8x8x8 izango da eta aretoaren puntu bakoitzaren koordenatua hiru zenbaki osoz adieraziko da, eta aretoaren puntu bakoitzari zenbaki ez-oso tenperatura bat dagokio. Adibidez, hurrego irudia begiratuz (1, 1, 8) puntuari 22.29 gradu dagozkio, eta(8, 8, 8) puntuari 22.15 graduko tenperatura dagokio.



Bektorean informazioa gordetzen eta ateratzen dakigula, ondoko hiru eragiketak egin:


  • Gelako zutabe bat aukeratu eta zutabe horretako punturik hotzena zehaztu

  • Gelako plano horizontal bat aukeratu eta plano horretako punturik hotzena zehaztu

  • Gelako punturik hotzena zehaztu


Adibidez, hona hemen programa exekutagarriaren balizko irteera zati bat:









Ariketaren planteamendua ulertuta eta programa exekutagarriaren irteera ikusita, zeure programa egitea eskatzen da. Ondoren, zure programa eta jarraian ematen den emaitza buruz buru jarri eta bakoitzaren alde onak eta alde ahulak ikusi:




 

10. astea | Errusiar Biderketaren Metodoa programatzen

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:



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 *)
...








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    34       7   
1    17  
   14   
2     8       28   
3     4       56   
4     2      112   
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:



{ "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.



 

10. astea | hainbat ezabaketa array batean

Array laguntzaile bat erabiliko dugu


Ezabaketa array batean algoritmoari esker, posizio jakin bateko elementua
arraytik ken daiteke, baina algoritmo hori zaila bihurtzen da elementu bat
baino gehiago kendu behar direnean. Array bateko zenbait elementu
ezabatzeko algoritmo hau erabiliko dugu: 06a_HainbatEzabaketa.pas non muga bat emanik elementu txikiak kentzen diren:



(* Algoritmo hau egitan ez da ezabaketa bat prozesaketa bat baizik *)
(* bektore laguntzaile bat erabiltzen da emaitza lortzeko. *)
program HainbatEzabaketaArrayetan_A ;

const
BEHEMUGA = 1 ;
GOIMUGA = 20 ;

type
tarZerrenda = array[BEHEMUGA..GOIMUGA] of real ;


procedure ArrayaBete(var arNotak: tarZerrenda;
var iLuzera: integer) ;
var
iIndizea: integer ;
begin
randomize ;
iLuzera := random(GOIMUGA) + 1 ;

writeln('Arrayan ', iLuzera, ' datu gordetzen') ;
for iIndizea:=BEHEMUGA to iLuzera do
begin
arNotak[iIndizea] := 10*random ; { 0.00 eta 9.99 arteko balioak }
end ;
end ;


procedure ArrayaIkusi(const arNotak: tarZerrenda;
iLuzera: integer) ;
var
iIndizea: integer ;
begin
writeln('Arrayaren edukia: ') ;
for iIndizea:=BEHEMUGA to iLuzera do
begin
writeln(iIndizea:2, '. nota = ', arNotak[iIndizea]:0:3) ;
end ;
writeln ;
end ;


{ array laguntzaile batean zenbaki handiak gorde eta amaitzean array laguntzailearen
informazio hori emaitza izango den parametrora eraman. Benetan ez da ezabaketa bat. }
procedure ArrayarenTxikiakEzabatu( var arNotak: tarZerrenda;
var iLuzera: integer;
rErreferentzia: real) ;
var
iIndizea, k: integer ;
arNotaHandiak: tarZerrenda;
begin
k := 0 ;
for iIndizea:=BEHEMUGA to iLuzera do
begin
if arNotak[iIndizea] > rErreferentzia then
begin
k := k + 1 ;
arNotaHandiak[k] := arNotak[iIndizea] ;
end ;
end ;
(* array berritua kanporatu, bere balio berriak eta luzera berria *)
arNotak := arNotaHandiak ;
iLuzera := k ;
end ;


{------------------------PROGRAMA NAGUSIA------------------------}

var
arNotak: tarZerrenda ;
iLuzera: integer ;
rErreferentzia: real ;
begin
ArrayaBete(arNotak, iLuzera) ;
ArrayaIkusi(arNotak, iLuzera) ;

writeln('Elementu txikiak arrayetik ezabatu') ;
write('Eman erreferentziaren balioa: ') ;
readln(rErreferentzia) ;

ArrayarenTxikiakEzabatu(arNotak, iLuzera, rErreferentzia) ;
ArrayaIkusi(arNotak, iLuzera) ;
readln ;
end.



 

2023(e)ko martxoaren 26(a), igandea

10. astea | mediana eta batezbestekoa




Gehienez 40 elementu gordetzeko gai den array batekin lan egingo dugu. Arrayaren elementuak zenbaki errealak izango dira.



Array zehatz honen datuek bi baldintza betetzen dituzte:




  1. Arrayaren datu guztiak desberdinak dira. Arraya betetzean, datua den zenbaki erreala arrayean gorde aurretik, frogatu beharra dago errepikaturik ez dela egongo. Horretarako, teoriako blogearen 9. astea | bilaketa sekuentzialaren aplikazio bat programara jo eta bertako BilaketaLineala izeneko funtzioa erabili gure behar izanetara egokituz, hots, beharko dituen moldapenak eginez

  2. Arrayaren datu guztiak ordenaturik daude. Arraya betetzean, datu berria dela frogatu ondoren, zein tokitan txertatuko den zehaztu beharra dago eta non txertatu dakiguka tartekaketaren algoritmoa aplikatu (gogoratu 10. astea | txertaketa array batean non elementu bat arrayaren posizio jakin batean tartekatzen den)



Zein da datuen rMed medianaren balioa? eta zein da datuen rBaBe batezbestekoaren balioa?



Mediana. Estatistikan, rMed mediana hainbat datu txikienetik handienera ordenaturik daudela, erdian dagoen datua da. Datu-kopurua bakoitia bada, denak ordenaturik daudela, rMed mediana erdiko datuak hartzen duen balioa da. Datu-kopurua bikoitia bada, datuak ordenaturik daudela, erdiko datu bi dagoenez, rMed mediana erdiko bi datu horien batezbestekoa dela esan daiteke (rMed aldagaiaren datu-mota real izango da).



Batezbestekoa. Batezbestekoaren balioa kalkulatzeko, rBaBe aldagaia erabiliko da (real datu-motakoa). Arrayak dituen balioen metekata egin ondoren, arrayaren elementu kopuruagatik zatiketa egingo da.























Arrayaren datu-mota eta arrayaren edukia


Arrayaren elementuak zenbaki errealak dira. Zehatzago hitz eginez, elementuen egitura hau da: 0 eta 9 arteko unitate bat, eta, 0 eta 9 arteko dezimal bat.



     program MedianaEtaBatezbestekoa ;
const
BEHEMUGA = 1 ;
GOIMUGA = 40 ;
type
tarZenbakienSorta = array[BEHEMUGA..GOIMUGA] of real ;
...


Arrayaren elementu guztiak desberdinak dira elkarrekiko, eta sailkaturik daude txikitik handira. Adibidez, hau izan daiteke 9 elementu dituen array baten edukia:



       balioak ===>     0.3   2.1   2.2   3.9   5.6   7.4   8.8   8.9   9.5
indizeak ===> 1 2 3 4 5 6 7 8 9








Programa nagusia


Programa nagusian array bat (eta bere luzera efektiboa) daukagu eta eskatzen diren mediana eta batezbesteko aritmetikoa kalulatzen dira.



{ =============================programa nagusia============================ }
var
arZenbakiak: tarZenbakienSorta ;
iLuzera: integer ;
rMed, rBaBe: real ;
begin
writeln ;
writeln ;

randomize ; (* ArrayaBete prozeduran random(10) funtzioa erabiltzen delako *)

ArrayaBete_DesberdinakEtaOrdenaturik(arZenbakiak, iLuzera) ;
writeln ;

writeln('Arrayaren edukia: ') ;
ArrayaIkusi(arZenbakiak, iLuzera) ;
writeln ;

rMed := fnrMedianaKalkulatu(arZenbakiak, iLuzera) ;
writeln('Mediana = ', rMed:0:2) ;
writeln ;

rBaBe := fnrBatezbestekoaKalkulatu(arZenbakiak, iLuzera) ;
writeln('Batezbestekoa = ', rBaBe:0:2) ;
writeln ;

writeln ;
writeln('====================================================') ;
writeln('RETURN sakatu amaitzeko ') ;
writeln('====================================================') ;
readln ;
end.








ArrayaBete_DesberdinakEtaOrdenaturik prozedura


Programaren eginkizun zailena ArrayaBete_DesberdinakEtaOrdenaturik prozedura honetan burutzen da, bere lana bikoitza da: 1) elementu desberdinak eta 2) ordenaturik gorde.



...
procedure ArrayaBete_DesberdinakEtaOrdenaturik(var arZenbakiak: tarZenbakienSorta;
var iLuzera: integer) ;
var
iKont, iUnitatea, iDezimala, iNonDago, iNonTxertatu: integer ;
rZbk: real ;
begin
iLuzera := random(GOIMUGA) + 1 ; (* 1 eta 40 arteko balioa *)

for iKont:=BEHEMUGA to iLuzera do
begin
repeat
iUnitatea := random(10) ; (* 0 eta 9 arteko balioa *)
iDezimala := random(10) ; (* 0 eta 9 arteko balioa *)

rZbk := iUnitatea*1.0 + iDezimala*0.1 ;

iNonDago := fniZenbakiaBilatu(arZenbakiak, iLuzera, rZbk) ;

if iNonDago <> 0 then
writeln('iKont = ', iKont:2, ' -------- ', rZbk:0:1, ' ----errepikatuta---- ', iNonDago:2, ' ----posizioan--------') ;

until iNonDago = 0 ; (* errepikatu elementu berria izan arte *)

iNonTxertatu := fniBerePosizioaAurkitu(arZenbakiak, iKont, rZbk) ;
//writeln('iNonTxertatu = ', iNonTxertatu) ;
ZbkTartekatu(arZenbakiak, iKont, rZbk, iNonTxertatu) ;
end ;
end ;
...


fniBerePosizioaAurkitu funtzioak bilaketa sekuentzialaren algoritmoa barneratzen du. Eta, ZbkTartekatu prozedurak elementu baten tartekataren algoritmoa barneratzen du.



Hona hemen MedianaEtaBatezbestekoa.pas programaren kodea eta bi exekuzioen balizko pantailaraketak:



Datu-kopurua bakoitia izatean


Datu-kopurua bikoitia izatean



 

10. astea | NAN baten letra kalkulatu



NAN batek zortzi zifra eta letra bat dauzka. Letra kalkulatzeko algoritmoa jarraian deskribatzen den hau da:




  1. NAN-aren zenbaki zati 23 egiten da hondarra eskuratzeko
  2. Zatiketa osoaren hondarra taula honetara ekarriz letra lortzen da: 




























































HONDARRA  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22
LETRA T R W A G M Y F P D X B N J Z S Q V H L C K E



Adibidez, NAN-aren zenbakia 12345678 bada, zati 23 eginez zatiketa osoa egin ondoren ateratzen hondarra 14 da, horregatik dagokion letra Z da.



Ariketaren balizko emaitza ikusi, non karaktereen array konstante bat erabiltzen den:



{-------------------------------------------------------------
NAN baten zifrak teklatuaren bitartez jaso kate batean eta
programak letra kalkulatu ondoren, NAN osoa pantailaratuko du
-------------------------------------------------------------}

program NANrenLetra ;

const
iZATITZAILEA = 23 ;

type
tsKate9 = string[9] ;
tacNANarenLetra = array[0..iZATITZAILEA-1] of char ;

const
acNANarenLetra: tacNANarenLetra = ( 'T', (* 0 *)
'R', (* 1 *)
'W', (* 2 *)
'A', (* 3 *)
'G', (* 4 *)
'M', (* 5 *)
'Y', (* 6 *)
'F', (* 7 *)
'P', (* 8 *)
'D', (* 9 *)
'X', (* 10 *)
'B', (* 11 *)
'H', (* 12 *)
'J', (* 13 *)
'Z', (* 14 *)
'S', (* 15 *)
'Q', (* 16 *)
'V', (* 17 *)
'H', (* 18 *)
'L', (* 19 *)
'C', (* 20 *)
'K', (* 21 *)
'E') ; (* 22 *)


function fnboDenakZifrak(sZifrak: tsKate9): boolean ;
var
boOndoDago: boolean ;
k: integer ;
begin
if length(sZifrak)=8 then
begin
boOndoDago := TRUE ;
for k:=1 to 8 do
begin
if (sZifrak[k] < '0') or (sZifrak[k] > '9') then
begin
boOndoDago := FALSE ;
writeln('Datuaren ':13, k, '. karakterea ez da zifra bat') ;
end ;
end ;
end
else
begin
boOndoDago := FALSE ;
writeln('Zortzi zifra izan behar dira':32) ;
end ;

fnboDenakZifrak := boOndoDago ;
end ;


function fncLetraLortu(sZifrak: tsKate9): char ;
var
liNANzenbakia: longint ;
iHondarra: integer ;
begin
val(sZifrak, liNANzenbakia) ;
//write('liNAN = ':12, liNANzenbakia) ;

iHondarra := liNANzenbakia mod iZATITZAILEA ;
//write('iHond. = ':13, iHondarra:2) ;

fncLetraLortu := acNANarenLetra[iHondarra] ;
end ;

(* -------------------------------------------------- *)

var
sZifrak: tsKate9 ;
sNANa: tsKate9 ;
cLetra: char ;
begin
writeln ;
repeat
writeln ;
write('NANren zortzi zifrak eman: ':31) ;
readln(sZifrak) ;
until fnboDenakZifrak(sZifrak) ;

//write('sZifrak = |':14, sZifrak, '|') ;

cLetra := fncLetraLortu(sZifrak) ;

sNANa := sZifrak + cLetra ;

writeln('NAN = ':10, sNANa) ;

writeln ;
write('ENTER sakatu exekuzioa amaitzeko... ') ;
readln ;
end.

10. astea | bilaketa bitarra array sailkatu/ordenatu batean











Bilaketa bitarraren zuhaitza osatzeko simuladorea







Enuntziatua


Demagun A bektorearen elementuak sailkaturik/ordenaturik daudela, gako ezagun bat zehaztu ondoren, balio hori aintzat harturik bektorea arakatu eta gakoarekin bat egiten duen lehen elementuari dagokion indizea aurkitu.





Ebazpena


Ebazpenak hiru urrats dituela onar daiteke.



Lehenengoan, bektorearen esparru baliagarria zehaztu behar da. asHiztegia bektorearen hasierako esparrua 1 behemuga eta iLuzera luzera efektiboaren bitartekoa izango da.



Ebazpenaren bigarren urratsean bektorearen esparru baliagarria erdibituz bi zatitan banatzen da, eta, esparruaren erdian dagoen elementuaren balioa gakoarekin alderaratzen da ondoko egoera bat gertatuz:


  • asHiztegia[Erdi] = sGakoa, hots, berdinak izatea, bilatzen ari ginen gakoa A bektorean aurkitzen da eta berari dagokion posizioa esparruaren erdiko elementuaren indizearena da

  • asHiztegia[Erdi] > sGakoa, hots, erdiko elementuaren balioa gakoa baino handiagoa bada, esparru baliagarria aldatu behar da: berria izango den esparruaren amaiera aurreko esparruaren erdia delarik (esparru berriaren hasiera ez da aldatzen). Beste modu batez esanda Eskn aldatu beharra dago

  • asHiztegia[Erdi] < sGakoa, hots, erdiko elementuaren balioa gakoa baino txikiagoa bada, esparru baliagarria aldatu behar da ere, baina orain: berria izango den esparruaren hasiera aurreko esparruaren erdia izanik (esparru berriaren bukaera ez da aldatzen). Beste modu batez esanda Ezkr aldatu beharra dago


Hirugarren urratsak ebazpenaren bigarren urratseko prozesu errepikakorraren irteerako kondizioarekin zerikusia du. Begizta bukatzeko, bi baldintza hauetatik bat betetzea aski da:


  1. bilaketa arrakastatsua: gakoa bektorean aurkitzea (esparru baliagarriaren erdiko elementuaren balioa eta gakoa berdinak direla frogatu da), edo bestela...

  2. ...bilaketa okerra: gakoa ez dago bektorean (esparru baliagarriak ez du elementurik barneratzen, esparruak duen goimuga bere behemuga baino txikiagoa delako)


Algoritmo hau programatzeko WHILE-DO eta REPEAT-UNTIL kontrol-egiturak proposatzen ditugu, ezin daiteke inolaz ere FOR-TO-DO egitura erabili.





Kodea


...
readln(sGakoa) ; { suposatuz sGakoa teklatuz irakurtzen dela }

boAurkitua := FALSE ; { hasieran oraindik ez dugu sGakoa aurkitu }
iEzkr := 1 ; { lehen indizea }
iEskn := iLuzera ; { luzera efektiboa }
repeat
iErdi := (iEzkr+iEskn) div 2 ;
if asHiztegia[iErdi] = sGakoa then
boAurkitua := TRUE
else
if asHiztegia[iErdi] > sGakoa then
iEskn := iErdi - 1
else
iEzkr := iErdi + 1 ;
until boAurkitua or (iEzkr > iEskn) ;

if boAurkitua then
writeln(sGakoa, '-ren lehen agerpena ', iErdi, ' posizioan ematen da')
else
writeln(sGakoa, ' ez da bektorean aurkitzen') ;
...






Eskema


Eskema hau jarraian datorren adibidearen exekuzio bati dagokio, kasu honetan yoyo gakoa ez da aurkituko:











Eskema hau adibidearen beraren beste exekuzio bati dagokio, kasu honetan uso gakoa aurkitu egingo da:















Adibidea: Hiztegia


Bektore bati esker hitzak gordeko ditugu memorian, bektoreari balioak ematean hitzen ordena alfabetikoa zainduko denez esan daiteke bektorea hiztegi bat dela.



Hiztegia datuz bete ondoren gako bat teklatuz irakurtzen da, adibide honetan gakoa hitz bat izango da noski.



Gakoaren lehen agerpena itzultzen duen funtzioak bilaketa bitarra darabil, gakoa bektorean aurkitzen denean funtzioak bere agerpen horri dagokion indizea itzuliko dio programa nagusiari, baina, gakoa bektorean ez dagoenaren egoera horretaz programa nagusia konturatu dadin funtzioak balio berezi bat itzultzen dio (posizioa ezin daitekeen izan balio berezia, adibidez 0).



Programa hauxe da:











Adibidea: Ikasleak


31. taldeko ikasleen zerrenda asGela31 bektorean gorderik daukagu. Bektorean datuak gordetzean hasieraketa bat egiten da (datuak ez dira teklatuz ematen). Bektorea beti beterik dagoelako bere luzera efektiboa GOIMUGA da.



asGela31 bektorearen edukia pantailaru ondoren ikus daiteke datuak alfabetikoki ordenaturik daudela. Beraz, ikasle baten bilaketa egiteko bilaketa bitarra egingo da.



Programa hauxe da: