2024(e)ko apirilaren 8(a), astelehena

25. Ariketa: fitxategiak (I)

ZER DAKIDAN:
Zenbakiak, karaktereak, kateak, zerrendak (arrayak) eta erregistroak lantzeko gai naiz.



ZER IKASIKO DUDAN:
Zer gertatzen da programaren exekuzioa bukatzean? Erabili diren aldagai guztien balioak galtzen direla. Datuak modu iraunkorrean gorde ahal izateko file datu-mota erabili behar da. Ariketa honetan fitxategi berri bat nola sortu ikasiko dut, eta lehendik existitzen den fitxategi bati elementu berriak nola gehitu ikasiko dut.




ESKATZEN DEN PROGRAMA 

Erregistroen fitxategi batekin lan egingo dugu. Fitxategiaren elementuak bi eremuko erregistroak izango dira. Lehen eremua ibilgailuaren matrikula izango da (matrikula guztien letrak BBB dira eta matrikula bakoitzaren  zifrak sekuentzialki doaz 0001etik hasita). Bigarren eremua ibilgailuaren aldiuneko abiadura izango da eta bere balioa auzaz lortuko dugu.

Gure programak fitxategiaren izena eskatuko du eta erabiltzaileak emandako sarrerarekin fitxategiaren existentzia konprobatuko du, ondoko bi bide irekiz:
  1. Fitxategia existitzen bada, bere edukia pantailaratuko da eta elementu berriak gehituko dira fitxategiaren amaieran. Horretarako, zenbat elementu beri gehituko diren eskatzen da eta erregistroak erdi auzaz bete ondoren fitxategian amaieran biltegitzen dira. Bukatzeko, fitxategia berrituaren edukia pantailaratzen da aldiuneko abiadura guztien batezbesteko aritmetikoa kalkulatzen da.
  2. Fitxategia existitzen ez bada, fitxategi berria sortuko da. Horretarako, zenbat elementu gordeko diren eskatzen da eta erregistroak erdi auzaz bete ondoren fitxategian biltegitzen dira. Bukatzeko, fitxategiaren edukia pantailaratzen da aldiuneko abiaduren batezbesteko aritmetikoa kalkulatzen da.
Erregistroaren egitura honako hau da:

1. eremua sMatrikula   8 karaktereko kate bat, kate desberdinak izango dira
  zerrendaren elementu guztientzat
2. eremua rAldiunekoAbiadura   zenbaki erreal bat

Hauxe da ariketaren programa:

{ 25. ariketa: auto bat radar atari azpitik igartzean ondoko datuak   }
{              jaso eta gordetzen dira fitxategi batean:              }

{     - Matrikula, karkatere-kate bat                                 }
{     - Aldi uneko abiadura, zenbaki erreal bat                       }
                       
{  Datuak erdi automatikoki lortuko dira: matrikulen letrak BBB dira  }
{  zifrak sekuentzialki doaz 0001etik hasita, abiaduren balioak auzaz }
{  sortuko dira. Ondorioz, matrikulak desberdinak izango dira.        }
 
{  Fitxategia existitzen ez bada, sortuko da eta datuz bete ondoren   }
{  bere edukia pantailaratuko da eta aldiuneko abiaduren batezbesteko }
{  aritmetikoaa kalkulatuko da. Fitxategia lehendik existitzen bada   }
{  bere uneko edukia pantailaratuko da, gero elementu berriak gehitu  }
{  ondoren berriro erakutsiko dira fitxategiaren eduki berria eta     }
{  abiaduren batezbesteko aritmetikoa.                                }                 

program Ariketa_25;

uses
   sysutils;    { fileExists() funtzioak behar duelako }
   
type
   tsKatea = string[250];          { fitxategiaren izen osoa luzea izan daitekeelako }
    
   tsKateMatrikula = string[8];    { ZZZZ-LLL formatuko matrikula }
              
   trdIbilgailua = record
                      sMatrikula        : tsKateMatrikula;
                      rAldiunekoAbiadura: real;
                   end;
    
   tfrdFitxategia = file of trdIbilgailua;


procedure IbilgailuarenInformazioaJaso(var rdIbilgailua: trdIbilgailua; i: integer);
var
   sMatrikulaZifra: tsKateMatrikula;
begin
   Str(i, sMatrikulaZifra) ;
   if i < 10 then
      sMatrikulaZifra := '000' + sMatrikulaZifra;
   if (i >= 10) and (i < 100) then
      sMatrikulaZifra := '00' + sMatrikulaZifra;
   if i >= 100 then
      sMatrikulaZifra := '0' + sMatrikulaZifra;
   rdIbilgailua.sMatrikula := sMatrikulaZifra + ' BBB';

   rdIbilgailua.rAldiunekoAbiadura := 50 + 130*random;   (* 50.0 eta 179.99 artean *)
end;


procedure IbilgailuarenInformazioaErakutsi(const rdIbilgailua: trdIbilgailua);
begin
   write(rdIbilgailua.sMatrikula:15); 
   write(rdIbilgailua.rAldiunekoAbiadura:14:2);      
   writeln;
end;


procedure FitxategiarenEdukiaErakutsi(sFitxIzen: tsKatea);
var
   fFitxategia: tfrdFitxategia;
   rdDatua: trdIbilgailua;
begin
   assign(fFitxategia, sFitxIzen);
   reset(fFitxategia);    {Fitxategia ireki baina barrukoa ez borratu!!!}

   writeln('Matrikula':38, 'Abiadura':14);
   writeln('---------':38, '--------':14);
   
   {Datuak kudeatu for bitartez}
   while not eof(fFitxategia) do  
   begin
      read(fFitxategia,rdDatua); {Irakurri eta hurrengora pasa}
      write(filePos(fFitxategia):10, '. elementua: ');
      IbilgailuarenInformazioaErakutsi(rdDatua);
   end;

   close(fFitxategia);     {Fitxategia itxi}
end;


procedure FitxategiaSortuEtaDatuzBete(sFitxIzen: tsKatea);
var
   fFitxategia: tfrdFitxategia;
   rdDatua: trdIbilgailua; 
   iZenbat, i: integer;
begin
   assign(fFitxategia, sFitxIzen);
   rewrite(fFitxategia);  {Fitxategia sortu, eta existitzekotan bere edukia borratu}

   write('Zenbat elementu izango ditu fitxategiak (adibidez 15): ');
   readln(iZenbat);
   
   randomize;
   for i:=1 to iZenbat do
   begin
      IbilgailuarenInformazioaJaso(rdDatua, i);
      write(fFitxategia, rdDatua); {fitxategian idatzi eta hurrengo elementura pasa}
   end;

   close(fFitxategia);      {fitxategia itxi}
end;


function fnsFitxategiarenAzkenElementukoMatrikulaLortu(sFitxIzen: tsKatea): tsKateMatrikula;
var
   fFitxategia: tfrdFitxategia;
   rdDatua: trdIbilgailua;
begin
   assign(fFitxategia, sFitxIzen);
   reset(fFitxategia);    {Fitxategia ireki baina barrukoa ez borratu!!!}

   seek(fFitxategia, fileSize(fFitxategia)-1);  {Fitxategiaren azken elementuaren gainean kokatu}
   read(fFitxategia, rdDatua);
   
   fnsFitxategiarenAzkenElementukoMatrikulaLortu := rdDatua.sMatrikula;
   
   close(fFitxategia);      {fitxategia itxi}
end ;

   
procedure FitxategiariDatuakGehitu(sFitxIzen: tsKatea);
var
   fFitxategia: tfrdFitxategia;
   rdDatua: trdIbilgailua; 
   iZenbat, i: integer;
   sMatrik, sMatrikulaZifra: tsKateMatrikula;
   iMatrikulaZifra: integer ;
begin
   sMatrik := fnsFitxategiarenAzkenElementukoMatrikulaLortu(sFitxIzen);
   sMatrikulaZifra := Copy(sMatrik, 1, 4);
   Val(sMatrikulaZifra, iMatrikulaZifra);
   
   assign(fFitxategia, sFitxIzen);
   reset(fFitxategia);                        {Fitxategia ireki baina barrukoa ez borratu!!!}
   seek(fFitxategia, fileSize(fFitxategia));  {Fitxategiaren bukaeran kokatu}
   
   write('Zenbat elementu gehituko dira fitxategira (adibidez 7): ');
   readln(iZenbat);
   
   for i:=iMatrikulaZifra+1 to iMatrikulaZifra+iZenbat do
   begin
      IbilgailuarenInformazioaJaso(rdDatua, i);
      write(fFitxategia, rdDatua);   {fitxategian idatzi eta hurrengo elementura pasa}
   end;

   close(fFitxategia);      {fitxategia itxi}
end;


function fnrBatezbestekoAbiaduraKalkulatu(sFitxIzen : tsKatea) : real;
var
   fFitxategia: tfrdFitxategia;
   rdDatua: trdIbilgailua;
   rMetatua: real;
begin
   assign(fFitxategia, sFitxIzen);
   reset(fFitxategia);    {Fitxategia ireki baina barrukoa ez borratu!!!}

   rMetatua := 0.0;
   while not eof(fFitxategia) do  
   begin
      read(fFitxategia,rdDatua); {Irakurri eta hurrengora pasa}
      rMetatua := rMetatua + rdDatua.rAldiunekoAbiadura;
   end;
   
   fnrBatezbestekoAbiaduraKalkulatu := rMetatua / fileSize(fFitxategia);
      
   close(fFitxategia);      {fitxategia itxi}
end ;

(* ---------------------- PROGRAMA NAGUSIA ---------------------- *)
    
var
   sFitxIzen: tsKatea;
   sBidea: tsKatea;
   rAbiadurenBBA: real;
begin
   writeln;
   writeln;
   writeln;
   
   //sBidea := 'C:\Radarrak\';                              (* Windows *)
   sBidea := '/Users/jesusromouriarte/Desktop/Radarrak/';   (* Mac *)   

   writeln('Ibilgailuen informazioa gordeko duen fitxategiaren izena eman ezazu.');
   write('Adibidez, ''Autoak.dat'' izena: ');
   readln(sFitxIzen); 
   sFitxIzen := sBidea + sFitxIzen;
   writeln;
   
   if fileExists(sFitxIzen) then     {konprobatu ea existitzen den ala ez}
   begin
      writeln(sFitxIzen, ' fitxategia existitzen da.');
      writeln('Hona hemen bere edukia:');
      FitxategiarenEdukiaErakutsi(sFitxIzen);
      rAbiadurenBBA := fnrBatezbestekoAbiaduraKalkulatu(sFitxIzen);
      writeln('Aldiuneko abiaduren batezbesteko aritmetikoa: ', rAbiadurenBBA:0:2, ' Km/h');
      writeln;
      
      writeln('Elementu berriak gehituko dira:');
      FitxategiariDatuakGehitu(sFitxIzen);
      FitxategiarenEdukiaErakutsi(sFitxIzen);
      rAbiadurenBBA := fnrBatezbestekoAbiaduraKalkulatu(sFitxIzen);
      writeln('Aldiuneko abiaduren batezbesteko aritmetikoa: ', rAbiadurenBBA:0:2, ' Km/h');
   end
   else
   begin
      writeln(sFitxIzen, ' fitxategirik ez dago.');
      writeln('Oraintxe sortuko dugu.');
      FitxategiaSortuEtaDatuzBete(sFitxIzen);      
      writeln('Sortutako fitxategiaren edukia:');
      FitxategiarenEdukiaErakutsi(sFitxIzen);
      rAbiadurenBBA := fnrBatezbestekoAbiaduraKalkulatu(sFitxIzen);
      writeln('Aldiuneko abiaduren batezbesteko aritmetikoa: ', rAbiadurenBBA:0:2, ' Km/h');
   end;

   writeln;
   write('RETURN sakatu programa bukatzeko');
   writeln;
   readln;
end.

Programaren balizko bi exekuzio hurrrengo irudietan erakusten dira, aurreneko exekuzioan Autoak.dat fitxategia sortzen da lehen aldiz eta bigarren exekuzioan Autoak.dat izena berriro ematean 5 elementu gehitzen dira:



 

24. Ariketa: erregistroak (III)

ZER DAKIDAN:
Zenbakiak, karaktereak, kateak, zerrendak (arrayak) eta erregistroak lantzeko gai naiz.



ZER IKASIKO DUDAN:
Erregistroen array batean ondoko operazioak nola egiten diren ikasiko dut:
  • Array datu-motako aldagai bateko elementuak erregistroak izanik, elementu guztiak desberdinak direla kontrolatu (18. Ariketa: zerrendak (I) gogoratu)
  • Array datu-motako aldagai bateko elementuak erregistroak izanik, beste array bat lortu eremu baten arabera sailkaturik
  • Array datu-motako aldagai bateko elementuak erregistroak izanik, beste array bat lortu bi eremuren arabera sailkaturik
Bestalde, arrayekin bezala, FUNCTION erako azpiprograma batek ez du Record datu-motako egitura bat itzuliko. Horregatik, erregistro bat emaitza izan behar bada beti PROCEDURE erako azpiprogramaz prozesatuko dugu.




ESKATZEN DEN PROGRAMA 

Erregistroekin lan eginez, 1 eta 30 arteko erregistroen sorta bat zerrenda batean gorde nahi da. Erregistro bakoitzak ibilgailu baten datuak bilduko ditu.

Gure programak lehenik zenbat erregistro gordeko dituen galdetuko du eta prozesu errepikakor batean sartuko da. Gero, prozesu errepikakor barruan, erregistro bakoitzaren eremuentzat balioak auzaz aukeratu (sMatrikula eremuetako balioak ez direla errepikatzen konprobatuko da) eta erregistroa bete ondoren zerrendan gordeko da.

Erregistroaren egitura honako hau da:

1. eremua sMatrikula   8 karaktereko kate bat, 'ZZZZ LLL' formatuko kate
  desberdinak izango dira zerrendaren elementu guztientzat
2. eremua cIbilgailuMota   karaktere bat
3. eremua rAldiunekoAbiadura   zenbaki erreal bat

Hauxe da ariketaren programa:

{ 24. ariketa: auto bat radar atari azpitik igartzean ondoko datuak   }
{              jaso eta gordetzen dira zerrenda batean:               }

{     - Matrikula, karkatere-kate bat                                 }
{     - Ibilgailu mota, karaktere bat                                 } 
{     - Aldi uneko abiadura, zenbaki erreal bat                       }
                       
{  Datuak erdi automatikoki lortuko dira auzazko balioak sortuz.      }
{  Matrikula bereko autoak ez direlako onartzen, matrikula jakin bat  }
{  sortzean zerrendan berria izango dela frogatu beharra dago.        } 
{  ardZerrenda lehen zerrendatik abiatuta beste hiru zerrenda lortuko }
{  dira:                                                              }                   

{     - ardZerrenda_Mat matrikulen arabera sailkaturiko zerrenda      }
{     - ardZerrenda_Abi abiaduren arabera sailkaturiko zerrenda       }
{     - ardZerrenda_MotMat ibilgailu motaren arabera sailkaturiko     }
{       zerrenda eta mota berekoen elementuak matrikulaz sailkaturik  }

program Ariketa_24 ;

const
   BEHEMUGA = 1 ;
   GOIMUGA = 30 ;
   
type
    tsKateMatrikula = string[8] ;    { ZZZZ-LLL formatuko matrikula }
              
    trdIbilgailua = record
                       sMatrikula         : tsKateMatrikula ;
                       cIbilgailuMota     : char ;
                       rAldiunekoAbiadura : real ;
                    end ;
    
    tardZerrenda = array[BEHEMUGA..GOIMUGA] of trdIbilgailua ;


procedure IbilgailuarenDatuakJaso(var rdIbilgailua: trdIbilgailua) ;
var
   iZenbat, iAusazkoa, iKont, k : integer ;
   sMatrikula, sMatrikulaZifra : tsKateMatrikula ;
begin
   iZenbat := 15 + random(16) ;    
   for iKont:=1 to iZenbat do
   begin
      sMatrikula := '' ;
      for k:=1 to 4 do
      begin
         iAusazkoa := random(10) ;
         Str(iAusazkoa, sMatrikulaZifra) ;
         sMatrikula := sMatrikula + sMatrikulaZifra ;        
      end ;

      iAusazkoa := random(5) ;
      case iAusazkoa of
         0: rdIbilgailua.sMatrikula := sMatrikula + ' KHS' ;
         1: rdIbilgailua.sMatrikula := sMatrikula + ' BPK' ;
         2: rdIbilgailua.sMatrikula := sMatrikula + ' KKK' ;
         3: rdIbilgailua.sMatrikula := sMatrikula + ' XYZ' ;
         4: rdIbilgailua.sMatrikula := sMatrikula + ' KGB' ;
      end ;

      iAusazkoa := random(4) ;
      case iAusazkoa of
         0: rdIbilgailua.cIbilgailuMota := 'A' ;
         1: rdIbilgailua.cIbilgailuMota := 'B' ;
         2: rdIbilgailua.cIbilgailuMota := 'C' ;
         3: rdIbilgailua.cIbilgailuMota := 'D' ;
      end ;

      rdIbilgailua.rAldiunekoAbiadura := 50 + random(131) ;   (* 50.0 eta 180.0 artean *)
   end ;
end ;


{ Bilaketa gauzatzeko funtzioan while-DO egitura erabiltzen da }
function fniMatrikulaZerrendanBilatu(const ardZerrenda: tardZerrenda; iZenbat: integer; sMatrik: tsKateMatrikula): integer ;
var
   iIndizea : integer ;
   boAurkitua : boolean ;
begin
   iIndizea := BEHEMUGA ;
   boAurkitua := FALSE ;
   while (iIndizea <= iZenbat) and not boAurkitua do
   begin
      if ardZerrenda[iIndizea].sMatrikula = sMatrik then
         boAurkitua := TRUE
      else
         iIndizea := iIndizea + 1 ;
   end ;

   if boAurkitua = TRUE then
     fniMatrikulaZerrendanBilatu := iIndizea
   else
     fniMatrikulaZerrendanBilatu := 0 ;          { 0 gezurrezko posizioa litzateke }
end ;


procedure ZerrendaDatuDesberdinezBete(var ardZerrenda: tardZerrenda; iLuzera: integer) ;
var
   iIndizea, iPosizioa : integer ;
   rdIbilgailua : trdIbilgailua ;
begin 
   randomize ; 
   IbilgailuarenDatuakJaso(rdIbilgailua) ;
   ardZerrenda[BEHEMUGA] := rdIbilgailua ;   { Lehen matrikula beti izango da berria }
   
   for iIndizea:=BEHEMUGA+1 to iLuzera do
   begin
      repeat
         IbilgailuarenDatuakJaso(rdIbilgailua) ;
         iPosizioa :=  fniMatrikulaZerrendanBilatu(ardZerrenda, iIndizea-1, rdIbilgailua.sMatrikula) ;
      
         if iPosizioa <> 0 then
            writeln(iIndizea:6, '. ibilgailurako: ''', rdIbilgailua.sMatrikula, ''' matrikula ', iPosizioa, '. posizioan dago!!!')
         else
            ardZerrenda[iIndizea] := rdIbilgailua ;
      until iPosizioa = 0 ;
   end ;
end ;


(* Parametro bat irteerakoa den bitartean bestea sarrerakoa *)
(* da. Horregatik   arraya erreferentziaz pasatzen da baina *)
(* aldatzen ez den N iLuzera logikoari dagokion osoa balioz *)
procedure ZerrendaMatrikulazSailkatu(var ardZerrenda_Mat: tardZerrenda; N: integer) ;
var
   Pos, j, k : integer ;
   rdMinimoa : trdIbilgailua ;
begin
   for k:=1 to N-1 do         (* N-1 zergatia hau da:    alde desordenatuan *)
   begin                      (* elementu bakarra dagoenean bera da minimoa *)
      rdMinimoa := ardZerrenda_Mat[k] ;
      Pos := k ;
      for j:=k+1 to N do                        (* ordenatu gabekoen artean *)
      begin
         if rdMinimoa.sMatrikula > ardZerrenda_Mat[j].sMatrikula then   (* minimoa aurkitu *)
         begin
            rdMinimoa := ardZerrenda_Mat[j] ;
            Pos := j ;
         end ;
      end ;                                            (* k posizioan txikiena jarri  *)
        ardZerrenda_Mat[Pos] := ardZerrenda_Mat[k] ;   (* txikiena rdMinimoa da eta Pos posizioan dago *)
        ardZerrenda_Mat[k] := rdMinimoa ;              (* k posiziokoa libratu ondoren bere edukia Pos *)
   end;                                                (* posizioan gordez k posizioan rdMinimoa jarri *)
end ;


(* Parametro bat irteerakoa den bitartean bestea sarrerakoa *)
(* da. Horregatik arraya erreferentziaz pasatzen da baina   *)
(* aldatzen ez den N iLuzera logikoari dagokion osoa balioz *)
procedure ZerrendaAbiadurazSailkatu(var ardZerrenda_Abi: tardZerrenda; N: integer) ;
var
   Pos, j, k : integer ;
   rdMaximoa : trdIbilgailua ;
begin
   for k:=1 to N-1 do         (* N-1 zergatia hau da:    alde desordenatuan *)
   begin                      (* elementu bakarra dagoenean bera da minimoa *)
      rdMaximoa := ardZerrenda_Abi[k] ;
      Pos := k ;
      for j:=k+1 to N do                        (* ordenatu gabekoen artean *)
      begin
         if rdMaximoa.rAldiunekoAbiadura < ardZerrenda_Abi[j].rAldiunekoAbiadura then   (* maximoa aurkitu *)
         begin
            rdMaximoa := ardZerrenda_Abi[j] ;
            Pos := j ;
         end ;
      end ;                                          (* k posizioan handiena jarri  *)
      ardZerrenda_Abi[Pos] := ardZerrenda_Abi[k] ;   (* handiena rdMaximoa da eta Pos posizioan dago *)
      ardZerrenda_Abi[k] := rdMaximoa ;              (* k posiziokoa libratu ondoren bere edukia Pos *)
   end;                                              (* posizioan gordez k posizioan rdMaximoa jarri *)
end ;


(* Parametro bat irteerakoa den bitartean bestea sarrerakoa *)
(* da. Horregatik arraya erreferentziaz pasatzen da baina   *)
(* aldatzen ez den N iLuzera logikoari dagokion osoa balioz *)
procedure ZerrendaMotazMatrikulazSailkatu(var ardZerrenda_MotMat: tardZerrenda; N: integer) ;
var
   Pos, j, k : integer ;
   rdMinimoa : trdIbilgailua ;
begin
   for k:=1 to N-1 do         (* N-1 zergatia hau da:    alde desordenatuan *)
   begin                      (* elementu bakarra dagoenean bera da minimoa *)
      rdMinimoa := ardZerrenda_MotMat[k] ;
      Pos := k ;
      for j:=k+1 to N do                        (* ordenatu gabekoen artean *)
      begin
         if (rdMinimoa.cIbilgailuMota > ardZerrenda_MotMat[j].cIbilgailuMota) or     (* minimo nagusia aurkitu   *)
            ((rdMinimoa.cIbilgailuMota = ardZerrenda_MotMat[j].cIbilgailuMota) and   (* eta berdina denean beste *)
             (rdMinimoa.sMatrikula > ardZerrenda_MotMat[j].sMatrikula)) then         (* bigarren minimoa aurkitu *)
         begin                                                                    
            rdMinimoa := ardZerrenda_MotMat[j] ;
            Pos := j ;
         end ;
      end ;                                                (* k posizioan txikiena jarri  *)
      ardZerrenda_MotMat[Pos] := ardZerrenda_MotMat[k] ;   (* txikiena rdMinimoa da eta Pos posizioan dago *)
      ardZerrenda_MotMat[k] := rdMinimoa ;                 (* k posiziokoa libratu ondoren bere edukia Pos *)
   end;                                                    (* posizioan gordez k posizioan rdMinimoa jarri *)
end ;


procedure IbilgailuarenDatuakErakutsi(const rdIbilgailua: trdIbilgailua) ;
begin
   write(rdIbilgailua.sMatrikula:15) ;
   write(rdIbilgailua.cIbilgailuMota:9) ; 
   write(rdIbilgailua.rAldiunekoAbiadura:14:2) ;      
   writeln ;
end ;


procedure ZerrendaIkusi(const ardZerrenda: tardZerrenda; iLuzera: integer) ;
var
   k : integer ;
   rdIbilgailua : trdIbilgailua ;
begin  
   writeln('Matrikula     Mota':28, 'Abiadura':14) ;
   writeln('---------     ----':28, '--------':14) ;
   for k:=BEHEMUGA to iLuzera do
   begin
      write(k:4) ;
      rdIbilgailua := ardZerrenda[k] ;
      IbilgailuarenDatuakErakutsi(rdIbilgailua) ;
   end ;
end ;

(* ---------------------- PROGRAMA NAGUSIA ---------------------- *)
    
var
   ardZerrenda, ardZerrenda_Mat, ardZerrenda_Abi, ardZerrenda_MotMat: tardZerrenda ;
   iLuzera: integer ;
begin
   writeln ;
   writeln ;
   writeln ;
   
   repeat
      write('Zenbat elementu izango dira (', BEHEMUGA, ' eta ', GOIMUGA, ' arteko balioa): ') ;
      readln(iLuzera) ;
   until (iLuzera >= BEHEMUGA) and (iLuzera <= GOIMUGA) ;
   writeln ;
   
   writeln('IBILGAILUEN DATUAK ESKURATZEN (ardZerrenda)') ;
   ZerrendaDatuDesberdinezBete(ardZerrenda, iLuzera) ;
   writeln ;
   
   writeln('IBILGAILUEN DATUAK ERAKUSTEN (ardZerrenda)') ;
   ZerrendaIkusi(ardZerrenda, iLuzera) ;
   writeln ;
   
   ardZerrenda_Mat := ardZerrenda ;
   writeln('IBILGAILUEN DATUAK MATRIKULAZ SAILKATZEN...') ;   
   ZerrendaMatrikulazSailkatu(ardZerrenda_Mat, iLuzera) ;

   writeln('IBILGAILUEN DATUAK ERAKUSTEN (ardZerrenda_Mat)') ;
   ZerrendaIkusi(ardZerrenda_Mat, iLuzera) ;
   writeln ;

   ardZerrenda_Abi := ardZerrenda ;
   writeln('IBILGAILUEN DATUAK ABIADURAZ SAILKATZEN...') ;   
   ZerrendaAbiadurazSailkatu(ardZerrenda_Abi, iLuzera) ;
   
   writeln('IBILGAILUEN DATUAK ERAKUSTEN (ardZerrenda_Abi)') ;
   ZerrendaIkusi(ardZerrenda_Abi, iLuzera) ;
   writeln ;
      
   ardZerrenda_MotMat := ardZerrenda ;
   writeln('IBILGAILUEN DATUAK MOTAZ ETA MATRIKULAZ SAILKATZEN...') ;   
   ZerrendaMotazMatrikulazSailkatu(ardZerrenda_MotMat, iLuzera) ;

   writeln('IBILGAILUEN DATUAK ERAKUSTEN (ardZerrenda_MotMat)') ;
   ZerrendaIkusi(ardZerrenda_MotMat, iLuzera) ;
   writeln ; 
      
   readln ;
end.

Programaren balizko exekuzio bat hurrrengo irudietan erakusten da:

ardZerrenda arrayaren 500 elementuak eskuratu dira eta horietarik lehen 20ak pantailaratu dira

Matrikulen araberako sailkapena: ardZerrenda arrayatik abiatuta ardZerrenda_Mat array ordenatua lortu da

Abiaduren araberako sailkapena: ardZerrenda arrayatik abiatuta ardZerrenda_Abi array ordenatua lortu da

Sailkapenaren eremu nagusia cIbilgailuMota eta sMatrikula sailkapenaren bigarren mailako eremua: ardZerrenda arrayatik abiatuta ardZerrenda_MotMat array ordenatua lortu da

 

23. Ariketa: erregistroak (II)

ZER DAKIDAN:
Zenbakiak, karaktereak, kateak, zerrendak (arrayak) eta erregistroak lantzeko gai naiz.



ZER IKASIKO DUDAN:
Oinarrizko datu-mota desberdinak egitura bakar batean gordetzeko Record datu-mota beharrezkoa da. Oinarrizko datu-mota bereko hainbat elementu gordetzeko Array datu-mota aproposa da. Ikas dezagun orain erregistroen zerrendekin lan egiten.




ESKATZEN DEN PROGRAMA 

Erregistroekin lan eginez, 1 eta 10 arteko erregistroen sorta bat zerrenda batean gorde nahi da. Erregistro bakoitzak ibilgailu baten datuak bilduko ditu.

Gure programak lehenik zenbat erregistro gordeko dituen galdetuko du eta prozesu errepikakor batean sartuko da. Gero, prozesu errepikakor barruan, erregistro bakoitzaren eremuentzat balioak auzaz aukeratu eta erregistroa bete ondoren zerrendan gordeko da.

Erregistroaren egitura honako hau da:

1. eremua sMatrikula   'ZZZZ-LLL' formatuko 8 karakteredun kate bat
2. eremua cIbilgailuMota   karaktere bat
3. eremua rdDataUnea   2 eremuko erregistroa (eremu bakoitza 3 osoen array bat)
4. eremua rAldiunekoAbiadura   zenbaki erreal bat

Hauxe da ariketaren programa:

{ 23. ariketa: auto bat radar atari azpitik igartzean ondoko datuak   }
{              jaso eta gordetzen dira zerrenda batean:               }

{     - Matrikula, karkatere-kate bat                                 }
{     - Ibilgailu mota, karaktere bat                                 }
{     - Data, 3 zenbakien array bat (posizioak: Urtea, Hilea, Eguna)  }
{     - Unea, 3 zenbakien array bat (posizioak: Orduak, Minutuak,     } 
{                                                        Segundoak)   }  
{     - Aldi uneko abiadura, zenbaki erreal bat                       }
                       
{  Datuak erdi automatikoki lortuko dira auzazko balioak sortuz. Auto }
{  bakoitzeko erregistro bat bete ondoren, array batean gordeko da.   }                   

program Ariketa_23 ;

const
   BEHEMUGA = 1 ;
   GOIMUGA = 10 ;
   
type
    tsKateMatrikula = string[8] ;    { ZZZZ-LLL formatuko matrikula }

    taiData = array[1..3] of integer ;  { Urtea, Hilea, Eguna }
    
    taiUnea = array[1..3] of integer ;  { Orduak, Minutuak, Segundoak }
    
    trdNoiz = record
                  Eguna : taiData ;
                  Ordua : taiUnea ;
              end ;
              
    trdIbilgailua = record
                       sMatrikula         : tsKateMatrikula ;
                       cIbilgailuMota     : char ;
                       rdDataUnea         : trdNoiz ;
                       rAldiunekoAbiadura : real ;
                    end ;
    
    tardZerrenda = array[BEHEMUGA..GOIMUGA] of trdIbilgailua ;


procedure IbilgailuarenDatuakJaso(var rdIbilgailua: trdIbilgailua) ;
var
   iZenbat, iAusazkoa, iKont, k : integer ;
   sMatrikula, sMatrikulaZifra : tsKateMatrikula ;
begin
   iZenbat := 15 + random(16) ;    
   for iKont:=1 to iZenbat do
   begin
      sMatrikula := '' ;
      for k:=1 to 4 do
      begin
         iAusazkoa := random(10) ;
         Str(iAusazkoa, sMatrikulaZifra) ;
         sMatrikula := sMatrikula + sMatrikulaZifra ;        
      end ;

      iAusazkoa := random(5) ;
      case iAusazkoa of
         0: rdIbilgailua.sMatrikula := sMatrikula + ' KHS' ;
         1: rdIbilgailua.sMatrikula := sMatrikula + ' BPK' ;
         2: rdIbilgailua.sMatrikula := sMatrikula + ' KKK' ;
         3: rdIbilgailua.sMatrikula := sMatrikula + ' XYZ' ;
         4: rdIbilgailua.sMatrikula := sMatrikula + ' KGB' ;
      end ;

      iAusazkoa := random(4) ;
      case iAusazkoa of
         0: rdIbilgailua.cIbilgailuMota := 'A' ;
         1: rdIbilgailua.cIbilgailuMota := 'B' ;
         2: rdIbilgailua.cIbilgailuMota := 'C' ;
         3: rdIbilgailua.cIbilgailuMota := 'D' ;
      end ;

      rdIbilgailua.rdDataUnea.Eguna[1] := 2021 ;              (* 2021-01-01 eta 2021-12-28 artean *)  
      rdIbilgailua.rdDataUnea.Eguna[2] := 1 + random(12) ;
      rdIbilgailua.rdDataUnea.Eguna[3] := 1 + random(27) ;

      rdIbilgailua.rdDataUnea.Ordua[1] := 13 ;                (* 13:05:00 eta 13:15:59 artean *)
      rdIbilgailua.rdDataUnea.Ordua[2] := 5 + random(11) ;
      rdIbilgailua.rdDataUnea.Ordua[3] := random(60) ;

      rdIbilgailua.rAldiunekoAbiadura := 50 + random(131) ;   (* 50.0 eta 180.0 artean *)
   end ;
end ;


procedure ZerrendaBete(var ardZerrenda: tardZerrenda; iLuzera: integer) ;
var
   k : integer ;
   rdIbilgailua : trdIbilgailua ;
begin  
   randomize ; 
   for k:=BEHEMUGA to iLuzera do
   begin
      writeln(k:4, '. ibilgailuaren datuak eskuratzen...') ;
      IbilgailuarenDatuakJaso(rdIbilgailua) ;
      ardZerrenda[k] := rdIbilgailua ;
   end ;
end ;


procedure IbilgailuarenDatuakErakutsi(const rdIbilgailua: trdIbilgailua) ;
begin
   writeln('Matrikula     Mota':24, 'Data':16, 'Ordua':16, 'Abiadura':14) ;
   writeln('---------     ----':24, '----------':16, '----------':16, '--------':14) ;
   write(rdIbilgailua.sMatrikula:15) ;
   write(rdIbilgailua.cIbilgailuMota:9) ;
   
   write(rdIbilgailua.rdDataUnea.Eguna[1]:10, '-') ;
   if rdIbilgailua.rdDataUnea.Eguna[2] >= 10 then
      write(rdIbilgailua.rdDataUnea.Eguna[2]:2, '-')
   else
      write('0', rdIbilgailua.rdDataUnea.Eguna[2], '-') ;   
   if rdIbilgailua.rdDataUnea.Eguna[3] >= 10 then
      write(rdIbilgailua.rdDataUnea.Eguna[3]:2)
   else
      write('0', rdIbilgailua.rdDataUnea.Eguna[3]) ;
   
   write(rdIbilgailua.rdDataUnea.Ordua[1]:10, ':') ; 
   if rdIbilgailua.rdDataUnea.Ordua[2] >= 10 then
      write(rdIbilgailua.rdDataUnea.Ordua[2]:2, ':')
   else
      write('0', rdIbilgailua.rdDataUnea.Ordua[2], ':') ;
   if rdIbilgailua.rdDataUnea.Ordua[3] >= 10 then
      write(rdIbilgailua.rdDataUnea.Ordua[3]:2)
   else
      write('0', rdIbilgailua.rdDataUnea.Ordua[3]) ;
      
   write(rdIbilgailua.rAldiunekoAbiadura:14:2) ;      
   writeln ;
   writeln ;
end ;


procedure ZerrendaIkusi(const ardZerrenda: tardZerrenda; iLuzera: integer) ;
var
   k : integer ;
   rdIbilgailua : trdIbilgailua ;
begin  
   for k:=BEHEMUGA to iLuzera do
   begin
      writeln(k:4, '. ibilgailuaren datuak:') ;
      rdIbilgailua := ardZerrenda[k] ;
      IbilgailuarenDatuakErakutsi(rdIbilgailua) ;
   end ;
end ;

(* ---------------------- PROGRAMA NAGUSIA ---------------------- *)
    
var
   ardZerrenda: tardZerrenda ;
   iLuzera: integer ;
begin
   writeln ;
   writeln ;
   writeln ;
   
   repeat
      write('   Zenbat elementu izango dira (', BEHEMUGA, ' eta ', GOIMUGA, ' arteko balioa): ') ;
      readln(iLuzera) ;
   until (iLuzera >= BEHEMUGA) and (iLuzera <= GOIMUGA) ;

   writeln ;
   ZerrendaBete(ardZerrenda, iLuzera) ;
   
   writeln ;
   ZerrendaIkusi(ardZerrenda, iLuzera) ;

   readln ;
end.

Programaren balizko exekuzio bat hurrrengo irudian erakusten da:


 

22. Ariketa: erregistroak (I)

ZER DAKIDAN:
Zenbakiak, karaktereak, kateak eta zerrendak (arrayak) lantzeko gai naiz.



ZER IKASIKO DUDAN:
Oinarrizko datu-mota desberdinak egitura bakar batean antolatzen eta gordetzen ikasiko dut, horretarako Record datu-mota funtsezkoa da. Erregistro batek hainbat eremu izango ditu, adibidez: demagun rdFitxa aldagaia erregistro bat dela eta bere eremu baten identifikadorea iAdina dela, eremu horren erreferentzia egiteko ondoko hau idatzi beharko da rdFitxa.iAdina non puntua lokailu berezia den.




ESKATZEN DEN PROGRAMA 

Erregistro baten eremuak datuz bete eta erregistroaren edukia pantailaratzea. Ariketaren erregistroak ibilgailu baten datuak bilduko ditu.

Erregistroaren egitura honako hau da:

1. eremua sMatrikula   'ZZZZ-LLL' formatuko 8 karakteredun kate bat
2. eremua cIbilgailuMota   karaktere bat
3. eremua rdDataUnea   2 eremuko erregistroa (eremu bakoitza 3 osoen array bat)
4. eremua rAldiunekoAbiadura   zenbaki erreal bat

Hauxe da ariketaren programa:

{ 22. ariketa: auto bat radar atari azpitik igartzean ondoko datuak   }
{              jaso eta gordetzen dira erregistro aldagai batean:     }

{     - Matrikula, karkatere-kate bat                                 }
{     - Ibilgailu mota, karaktere bat                                 }
{     - Data, 3 zenbakien array bat (posizioak: Urtea, Hilea, Eguna)  }
{     - Unea, 3 zenbakien array bat (posizioak: Orduak, Minutuak,     } 
{                                                        Segundoak)   }  
{     - Aldi uneko abiadura, zenbaki erreal bat                       }
                       
{  Datuak erdi automatikoki lortuko dira auzazko balioak aukeratuz.   }                   

program Ariketa_22 ;
   
type
    tsKateMatrikula = string[8] ;    { ZZZZ-LLL formatuko matrikula }

    taiData = array[1..3] of integer ;  { Urtea, Hilea, Eguna }
    
    taiUnea = array[1..3] of integer ;  { Orduak, Minutuak, Segundoak }
    
    trdNoiz = record
                  Eguna : taiData ;
                  Ordua : taiUnea ;
              end ;
              
    trdIbilgailua = record
                       sMatrikula         : tsKateMatrikula ;
                       cIbilgailuMota     : char ;
                       rdDataUnea         : trdNoiz ;
                       rAldiunekoAbiadura : real ;
                    end ;


procedure IbilgailuarenDatuakJaso(var rdIbilgailua: trdIbilgailua) ;
var
   iZenbat, iAusazkoa, iKont, k : integer ;
   sMatrikula, sMatrikulaZifra : tsKateMatrikula ;
begin
   randomize ;
   iZenbat := 15 + random(16) ;    
   for iKont:=1 to iZenbat do
   begin
      sMatrikula := '' ;
      for k:=1 to 4 do
      begin
         iAusazkoa := random(10) ;
         Str(iAusazkoa, sMatrikulaZifra) ;
         sMatrikula := sMatrikula + sMatrikulaZifra ;        
      end ;

      iAusazkoa := random(5) ;
      case iAusazkoa of
         0: rdIbilgailua.sMatrikula := sMatrikula + ' KHS' ;
         1: rdIbilgailua.sMatrikula := sMatrikula + ' BPK' ;
         2: rdIbilgailua.sMatrikula := sMatrikula + ' KKK' ;
         3: rdIbilgailua.sMatrikula := sMatrikula + ' XYZ' ;
         4: rdIbilgailua.sMatrikula := sMatrikula + ' KGB' ;
      end ;

      iAusazkoa := random(4) ;
      case iAusazkoa of
         0: rdIbilgailua.cIbilgailuMota := 'A' ;
         1: rdIbilgailua.cIbilgailuMota := 'B' ;
         2: rdIbilgailua.cIbilgailuMota := 'C' ;
         3: rdIbilgailua.cIbilgailuMota := 'D' ;
      end ;

      rdIbilgailua.rdDataUnea.Eguna[1] := 2021 ;              (* 2021-01-01 eta 2021-12-28 artean *)  
      rdIbilgailua.rdDataUnea.Eguna[2] := 1 + random(12) ;
      rdIbilgailua.rdDataUnea.Eguna[3] := 1 + random(27) ;

      rdIbilgailua.rdDataUnea.Ordua[1] := 13 ;                (* 13:05:00 eta 13:15:59 artean *)
      rdIbilgailua.rdDataUnea.Ordua[2] := 5 + random(11) ;
      rdIbilgailua.rdDataUnea.Ordua[3] := random(60) ;

      rdIbilgailua.rAldiunekoAbiadura := 50 + random(131) ;   (* 50.0 eta 180.0 artean *)
   end ;
end ;


procedure IbilgailuarenDatuakErakutsi(const rdIbilgailua: trdIbilgailua) ;
begin
   writeln('Matrikula: ':20, rdIbilgailua.sMatrikula) ;
   
   writeln('Mota: ':20, rdIbilgailua.cIbilgailuMota) ;
   
   write('Data: ':20) ; 
   write(rdIbilgailua.rdDataUnea.Eguna[1], '-') ;
   if rdIbilgailua.rdDataUnea.Eguna[2] >= 10 then
      write(rdIbilgailua.rdDataUnea.Eguna[2], '-')
   else
      write('0', rdIbilgailua.rdDataUnea.Eguna[2], '-') ;   
   if rdIbilgailua.rdDataUnea.Eguna[3] >= 10 then
      writeln(rdIbilgailua.rdDataUnea.Eguna[3])
   else
      writeln('0', rdIbilgailua.rdDataUnea.Eguna[3]) ;
   
   write('Ordua: ':20) ;  
   write(rdIbilgailua.rdDataUnea.Ordua[1], ':') ; 
   if rdIbilgailua.rdDataUnea.Ordua[2] >= 10 then
      write(rdIbilgailua.rdDataUnea.Ordua[2], ':')
   else
      write('0', rdIbilgailua.rdDataUnea.Ordua[2], ':') ;
   if rdIbilgailua.rdDataUnea.Ordua[3] >= 10 then
      writeln(rdIbilgailua.rdDataUnea.Ordua[3])
   else
      writeln('0', rdIbilgailua.rdDataUnea.Ordua[3]) ;
      
   writeln('Abiadura: ':20, rdIbilgailua.rAldiunekoAbiadura:6:2) ;      
end ;

(* ---------------------- PROGRAMA NAGUSIA ---------------------- *)
    
var
   rdIbilgailua: trdIbilgailua ;
begin
   writeln ;
   writeln ;
   writeln ;
   
   writeln('    Ibilgailuaren datuak eskuratzen... ') ;
   IbilgailuarenDatuakJaso(rdIbilgailua) ;   
   writeln ;
   writeln ;
   
   writeln('    Hona hemen ibilgailuaren datuak:') ;
   IbilgailuarenDatuakErakutsi(rdIbilgailua) ;   
   writeln ;
   writeln ;
      
   readln ;
end.

Programaren balizko exekuzio bat hurrrengo irudian erakusten da:

Erregistroa itzultzen duen funtziorik ez dugu programatuko, gauza bera gertatzen da arrayekin (21. Ariketa: zerrendak (IV))

 

2024(e)ko martxoaren 18(a), astelehena

21. Ariketa: zerrendak (IV)

ZER DAKIDAN:
Array bat erabiltzeko gai naiz.



ZER IKASIKO DUDAN:
FUNCTION erako azpiprograma batek ez du Array datu-motako zerrenda bat itzuliko. Horregatik, array bat emaitza izan behar bada beti PROCEDURE erako azpiprogramaz prozesatuko dugu.




ESKATZEN DEN PROGRAMA

Kateekin lan eginez 20. Ariketa: zerrendak (III) programatik abiatu eta ZZZZ-LLL itxurako matrikulak biltzen dituen hasierako zerrendatik beste zerrenda bat lortu LLLZZZZ itxurako datuekin. Suposatuko dugu programari emandako matrikulen datuak egokiak direla, baina programak datuen egokitasuna kontrolatu beharko balu gogoratu 19. Ariketa: karaktere-kateak (II) programan ikasitakoa.

Gure programaren zereginak:
  1. Datuak jaso eta ZZZZ-LLL itxurako matrikulen zerrenda lortu, hasierako zerrenda izango dena
  2. Hasierako zerrendaren elementu guztiak banan banan prozesatu eta LLLZZZZ itxurako zerrenda berria eskuratu
Hasierako zerrenda definitzeko asMatrikulak eta iLuzera aldagaiak behar dira; era beretsuan, bukaerako zerrenda definitzeko asKateak eta iLuzera aldagaiak behar dira (iLuzera berdina da kasu bietan). Helburuko asKateak zerrendari balioak emateko ondoko bi aukera hauek daude, baina horietarik bakarra ontzat emango dugu.

Prozedura bai, non bilatzen den zerrenda irteerako parametroa den:
procedure ZerrendaBerriaLortu(const asMatrikulak: tasHasierakoZerrenda;
                                    var asKateak: tasBukaerakoZerrenda;
                                         iLuzera: integer);
Funtzioa ez, array bat itzultzen duen funtziorik ez dugu onartuko:
function fnasZerrendaLortu(const asMatrikulak: tasHasierakoZerrenda;
                                      iLuzera: integer) : tasBukaerakoZerrenda ;

Hauxe da ariketaren programa:
{ 21. ariketa: hainbat matrikula zerrenda zerrenda batean jaso eta    }
{              zerrenda berri bat lortu.                              }

{ ZZZZ-LLL (non Z zifrak eta L letrak diren) formatuko matrikulak     }
{ gordetzen dituen arrayarekin lan egingo da. Zerrenda berria lortu   }
{ LLLZZZZ itxura datuekin.                                            }
 
program Ariketa_21 ;

const
   BEHEMUGA = 1 ;
   GOIMUGA = 10 ;
type
   tsKate8 = string[8] ;
   tasHasierakoZerrenda = array[BEHEMUGA..GOIMUGA] of tsKate8 ;
   tsKate7 = string[7] ;
   tasBukaerakoZerrenda = array[BEHEMUGA..GOIMUGA] of tsKate7 ; 


procedure HasierakoZerrendaBete(var asMatrikulak: tasHasierakoZerrenda; var iLuzera: integer) ;
var
   k : integer ;
begin
   repeat
      write('   Zerrendak zenbat elementu izango ditu? ') ;
      readln(iLuzera) ;
   until (iLuzera >= BEHEMUGA) and (iLuzera <= GOIMUGA) ;
   writeln ;
   
   for k:=BEHEMUGA to iLuzera do
   begin
      write('   ''1234-XYZ'' itxurako ', k, '. matrikula eman: ') ;
      readln(asMatrikulak[k]) ;
   end ;
end ;
  

procedure HasierakoZerrendaIkusi(const asMatrikulak: tasHasierakoZerrenda; iLuzera: integer) ;
var
   iIndizea : integer ;
begin
   writeln('   Matrikulen zerrendaren edukia: ') ;
   for iIndizea:=BEHEMUGA to iLuzera do
   begin
      writeln(iIndizea:4, '. matrikula = ', asMatrikulak[iIndizea]) ;
   end ;
end ;
 

procedure BukaerakoZerrendaIkusi(const asKateak: tasBukaerakoZerrenda; iLuzera: integer) ;
var
   iIndizea : integer ;
begin
   writeln('   Emaitzen zerrendaren edukia: ') ;
   for iIndizea:=BEHEMUGA to iLuzera do
   begin
      writeln(iIndizea:4, '. katea = ', asKateak[iIndizea]) ;
   end ;
end ;


procedure ZerrendaBerriaLortu(const asMatrikulak: tasHasierakoZerrenda;
                                    var asKateak: tasBukaerakoZerrenda;
                                         iLuzera: integer) ;
var
   iIndizea : integer ;
   sZenbakiak, s3Letrak : tsKate7 ;
begin
   for iIndizea:=BEHEMUGA to iLuzera do
   begin
      sZenbakiak := Copy(asMatrikulak[iIndizea], 1, 4) ;
      s3Letrak := Copy(asMatrikulak[iIndizea], 6, 3) ;
      asKateak[iIndizea] := s3Letrak + sZenbakiak ;
   end ;
end ;


{
function fnasZerrendaBerriaLortu(const asMatrikulak: tasHasierakoZerrenda;
                                            iLuzera: integer) : tasBukaerakoZerrenda ;
var
   asKateak : tasBukaerakoZerrenda ;
   iIndizea : integer ;
   sZenbakiak, s3Letrak : tsKate7 ;
begin
   for iIndizea:=BEHEMUGA to iLuzera do
   begin
      sZenbakiak := Copy(asMatrikulak[iIndizea], 1, 4) ;
      s3Letrak := Copy(asMatrikulak[iIndizea], 6, 3) ;
      asKateak[iIndizea] := s3Letrak + sZenbakiak ;
   end ;
   fnasZerrendaBerriaLortu := asKateak ;
end ;
}

(* ---------------------- PROGRAMA NAGUSIA ---------------------- *)
 
var
   asMatrikulak : tasHasierakoZerrenda ;
   asKateak : tasBukaerakoZerrenda ;
   iLuzera : integer ;
begin
   writeln ;
   writeln ;
   writeln ;
      
   HasierakoZerrendaBete(asMatrikulak, iLuzera) ;
   HasierakoZerrendaIkusi(asMatrikulak, iLuzera) ;
   writeln ;
   
   writeln('   Matrikulen zerrenda prozesatzen...') ; 
   writeln ;
     
   ZerrendaBerriaLortu(asMatrikulak, asKateak, iLuzera) ;          { BAI }
   //asKateak := fnasZerrendaBerriaLortu(asMatrikulak, iLuzera) ;  { EZ }
   
   BukaerakoZerrendaIkusi(asKateak, iLuzera) ;
   writeln ;   
    
   readln ;
end.

Programaren balizko exekuzio bat hurrrengo irudian erakusten da:

Arraya itzultzen duen funtziorik ez dugu programatuko, gauza bera gertatzen da erregistroekin (22. Ariketa: erregistroak (I))

 

20. Ariketa: zerrendak (III)

ZER DAKIDAN:
Zenbakiak, karaktereak eta kateak lantzeko gai naiz. Halaber, array bat erabiltzeko gai naiz.



ZER IKASIKO DUDAN:
Array datu-motako zerrenda batetik abiatuz beste zerrenda bi lortzen ikasiko dut.




ESKATZEN DEN PROGRAMA

Kateekin lan eginez, 1 eta 10 arteko kateen zerrenda bat lortu nahi da. Kateak autoen matrikulak direlako suposatuko dugu zerrendan kate errepikaturik ez dela egongo. Suposatzea aski ez bada eta gure programak egoera hori kontrolatu behar badu, gogoratu 18. Ariketa: zerrendak (I) programan ikasitakoa.

Programa honek lehenik zenbat matrikula gordeko dituen galdetuko du. Ondoren matrikulak banan banan teklatuz irakurriko ditu programak. Demagun matrikula guztien itxura ZZZZ-LLL dela, non Z zenbakizko zifra bat izango den eta L alfabeto larriaren letra bat. Suposatuko dugu programari emandako matrikulen datuak egokiak direla, baina programak datuen egokitasuna kontrolatu beharko balu, gogoratu 17. Ariketa: karaktere-kateak (II) programan ikasitakoa.

Gure programaren zereginak:
  1. Datuak jaso eta matrikulen zerrenda bat lortu, hasierako zerrenda izango dena
  2. Hasierako zerrendaren elementu guztiak banan banan prozesatu bi zerrenda berri eskuratzeko:
    • Matrikulen zifrak biltzen dituen zerrenda berria
    • Matrikulen letrak biltzen dituen zerrenda berria
  3. Zifrak biltzen dituen zerrenda berria prozesatu eragiketa aritmetikoak burutuz
  4. Letrak biltzen dituen zerrenda berria prozesatu maximoa eta minimoa zehaztuz

Hauxe da ariketaren programa:
{ 20. ariketa: hainbat matrikula zerrenda zerrenda batean jaso eta bi }
{              zerrenda berri lortu: zenbaki osoen zerrenda bat eta   }
{              kateen zerrenda bat.                                   }

{ ZZZZ-LLL (non Z zifrak eta L letrak diren) formatuko matrikulak     }
{ gordetzen dituen arrayarekin lan egingo da. Zerrenda berriak lortu  }
{ ondoren, zifren zerrendarekin eragiketa aritmetikoak egingo dira    }
{ eta 3 karaktereko kateen zerrenda berriarekin minimoa eta maximoa   }
{ zehaztuko dira.                                                     }
  
 
{ Abiapuntuko zerrendaren datuak honelako kateak izan daitezke:       }
{                   '1234-XYZ'                                        }
{                   '8888-ABC'                                        }
{                   '4803-BPK'                                        }
{                   '6666-KHS'                                        }
 
program Ariketa_20 ;

const
   BEHEMUGA = 1 ;
   GOIMUGA = 10 ;
type
   tsKate8 = string[8] ;
   tasHasierakoZerrenda = array[BEHEMUGA..GOIMUGA] of tsKate8 ;
   tsKate3 = string[3] ;
   tasZerrendaBerria = array[BEHEMUGA..GOIMUGA] of tsKate3 ;
   taiZerrendaBerria = array[BEHEMUGA..GOIMUGA] of integer ; 


(* Lehenengo parametroa array bat delako eta irteerakoa      *)
(* delako erreferentziaz pasatzen da. Gauza bera bigarren    *)
(* parametroarekin erreferentziaz ere bere balioa prozedura  *)
(* barruan hartu eta irteerakoa delako.                      *)
procedure HasierakoZerrendaBete(var asMatrikulak: tasHasierakoZerrenda; var iLuzera: integer) ;
var
   k : integer ;
begin
   repeat
      write('   Zerrendak zenbat elementu izango ditu? ') ;
      readln(iLuzera) ;
   until (iLuzera >= BEHEMUGA) and (iLuzera <= GOIMUGA) ;
   writeln ;
   
   for k:=BEHEMUGA to iLuzera do
   begin
      write('   ''1234-XYZ'' itxurako ', k, '. matrikula eman: ') ;
      readln(asMatrikulak[k]) ;
   end ;
end ;
  
 
(* Nahiz eta parametro biak sarrerakoak izan, lehenengoa     *)
(* array bat delako eta memorian kopia berriak ekiditeko     *)
(* erreferentziaz pasatzen da, const delako babesturik       *)
(* dago. Bigarren parametroa berriz balioz doa.              *)
procedure HasierakoZerrendaIkusi(const asMatrikulak: tasHasierakoZerrenda; iLuzera: integer) ;
var
   iIndizea : integer ;
begin
   writeln('   Matrikulen zerrendaren edukia: ') ;
   for iIndizea:=BEHEMUGA to iLuzera do
   begin
      writeln(iIndizea:4, '. matrikula = ', asMatrikulak[iIndizea]) ;
   end ;
end ;
 

procedure ZerrendaBanatu(const asMatrikulak: tasHasierakoZerrenda;
                           var ai4Zenbakiak: taiZerrendaBerria;
                           var asHiruLetrak: tasZerrendaBerria;
                                    iLuzera: integer) ;
var
   iIndizea, iGidoiaNon, iErrorea : integer ;
   s3Letrak : tsKate3 ;
   iZenbakiak : integer ;
   sZenbakiak : tsKate8 ;
begin
   for iIndizea:=BEHEMUGA to iLuzera do
   begin
      iGidoiaNon := Pos('-', asMatrikulak[iIndizea]) ;      
      if iGidoiaNon = 0 then writeln('   ERROREA: matrikulen datuak desegokiak dira')
      else
      begin
         sZenbakiak := Copy(asMatrikulak[iIndizea], 1, 4) ;
         s3Letrak := Copy(asMatrikulak[iIndizea], 6, 3) ;
         Val(sZenbakiak, iZenbakiak, iErrorea) ;
         if iErrorea <> 0 then
            writeln('   ERROREA: matrikulen datuak desegokiak dira') ;
         //writeln('iZenbakiak-->', iZenbakiak, '    s3Letrak-->', s3Letrak) ;
         ai4Zenbakiak[iIndizea] := iZenbakiak ;
         asHiruLetrak[iIndizea] := s3Letrak ;
      end ;
   end ;
end ;


procedure KateenZerrendaBerriaIkusi(const asHiruLetrak: tasZerrendaBerria; iLuzera: integer) ; 
var
   iIndizea : integer ;
begin
   writeln('   Zerrenda berri baten edukia: ') ;
   for iIndizea:=BEHEMUGA to iLuzera do
   begin
      writeln(iIndizea:4, '. datua = ', asHiruLetrak[iIndizea]) ;
   end ;
end ;


procedure OsoenZerrendaBerriaIkusi(const ai4Zenbakiak: taiZerrendaBerria; iLuzera: integer) ; 
var
   iIndizea : integer ;
begin
   writeln('   Zerrenda berri baten edukia: ') ;
   for iIndizea:=BEHEMUGA to iLuzera do
   begin
      writeln(iIndizea:4, '. datua = ', ai4Zenbakiak[iIndizea]) ;
   end ;
end ;

 
(* Funtzio batean parametroak BETI sarrerakoak.              *)
function fnrBatezbestekoaKalkulatu(const ai4Zenbakiak: taiZerrendaBerria; iLuzera: integer) : real ;
var
   rMetagailu : real ;
   k : integer ;
begin
   rMetagailu := 0.0 ;
   for k:=BEHEMUGA to iLuzera do
   begin
      rMetagailu := rMetagailu + ai4Zenbakiak[k] ;
   end ;
 
   fnrBatezbestekoaKalkulatu := rMetagailu / iLuzera ;
end ;
 

function fnrMetatuaKalkulatu(const ai4Zenbakiak: taiZerrendaBerria; iLuzera: integer) : real ;
var
   rMetagailu : real ;
   k : integer ;
begin
   rMetagailu := 0.0 ;
   for k:=BEHEMUGA to iLuzera do
   begin
      rMetagailu := rMetagailu + ai4Zenbakiak[k] ;
   end ;
 
   fnrMetatuaKalkulatu := rMetagailu ;
end ;


function fniZehaztuMinimoaNon (const asHiruLetrak: tasZerrendaBerria; iLuzera : integer) : integer ;
var
   k, iMinimoaNon : integer ;
   sBalioMinimoa : tsKate3 ;
begin
   sBalioMinimoa := asHiruLetrak[BEHEMUGA] ;
   iMinimoaNon := BEHEMUGA ;
   for k:=BEHEMUGA to iLuzera do       (* edo ---> for k:=BEHEMUGA+1 to iLuzera do *)
   begin
      if asHiruLetrak[k] < sBalioMinimoa then
      begin
         sBalioMinimoa := asHiruLetrak[k] ;
         iMinimoaNon := k ;
      end ;
   end ;

   fniZehaztuMinimoaNon := iMinimoaNon ;
end ;


function fniZehaztuMaximoaNon (const asHiruLetrak: tasZerrendaBerria; iLuzera : integer) : integer ;
var
   k, iMaximoaNon : integer ;
   sBalioMaximoa : tsKate3 ;
begin
   sBalioMaximoa := asHiruLetrak[BEHEMUGA] ;
   iMaximoaNon := BEHEMUGA ;
   for k:=BEHEMUGA to iLuzera do       (* edo ---> for k:=BEHEMUGA+1 to iLuzera do *)
   begin
      if asHiruLetrak[k] > sBalioMaximoa then
      begin
         sBalioMaximoa := asHiruLetrak[k] ;
         iMaximoaNon := k ;
      end ;
   end ;

   fniZehaztuMaximoaNon := iMaximoaNon ;
end ;

(* ---------------------- PROGRAMA NAGUSIA ---------------------- *)
 
var
   asMatrikulak   : tasHasierakoZerrenda ;
   asHiruLetrak   : tasZerrendaBerria ;
   ai4Zenbakiak   : taiZerrendaBerria ;
   iLuzera        : integer ;
   rMetatua       : real ;
   rBatezbestekoa : real ;
   iMinimoaNon    : integer ;
   iMaximoaNon    : integer ;
begin
   writeln ;
   writeln ;
   writeln ;
      
   HasierakoZerrendaBete(asMatrikulak, iLuzera) ;
   HasierakoZerrendaIkusi(asMatrikulak, iLuzera) ;
   writeln ;
      
   ZerrendaBanatu(asMatrikulak, ai4Zenbakiak, asHiruLetrak, iLuzera) ;
   
   OsoenZerrendaBerriaIkusi(ai4Zenbakiak, iLuzera) ;
   KateenZerrendaBerriaIkusi(asHiruLetrak, iLuzera) ;
   writeln ;   

   rMetatua := fnrMetatuaKalkulatu(ai4Zenbakiak, iLuzera) ;
   writeln('   Zenbakien metatua = ', rMetatua:0:3) ;
   rBatezbestekoa := fnrBatezbestekoaKalkulatu(ai4Zenbakiak, iLuzera) ;
   writeln('   Batezbestekoa = ', rBatezbestekoa:0:3) ;
   
   iMinimoaNon := fniZehaztuMinimoaNon (asHiruLetrak, iLuzera) ;
   iMaximoaNon := fniZehaztuMaximoaNon (asHiruLetrak, iLuzera) ;
   writeln('   Kateen arteko txikiena = ', asHiruLetrak[iMinimoaNon]) ;
   writeln('   Kateen arteko handiena = ', asHiruLetrak[iMaximoaNon]) ;
    
   readln ;
end.

Programaren balizko exekuzio bat hurrrengo irudian erakusten da:


 

19. Ariketa: zerrendak (II)

ZER DAKIDAN:
Zenbakiak, karaktereak eta kateak lantzeko gai naiz. Halaber, array bat erabiltzeko gai naiz.



ZER IKASIKO DUDAN:
Array datu-motako zerrenda batean ondoko bi algoritmoak ikasiko ditut:
  • Elementu berri bat zerrendaren erdian txertatzen ikasiko dut
  • Zerrendaren erdiko elementu bat ezabatzen ikasiko dut




ESKATZEN DEN PROGRAMA (I) 

Abiadurak adierazten dituzten zenbaki errealekin lan eginez, 1 eta 10 arteko errealen zerrenda bat lortu nahi da. Zerrendaren elementuak abiadurak dira eta balio errepikatuak onartzen dira.

Programa honek lehenik zenbat abiadura gordeko dituen erabakitzen du, eta gero abiaduren zerrenda osatzen du. Bildutako abiaduren balioak pantailaratu ondoren, rAbiaduraBerria elementu berri bat eta iNon posizio bat eskatuko ditu programak, bi datu horiekin burutzen da elementu berriaren tartekaketa zerrendan (aurreko guztia baldin eta lekurik badago zerrendan). Bukatzean, zerrenda berria pantailaratuko du progranak.

Hauxe da ariketaren programa:
{ 19. ariketa: hainbat abiaduren zerrenda osatu ondoko baldintzekin:  }
{     - Abiaduren kopurua zerrendan 1 eta 10 artekoa izango da        }
{     - Abiaduren balioak 30.0 Km eta 179.9 Km artekoak izango dira   }

{ Abiaduren zerrenda lortu eta elementu berri bat txertatu zerrendan. }

program Ariketa_19_I ;

const
  BEHEMUGA = 1 ;
  GOIMUGA = 10 ;
  
type
  tarAbiadurenSorta = array[BEHEMUGA..GOIMUGA] of real ;

   
procedure AbiadurenarrayaBete(var arAbiadurak: tarAbiadurenSorta;
                                  var iLuzera: integer) ;
var
   iIndizea: integer ;
begin
   Randomize ;
   iLuzera := Random(GOIMUGA) + 1 ;

   writeln('    Abiaduren zerrendan ', iLuzera, ' datu gordetzen...') ;
   writeln('    Aurrera egiteko RETURN sakatu!') ;
   readln ;
            
   for iIndizea:=BEHEMUGA to iLuzera do
   begin
      arAbiadurak[iIndizea] := 30 + 150*Random ;      { 30.0 eta 179.9 arteko balioak }
   end ;
end ;


procedure AbiadurenarrayaIkusi(const arAbiadurak: tarAbiadurenSorta;
                                         iLuzera: integer) ;
var
   iIndizea: integer ;
begin
   writeln ;
   writeln('    Abiaduren zerrendaren edukia: ') ;
   for iIndizea:=BEHEMUGA to iLuzera do
   begin
      writeln(iIndizea:22, '. abiadura = ', arAbiadurak[iIndizea]:0:3) ;
   end ;
   writeln ;
end ;

 
procedure Tartekaketa(var arAbiadurak: tarAbiadurenSorta;
                          var iLuzera: integer;
                           rElementua: real;
                                 iNon: integer) ;
var
   iIndizea: integer ;
begin
   for iIndizea:=iLuzera doWNto iNon do
   begin
      arAbiadurak[iIndizea+1] := arAbiadurak[iIndizea] ;
   end ;
   arAbiadurak[iNon] := rElementua ;
   iLuzera := iLuzera + 1 ;
end ;

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

var
   arAbiadurak: tarAbiadurenSorta ;
   iLuzera, iNon: integer ;
   rAbiaduraBerria: real ;
begin
   writeln ;
   writeln ;
   writeln ;
   
   AbiadurenarrayaBete(arAbiadurak, iLuzera) ;
   AbiadurenarrayaIkusi(arAbiadurak, iLuzera) ;

   if iLuzera < GOIMUGA then
   begin
      write('    Eman abiadura berriaren balioa (30.0 eta 179.9 artekoa) ') ;
      readln(rAbiaduraBerria) ;
      repeat
         write('    Eman abiadura berriaren posizioa zerrendan: ') ;
         readln(iNon) ;
      until (iNon >= BEHEMUGA) and (iNon <= iLuzera) ;

      Tartekaketa(arAbiadurak, iLuzera, rAbiaduraBerria, iNon) ;
      AbiadurenarrayaIkusi(arAbiadurak, iLuzera) ;
   end
   else
      writeln('    Zerrenda beterik dago, ezin da elementu berria txertatu.') ;
      
   readln ;
end.

Programaren balizko exekuzio bat hurrrengo irudian erakusten da:





ESKATZEN DEN PROGRAMA (II) 

Abiadurak adierazten dituzten zenbaki errealekin lan eginez, 1 eta 10 arteko errealen zerrenda bat lortu nahi da. Zerrendaren elementuak abiadurak dira eta balio errepikatuak onartzen dira.

Programa honek (aurrekoak bezala) lehenik zenbat abiadura gordeko dituen erabakitzen du, eta gero abiaduren zerrenda osatzen du. Bildutako abiaduren balioak pantailaratu ondoren, zerrendatik kenduko den elementuaren iNon posizioa eskatuko du programak, datu horrekin burutzen da elementuaren ezabaketa zerrendatik. Bukatzean, zerrenda berria pantailaratuko du progranak eta ezabatutako abiadura erakutsiko du ere.

Hauxe da ariketaren programa:
{ 19. ariketa: hainbat abiaduren zerrenda osatu ondoko baldintzekin:  }
{     - Abiaduren kopurua zerrendan 1 eta 10 artekoa izango da        }
{     - Abiaduren balioak 30.0 Km eta 179.9 Km artekoak izango dira   }

{ Abiaduren zerrenda lortu eta elementu jakin bat zerrendatik kendu.  }

program Ariketa_19_II ;

const
  BEHEMUGA = 1 ;
  GOIMUGA = 10 ;
  
type
  tarAbiadurenSorta = array[BEHEMUGA..GOIMUGA] of real ;


procedure AbiadurenarrayaBete(var arAbiadurak: tarAbiadurenSorta;
                                  var iLuzera: integer) ;
var
   iIndizea: integer ;
begin
   Randomize ;
   iLuzera := Random(GOIMUGA) + 1 ;

   writeln('    Abiaduren zerrendan ', iLuzera, ' datu gordetzen...') ;
   writeln('    Aurrera egiteko RETURN sakatu!') ;
   readln ;
            
   for iIndizea:=BEHEMUGA to iLuzera do
   begin
      arAbiadurak[iIndizea] := 30 + 1530*Random ;      { 30.0 eta 179.9 arteko balioak }
   end ;
end ;


procedure AbiadurenarrayaIkusi(const arAbiadurak: tarAbiadurenSorta;
                                         iLuzera: integer) ;
var
   iIndizea: integer ;
begin
   writeln ;
   writeln('    Abiaduren zerrendaren edukia: ') ;
   for iIndizea:=BEHEMUGA to iLuzera do
   begin
      writeln(iIndizea:22, '. abiadura = ', arAbiadurak[iIndizea]:0:3) ;
   end ;
   writeln ;
end ;


procedure Ezabaketa(var arAbiadurak: tarAbiadurenSorta;
                        var iLuzera: integer;
                               iNon: integer) ;
var
   iIndizea: integer ;
begin
   for iIndizea:=iNon to iLuzera-1 do
   begin
      arAbiadurak[iIndizea] := arAbiadurak[iIndizea+1] ;
   end ;
   iLuzera := iLuzera - 1 ;
end ;

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

var
  arAbiadurak: tarAbiadurenSorta ;
  iLuzera, iNon: integer ;
  rElemKopia: real ;
begin 
   writeln ;
   writeln ;
   writeln ;
   
   AbiadurenarrayaBete(arAbiadurak, iLuzera) ;
   AbiadurenarrayaIkusi(arAbiadurak, iLuzera) ;

   repeat
      write('    Ezabatuko den abiaduraren posizioa zerrendan: ') ;
      readln(iNon) ;
   until (iNon >= BEHEMUGA) and (iNon <= iLuzera) ;

   rElemKopia := arAbiadurak[iNon] ;        { aterako den datuaren kopia egin }

   Ezabaketa(arAbiadurak, iLuzera, iNon) ;

   AbiadurenarrayaIkusi(arAbiadurak, iLuzera) ;
   writeln('    Hona hemen zerrendatik ezabatu den abiadura: ', rElemKopia:0:3) ;
   
   readln ;
end.

Programaren balizko exekuzio bat hurrrengo irudian erakusten da: