Sunteți pe pagina 1din 12

5.

Masive memorate în fişiere

Una din aplicaţiile des întâlnite în lucrul cu fişiere este memorarea masivelor
de date de dimensiuni mari, care fac imposibilă aducerea integrală a lor în memoria
internă. Problema principală a prelucrării masivelor (vectori, matrice etc.) memorate
în fişiere binare o constituie determinarea poziţiei unui anumit element din masiv în
cadrul fişierului. Indiferent de numărul de dimensiuni ale masivului şi de modalităţile
de memorare a elementelor sale în cadrul fişierului, legătura între elementul de masiv
care se referă şi numărul relativ al articolului care îl conţine se realizează pe baza
funcţiei rang, similară celei implementate pentru datele de tip ARRAY.
În cazul masivelor memorate în fişiere, prelucrarea acestora depinde de
unele caracteristici particulare: numărul de dimensiuni ale masivului; ordinea de
memorare în fişier (lexicografică sau invers lexicografică); modul de memorare (dens
sau nedens); ordinea de parcurgere a masivului.

5.1. Prelucrarea vectorilor

De regulă, vectorii se memorează dens. Numărul relativ al articolului


depinde de rangul elementului în cadrul vectorului, astfel:
• nr_relativ=rang(xi)=i, pentru i=1..n, dacă articolul cu numărul relativ 0 nu
este utilizat, caz în care dimensiunea vectorului este n=FileSize(f)-1, sau memorează
numărul efectiv de componente ale vectorului (n<FileSize(f));
• nr_relativ=rang(xi)-1=i-1, pentru i=1..n, dacă vectorul se memorează
începând cu primul articol (caz în care dimensiunea vectorului este n=FileSize(f)).
Pentru exemplificarea prelucrării vectorilor de mari dimensiuni memoraţi în
fişiere s-a construit unitatea Pascal Unit_vec, care conţine următoarele proceduri de
prelucrare a vectorilor memoraţi dens, începând de la poziţia 0:
• Creare_vector realizează crearea în acces secvenţial a unui fişier binar
ale cărui articole, de tip REAL, memorează elementele vectorului.
• Listare_vector afişează pe ecran conţinutul fişierului (vectorului),
printr-o parcurgere secvenţială. Procedura poate fi folosită de către utilizator, în
special pentru verificarea corectitudinii rezultatelor.
• Sortare_vector realizează sortarea fişierului prin metoda selecţiei, prin
interschimbarea fizică a elementelor vectorului (articolelor), utilizând accesul direct.
• Min_max_vector determină elementul minim, respectiv maxim din
vector, printr-o singură parcurgere secvenţială a fişierului.
• Interclasare realizează interclasarea a doi vectori de dimensiuni
diferite, memoraţi în câte un fişier binar. Procedura asigură sortarea lor înainte de
interclasarea propriu-zisă. Rezultatul va fi memorat într-un fişier binar, similar
vectorilor iniţiali.
• Produs_vectorial determină produsul vectorial dintre doi vectori,
memoraţi consecutiv în acelaşi fişier. Rezultatul va fi memorat împreună cu vectorii
iniţiali, ca extindere a fişierului de intrare, a cărui dimensiune la ieşire va fi 3n.
Algoritmi în programare. Aplicaţii

unit unit_vec;
INTERFACE
uses crt;
type tipfis=file of real;
procedure creare_vector(var f:tipfis; var nume:string);
procedure listare_vector(var f:tipfis; var nume:string);
procedure sortare_vector(var f:tipfis; var nume:string);
procedure min_max_vector(var f:tipfis; var nume:string;
var min,max:real);
procedure interclasare(var f,g,h:tipfis;
var nume1,nume2,nume3: string);
procedure produs_vectorial(var f:tipfis; var nume:string);
IMPLEMENTATION
var n,i,j:word; x,y,z,hv:real;
procedure creare_vector;
begin
clrscr; assign(f,nume); rewrite(f);
write('Dimensiune vector: '); readln(n);
for i:=1 to n do
begin
write('x(',i:2,') = '); readln(x); write(f,x)
end;
close(f)
end;
procedure listare_vector;
begin
clrscr; assign(f,nume); reset(f);
for i:=1 to filesize(f) do
begin read(f,x); writeln('x(',i:2,') = ',x:10:2) end;
close(f)
end;
procedure sortare_vector;
begin
clrscr; assign(f,nume); reset(f); n:=filesize(f);
for i:=1 to n-1 do
begin
seek(f,i-1); read(f,x);
for j:=i+1 to n do
begin
seek(f,j-1); read(f,y);
if x>y then
begin
seek(f,i-1); write(f,y);
seek(f,j-1); write(f,x);
x:=y
end
end
end;
close(f)
end;
Masive memorate în fişiere

procedure min_max_vector;
begin
assign(f,nume); reset(f);
read(f,max);
min:=max;
for i:=2 to filesize(f) do
begin
read(f,x);
if x>max then max:=x
else if x<min then min:=x
end;
close(f)
end;
procedure interclasare;
begin
hv:=1000000;
sortare_vector(f,nume1);
sortare_vector(g,nume2);
reset(f); reset(g);
assign(h,nume3);
rewrite(h);
read(f,x);
read(g,y);
while (x<>hv) or (y<>hv) do
if x<y then
begin
write(h,x);
if eof(f) then x:=hv else read(f,x)
end
else
begin
write(h,y);
if eof(g) then y:=hv else read(g,y)
end;
close(f); close(g); close(h)
end;
procedure produs_vectorial;
begin
assign(f,nume); reset(f);
n:=filesize(f) div 2;
for i:=1 to n do
begin
seek(f,i-1); read(f,x);
seek(f,n+i-1); read(f,y);
z:=x*y;
seek(f,2*n+i-1); write(f,z)
end;
close(f);
end;
end.
Algoritmi în programare. Aplicaţii

5.2. Prelucrarea matricelor

O matrice poate fi memorată într-un fişier binar nedens (similar memorării în


memoria principală) sau dens, în ordine lexicografică sau invers lexicografică.
Numărul relativ al elementului aij se determină pe baza funcţiei rang, astfel:
• rang(aij)=(i-1)⋅nr_coloane+j, în cazul memorării lexicografice, unde
nr_coloane este fie numărul coloanelor efective (populare densă), fie numărul
coloanelor rezervate (populare nedensă);
• rang(aij)=(j-1)⋅nr_linii+i, în cazul memorării invers lexicografice, unde
nr_linii este fie numărul liniilor efective (populare densă), fie numărul liniilor
rezervate (populare nedensă).
Fie m şi n numărul liniilor, respectiv coloanelor efective şi mr şi nr numărul
liniilor, respectiv coloanelor rezervate (mr şi nr corespund elementelor din declaraţia
ARRAY). Pentru ca fişierul să conţină informaţii complete despre matrice trebuie să
memoreze pe lângă elementele ei şi alte informaţii cu privire la dimensiuni:
ƒ m (sau n), în cazul memorării dense. Când se memorează m, n se
determină după relaţia FileSize(f) DIV m; când se memorează n, m se determină
după relaţia FileSize(f) DIV n. Funcţia rang depinde de m sau n, după cum matricea
este memorată invers lexicografic sau lexicografic;
ƒ n şi nr, în cazul memorării nedense în ordine lexicografică; m se
determină după relaţia FileSize(f) DIV nr, iar mr nu are relevanţă (el putea fi
memorat în locul lui nr, acesta determinându-se după relaţia FileSize(f) DIV mr).
Funcţia rang depinde de nr;
ƒ m şi mr, în cazul memorării nedense în ordine invers lexicografică; n se
determină după relaţia FileSize(f) DIV mr, iar nr nu are relevanţă (el putea fi
memorat în locul lui mr, acesta determinându-se după relaţia FileSize(f) DIV nr).
Funcţia rang depinde de mr.
Funcţia rang se calculează şi se utilizează numai dacă problema de rezolvat
implică parcurgerea matricei în altă ordine decât cea în care este memorată în fişier
(consultarea acestuia se realizează în acces direct).

1. Pentru exemplificarea prelucrării matricelor dreptunghiulare, memorate dens şi


lexicografic s-a construit unitatea Unit_mat. Se presupune că matricea are
dimensiunea maximă 100x100. Unitatea conţine următoarele proceduri:
• Creare_matrice realizează crearea în acces secvenţial a unui fişier binar,
care va conţine în primul articol numărul de linii, iar în celelalte elementele matricei.
• Listare_matrice afişează pe ecran o matrice dreptunghiulară, sub
formă tabelară, prin parcurgerea secvenţială a fişierului care o memorează.
• Maxime_pe_coloane determină elementul maxim de pe fiecare coloană a
unei matrice dreptunghiulare, memorată într-un fişier binar. Elementele matricei sunt
accesate direct, pe baza funcţiei rang. Rezultatul se depune într-un vector, memorat
în memoria principală.
• Determinare_linii selectează liniile cu elemente constante ale unei
matrice dreptunghiulare, memorată într-un fişier binar. Primul element al fiecărei
Masive memorate în fişiere

linii este accesat direct pe baza funcţiei rang, celelalte elemente fiind accesate
secvenţial. Rezultatul se depune într-un vector, memorat în memoria principală.
• Transpusa determină transpusa unei matrice dreptunghiulare, memorată
într-un fişier binar. Rezultatul este depus într-un alt fişier binar, cu structură similară
fişierului iniţial. Fişierul de intrare este parcurs în acces direct, iar cel de ieşire este
creat în acces secvenţial.
• Adunare_matrice determină suma a două matrice dreptunghiulare,
memorate în câte un fişier binar. Rezultatul este memorat similar, într-un alt fişier
binar. Fişierele de intrare, precum şi cel de ieşire, sunt parcurse secvenţial.
• Produs_matrice realizează înmulţirea a două matrice dreptunghiulare,
memorate în câte un fişier binar. Rezultatul este memorat similar, într-un alt fişier
binar. Fişierele de intrare sunt parcurse în acces direct, iar cel de ieşire este creat în
acces secvenţial.
• Coloane_progr_aritm determină coloanele cu elemente în progresie
aritmetică ale unei matrice dreptunghiulare, memorată într-un fişier binar. Fişierul de
intrare se parcurge în acces direct, iar rezultatul de depune într-un vector, memorat în
memoria principală. Pentru ca problema să aibă sens, matricea trebuie să aibă minim
trei linii.

unit unit_mat;
INTERFACE
uses crt;
type art=record
case boolean of
false:(dim:word);
true:(a:real)
end;
tipfis=file of art;
vector=array[1..100] of real;
procedure creare_matrice(var f:tipfis; var nume:string);
procedure listare_matrice(var f:tipfis; var nume:string);
procedure maxime_pe_coloane(var f:tipfis; var nume:string;
var nrc:word; var max:vector);
procedure determinare_linii(var f:tipfis; var nume:string;
var k:word; var v:vector);
procedure coloane_progr_aritm(var f:tipfis; var nume:string;
var k:word; var v:vector);
procedure transpusa(var f,g:tipfis; var nume1,nume2:string);
procedure adunare_matrice(var f,g,h:tipfis; var nume1,nume2,
nume3 :string);
procedure produs_matrice(var f,g,h:tipfis; var nume1,nume2,
nume3 :string);
IMPLEMENTATION
var
m,n,p,i,j,k:word;
x,y,z:art; vb:boolean;
r:real;
Algoritmi în programare. Aplicaţii

procedure creare_matrice;
begin
clrscr; assign(f,nume); rewrite(f);
write('Nr. linii: '); readln(m);
write('Nr. coloane: '); readln(n);
x.dim:=m; write(f,x);
for i:=1 to m do
for j:=1 to n do
begin
write('a(',i,',',j,') = '); readln(x.a);
write(f,x)
end;
close(f)
end;
procedure listare_matrice;
begin
clrscr; assign(f,nume); reset(f);
read(f,x); m:=x.dim;
n:=(filesize(f)-1) div m;
for i:=1 to m do
begin
for j:=1 to n do
begin
read(f,x); write(x.a:5:2,' ')
end;
writeln
end;
close(f)
end;
procedure maxime_pe_coloane;
begin
assign(f,nume); reset(f);
read(f,x); m:=x.dim; nrc:=(filesize(f)-1) div m;
for j:=1 to nrc do
begin
seek(f,j); read(f,x);
max[j]:=x.a;
for i:=2 to m do
begin
seek(f,(i-1)*nrc+j); read(f,x);
if x.a>max[j] then max[j]:=x.a
end
end
end;
procedure determinare_linii;
begin
assign(f,nume); reset(f);
read(f,x); m:=x.dim; n:=(filesize(f)-1) div m;
k:=0;
for i:=1 to m do
Masive memorate în fişiere

begin
j:=1; vb:=false; seek(f,(i-1)*n+1); read(f,x);
while (j<=n-1) and not vb do
begin
read(f,y);
if x.a<>y.a then vb:=true else inc(j)
end;
if j=n then begin inc(k); v[k]:=i end
end
end;
procedure transpusa;
Begin
assign(f,nume1); assign(g,nume2);
reset(f); rewrite(g);
read(f,x); m:=x.dim; n:=(Filesize(f)-1) div m;
x.dim:=n; Write(g,x);
for i:=1 to n do
for j:=1 to m do
begin
seek(f,(j-1)*n+i);
read(f,x);
write(g,x)
end;
close(f); close(g)
end;
procedure adunare_matrice;
begin
assign(f,nume1); assign(g,nume2); assign(h,nume3);
reset(f); reset(g); rewrite(h);
read(f,x);
m:=x.dim; n:=(Filesize(f)-1) div m;
seek(g,1); write (h,x);
for i:=1 to m do
for j:=1 to n do
begin
read(f,x); read(g,y);
z.a:=x.a+y.a;
write(h,z)
end;
close(f); close(g); close(h)
end;
procedure produs_matrice;
begin
assign(f,nume1); assign(g,nume2); assign(h,nume3);
reset(f); reset(g); rewrite(h);
read(f,x); m:=x.dim; read(g,y); n:=y.dim;
p:=(Filesize(g)-1) div n; write(h,x);
for i:=1 to m do
for j:=1 to p do
begin
Algoritmi în programare. Aplicaţii

z.a:=0;
for k:=1 to n do
begin
seek(f,(i-1)*n+k); Read(f,x);
seek(g,(k-1)*p+j); read(g,y);
z.a:=z.a+x.a*y.a
end;
write(h,z)
end;
close(f); close(g); close(h)
end;
procedure coloane_progr_aritm;
begin
assign(f,nume); reset(f);
read(f,x); m:=x.dim; n:=(Filesize(f)-1) div m;
k:=0;
for j:=1 to n do
begin
vb:=false;
for i:=1 to m-2 do
begin
seek(f,i*n+j); read(f,x);
seek(f,(i-1)*n+j); read(f,y);
seek(f,(i+1)*n+j); read(f,z);
if 2*x.a<>(y.a+z.a) then vb:=true
end;
if not vb then
begin
k:=k+1;
v[k]:=j
end
end;
close(f)
end
end.

2. Pentru exemplificarea prelucrării matricelor pătrate, memorate dens şi lexicografic


s-a construit unitatea Unit_m2, care include o serie de proceduri şi funcţii specifice.
Numărul de linii şi de coloane ale matricei nu este memorat în fişier, ci va fi calculat
pe baza dimensiunii fişierului (presupus n2). Numărul relativ al elementului în fişier
este dat de rangul elementului a(i,j) minus 1, deoarece matricea se memorează în
fişier începând de la poziţia 0.
• Procedurile Creare_mat_real şi Creare_mat_intreg realizează crearea
în acces secvenţial a unui fişier binar, care va conţine matricea cu elemente reale,
respectiv întregi.
• Procedurile Listare_mat_real şi Listare_mat_intreg afişează pe
ecran o matrice pătrată cu elemente reale, respectiv întregi, sub formă tabelară, prin
parcurgerea secvenţială a fişierului care o memorează.
Masive memorate în fişiere

• Funcţia Medie_a determină media aritmetică a elementelor din triunghiul de


deasupra diagonalei principale, inclusiv diagonala, dintr-o matrice pătrată cu
elemente reale. Media se calculează numai dacă există cel puţin două elemente.
• Funcţia Medie_g determină media geometrică a elementelor strict pozitive de
pe diagonala secundară a unei matrice pătrate cu elemente reale. Media se calculează
numai dacă există cel puţin două elemente, fişierul fiind parcurs în acces direct.
• Funcţia Urma calculează urma unei matrice pătrate cu elemente reale (suma
elementelor de pe diagonala principală). Fişierul este parcurs în acces direct.
• Funcţia Numar determină numărul de elemente divizibile cu 3 din triunghiul
de sub diagonala secundară dintr-o matrice pătrată cu elemente naturale.

unit unit_m2;
INTERFACE
uses crt;
type tipfis=file of real; tipfisi=file of word;
vector=array[1..100] of real;
procedure creare_mat_real(var f:tipfis; var nume:string);
procedure creare_mat_intreg(var f:tipfisi; var nume:string);
procedure listare_mat_real(var f:tipfis; var nume:string);
procedure listare_mat_intreg(var f:tipfisi; var nume:string);
function medie_a(var f:tipfis; var nume:string):real;
function medie_g(var f:tipfis; var nume:string):real;
function urma(var f:tipfis; var nume:string):real;
function numar(var f:tipfisi; var nume:string):word;
IMPLEMENTATION
var n,i,j,k,x:word; a,med,tr:real;
procedure creare_mat_real;
begin
clrscr; assign(f,nume); rewrite(f);
write('Nr.linii/coloane: '); readln(n);
for i:=1 to n do
for j:=1 to n do
begin
write('a(',i,',',j,')='); readln(a); write(f,a)
end;
close(f)
end;
procedure creare_mat_intreg;
begin
clrscr; assign(f,nume); rewrite(f);
write('Nr.linii/coloane: '); readln(n);
for i:=1 to n do
for j:=1 to n do
begin
write('a(',i,',',j,')='); readln(x); write(f,x)
end;
close(f)
end;
Algoritmi în programare. Aplicaţii

procedure listare_mat_real;
begin
clrscr; assign(f,nume); reset(f);
n:=trunc(sqrt(filesize(f)));
for i:=1 to n do begin
for j:=1 to n do
begin read(f,a); write(a:5:2,' ') end;
writeln
end;
close(f)
end;
procedure listare_mat_intreg;
begin
clrscr; assign(f,nume); reset(f);
n:=trunc(sqrt(filesize(f)));
for i:=1 to n do begin
for j:=1 to n do
begin read(f,x); write(x,' ') end;
writeln
end;
close(f)
end;
function medie_a;
begin
assign (f,nume); reset (f); n:=trunc(sqrt(filesize(f)));
med:=0; k:=0;
for i:=1 to n do
for j:=i to n do
begin
seek (f,(i-1)*n+j-1); read (f,a);
med:=med+a; k:=k+1
end;
if k>=2 then medie_a:=med/k;
close (f)
end;
function medie_g;
begin
assign(f,nume); reset(f); n:=trunc(sqrt(filesize(f)));
med:=1; k:=0;
for i:=1 to n do
begin
seek(f,i*(n-1)); read(f,a);
if a>0 then begin
med:=med*a;
k:=k+1
end
end;
if k>=2 then medie_g:=exp(ln(med)/k);
close (f)
end;
Masive memorate în fişiere

function urma;
begin
assign (f,nume); reset (f);
n:=trunc(sqrt(filesize(f)));
tr:=0;
for i:=1 to n do
for j:=1 to n do
begin
seek (f,(j-1)*n+j-1);
read (f,a);
tr:=tr+a
end;
urma:=tr;
close (f)
end;
function numar;
begin
assign (f,nume); reset (f);
n:=trunc(sqrt(filesize(f)));
k:=0;
for j:=2 to n do
for i:=n-j+2 to n do
begin
seek (f,(i-1)*n+j-1);
read (f,x);
if (x mod 3)=0 then inc(k)
end;
numar:=k;
close (f)
end
end.

5.3. Matrice memorate nedens

Să se determine elementul maxim de pe fiecare coloană a unei matrice de


dimensiuni m⋅n (n<=1000), memorată nedens într-un fişier binar, în ordine
lexicografică. Primul articol conţine numărul de coloane efective. Numărul rezervat
de coloane este 1000. Pot fi elaborate variante în care se încarcă în memoria internă o
întreagă linie a matricei. Din această categorie de rezolvări sunt prezentate două
variante: cu parcurgerea integrală de n ori a fişierului şi cu o singură parcurgere.

• Varianta 1 - fişierul se parcurge integral de n ori.


type
vector=array[1..1000] of real;
var
matrice:file of vector;
max,linie:vector;
m,n,i,j:longint;
Algoritmi în programare. Aplicaţii

begin
assign(matrice,'matrice.dat'); reset(matrice);
read(matrice,linie); {citirea numarului de coloane}
n:=trunc(linie[1]);
m:=filesize(matrice)-1;
for j:=1 to n do
begin
seek(matrice,1); {pozitionare pe prima linie}
read(matrice,linie);
max[j]:=linie[j];
for i:=2 to m do
begin
read(matrice,linie);
if linie[j] > max[j] then max[j]:=linie[j]
end
end;
writeln('Maximele pe fiecare coloana sunt:');
for j:=1 to n do
writeln('Coloana ',j,' = ',max[j]:10:2);
close(matrice)
end.

• Varianta 2 - fişierul se parcurge o singură dată.


type
vector=array[1..1000] of real;
var
matrice:file of vector;
max,linie:vector;
m,n,i,j:longint;
begin
assign(matrice,'matrice.dat'); reset(matrice);
read(matrice,linie); {citirea numarului de coloane}
n:=trunc(linie[1]);
m:=filesize(matrice)-1;
read(matrice,linie);
{initializare maxime cu primul element de pe coloana j}
for j:=1 to n do max[j]:=linie[j];
for i:=2 to m do
begin
read(matrice,linie);
for j:=1 to n do
if linie[j] > max[j] then max[j]:=linie[j]
end;
writeln('Maximele pe fiecare coloana sunt:');
for j:=1 to n do
writeln('Coloana ',j,' = ',max[j]:10:2);
close(matrice)
end.

S-ar putea să vă placă și