Beruflich Dokumente
Kultur Dokumente
ASD17AlgVectLab
ASD17AlgVectLab
R2.
Enunul problemei: Fie v = (v1, , vn). S se calculeze media vectorului =
dispersia
vectorului
1 n
(v i ) 2 .
n i=1
De
exemplu,
1 n
vi i
n i =1
pentru v = (1 2 3 6):
1
14
= 3.5.
(1 3) 2 + (2 3) 2 + (3 3) 2 + (6 3) 2 =
4
4
Metoda de rezolvare: Media vectorului reprezint chiar media aritmetic a componentelor
vectorului (adic suma componentelor mprit la numrul componentelor) , iar dispersia
reprezint de asemenea o sum mprit la numrul componentelor. nti calculm suma
componentelor n variabila , apoi mprim rezultatul din la n i actualizm . Similar
pentru , nti calculm suma ptratelor diferenei dintre valoarea curent i n variabila ,
apoi mprim rezultatul din la n i actualizm .
= (1 +2+3+6) / 4 = 12 / 4 = 3, iar =
*dispersia vectorului
pentru i = 1,n repeta
*parcurgem vectorul
2
+ (vi-)
*adaugam la miu componenta curenta
/ n
*se imparte rezultatul la n
scrie ,
ASD17AlgVectLab
R3.
Enunul problemei: Fie vectorii u = (u1, , un) i v = (v1, , vn). S se calculeze produsul
scalar dintre cei doi vectori i normele ambilor vectori. De exemplu, pentru u = (-1 1 2 0) i
v = (1 2 3 6), produsul scalar dintre cei doi vectori este < u, v > = (-1)1 + 12 + 23 + 06 = 7,
norma vectorului u este ||u|| =
(1) 2 + 12 + 2 2 + 0 2 =
||v|| = 12 + 2 2 + 3 2 + 6 2 = 50 ~7.07.
Metoda de rezolvare: Pentru u = (u1, , un) i v = (v1, , vn):
n
(ui )2
i =1
n
(vi )2 .
i =1
Aadar, produsul scalar este o sum, iar normele pot fi vzute iniial ca fiind sumele de sub
radicali, apoi se corecteaz prin calcularea radicalului din sumele calculate anterior.
O descriere a algoritmului n pseudocod:
citete n,u1,...,un,v1,...,vn
*am citit dimensiunea comuna si elementele celor 2 vectori
ps 0
*media vectorului
pentru i = 1,n repeta
*parcurgem vectorul
ps ps + uivi
*adaugam la miu componenta curenta
Nu 0
*norma vectorului u, initial 0
pentru i = 1,n repeta
*parcurgem vectorul u
2
Nu Nu + (ui)
*se adauga patratul compon.curente
Nu Nu
*se corecteaza valoarea variabilei Nu
Nv 0
*norma vectorului u, initial 0
pentru i = 1,n repeta
*parcurgem vectorul u
Nv Nv + (vi)2
*se adauga patratul compon.curente
Nv Nv
*se corecteaza valoarea variabilei Nv
scrie ps, Nu, Nv
for (i=0;i<n;i++) {
ps += u[i]*v[i];
Nu += u[i]*u[i];
Nv += v[i]*v[i];
}
Nu = sqrt(Nu);
Nv = sqrt(Nv);
ASD17AlgVectLab
"<<fixed<<
O alt implementare n C++ a acestui algoritm poate folosi funcie pentru calculul produsului
scalar i aceasta folosete i la calculul normei unui vector innd cont c norma unui vector
se poate exprima n funcie de produsul scalar dintre doi vectori egali (||u|| = < u, u > ):
# include <iostream>
# include <iomanip>
# include <math.h>
using namespace std;
float ps(float u[20], float v[20], int n)
{ //functie ce calculeaza produsul scalar dintre vectorii
//dati ca primii do parametri ai functiei, ambii de dim. n
float s = 0;
for (int i=0;i<n;i++) s += u[i]*v[i];
return s;
}
int main() {
int n,i;
float u[20],v[20];
//se citesc dimensiunea comuna si elementele vectorilor
cout<<"Dati dimensiunea vectorilor: "; cin>>n;
cout<<"Dati elementele vectorului u:"<<endl;
for (i=0;i<n;i++)
{ cout<<"u["<<i+1<<"]="; cin>>u[i]; }
cout<<"Dati elementele vectorului v:"<<endl;
for (i=0;i<n;i++)
{ cout<<"v["<<i+1<<"]="; cin>>v[i]; }
//afisam valorile obtinute
cout<<"Produsul scalar dintre u si v = " << fixed<<
setprecision(2) << ps(u,v,n)<<endl;
cout<<"Norma vectorului u = "<<sqrt(ps(u,u,n))<<endl;
cout<<"Norma vectorului v = "<<sqrt(ps(v,v,n))<<endl;
return 0;
}
Rulare:
Dati
Dati
u[1]
u[2]
u[3]
u[4]
Dati
v[1]
ASD17AlgVectLab
v[2] = 2 <Enter>
v[3] = 3 <Enter>
v[4] = 6 <Enter>
Produsul scalar dintre u si v = 7
Norma vectorului u = 2.45
Norma vectorului v = 7.07
R3.
Enunul problemei: S se inverseze ordinea elementelor unui vector. De exemplu, pentru
v = (1 2 3 4 5) => v = (5 4 3 2 1)
Metoda de rezolvare: Pentru c se dorete inversarea efectiv a ordinii elementelor, nu doar
afiarea (cnd se putea parcurge vectorul de la final spre sfrit), putem parcurge elementele
pn la jumtatea vectorului i s interschimbm elementul curent cu simetricul su fa de
jumtatea vectorului: pentru un vector memorat ca n C/C++ v[0],...,v[n-1], acest lucru
presupune parcurgerea cu i=0,1,...,[n/2]-1 i interschimbarea componentelor v[i] i
v[n-1-i] (acesta se poate realiza prin intermediul unei variabile auxiliare de acelai tip cu
elementele vectorului: aux = v[i]; v[i] = v[n-1-i]; v[n-1-i] = aux;).
O descriere a algoritmului n C++:
# include <iostream>
using namespace std;
int main() {
float v[20];
int n,i;
//se citesc dimensiunea si elementele vectorului
cout<<"Dati dimensiunea vectorului: "; cin>>n;
cout<<"Dati elementele vectorului:"<<endl;
for (i=0;i<n;i++)
{ cout<<"v["<<i+1<<"]="; cin>>v[i]; }
//afisam vectorul initial
cout<<"Vectorul initial este: ";
for (i=0;i<n;i++) cout<<v[i]<<" ";
//inversam ordinea elementelor
for (i=0;i<n/2;i++)
{
float aux = v[i];
v[i] = v[n-i-1];
v[n-i-1] = aux;
}
//afisam vectorul cu elementele inversate
cout<<endl<<"Vectorul cu elementele inversate este: ";
for (i=0;i<n;i++) cout<<v[i]<<" ";
cout<<endl;
return 0;
}
Rulare:
Dati dimensiunea vectorului: 5 <Enter>
Dati elementele vectorului u:
u[1] = 1 <Enter>
u[2] = 2 <Enter>
u[3] = 3 <Enter>
u[4] = 4 <Enter>
u[4] = 4 <Enter>
Elementele vectorului initial: 1 2 3 4 5
Vectorul cu elementele inversate este: 5 4 3 2 1
ASD17AlgVectLab
R4.
Scriei un algoritm pentru a stabili dac un vector de numere reale este cresctor (vi vi+1,
pentru orice i = 1,, n-1) sau nu.
Metoda de rezolvare: O metod de descriere a algortitmului ar fi aceea n care la nceput se
presupune c vectorul v = (v1, v2, , vn) este cresctor, apoi se parcurge vectorul cu
i = 1,, n-1 i n cazul n care vi / vi+1, atunci nu este cresctor. n C/C++ apare decalajul de
indici: pentru vectorul v[0], , v[n-1], se parcurge vectorul cu i=0,,n-2 i n cazul n
care dou componente vecine nu sunt corespunztoare, adic v[i] > v[i+1], atunci nu este
cresctor (pentru aceasta putem folosi o variabil care va avea valoarea 1 n cazul n care
vectorul este cresctor i valoarea 0 n cazul n care vectorul nu este cresctor).
O descriere a algoritmului n pseudocod:
citete n,v1,...,vn *citim dimensiunea si elementele vectorului
crescator adevarat
pentru i = 1,n-1 repeta
daca v[i]>v[i+1] atunci
crescator fals
sau folosind funcie pentru a determina dac un vector este crescror sau nu
#include <iostream>
using namespace std;
int Crescator(float v[20], int n) {
for (int i=0;i<=n-2;i++)
if (v[i]>v[i+1]) return 0;
return 1;
}
ASD17AlgVectLab
int main() {
float v[20];
int n,i;
cout<<"n="; cin>>n;
cout<<"Dati elementele vectorului: "<<endl;
for (i=0;i<n;i++)
{
cout<<"v["<<i+1<<"]=";
cin >> v[i];
}
if (Crescator(v,n)==1) //sau if (Crescator(v,n))
cout<<"Sirul este crescator"<<endl;
else
cout<<"Sirul nu este crescator"<<endl;
return 0;
}
Observaie: Dac se cere determinarea faptului dac vectorul este monoton sau nu se poate
nti testa dac este monoton cresctor; n caz afirmativ se afieaz un mesaj, altfel se testeaz
similar dac vectorul este monoton descresctor.
#include <iostream>
using namespace std;
int main() {
int n,i,mon_cresc,mon_descresc;
float v[20];
cout<<"Dati dimensiunea vectorului: "; cin>>n;
cout<<"Dati elementele vectorului: "<<endl;
for (i=0;i<n;i++)
{ cout<<"v["<<i+1<<"]="; cin >> v[i]; }
mon_cresc = 1; // Presupunem ca vectorul este crescator
for (i=0;i<=n-2;i++)
if (v[i]>v[i+1]) { //elementele sunt "pe dos"
mon_cresc = 0;
break; //nu se merge mai departe (se iese din for)
}
if (mon_cresc) //sau if (mon_cresc==1)
cout<<"Sirul este crescator => monoton";
else {
mon_descresc=1; // presupunem ca vectorul este descrescator
for (i=0;i<=n-2;i++) //componentele care au element urmator
if (v[i]<v[i+1]) { //elementele sunt "pe dos"
mon_descresc=0;
break;
}
if (mon_descresc) //sau if (mon_descresc==1)
cout<<"Sirul este descrescator => monoton"<<endl;
else cout<<"Sirul nu este monoton"<<endl;
}
return 0;
}
ASD17AlgVectLab
R5.
Scriei un algoritm pentru a stabili dac un vector de numere reale are componentele n
progresie aritmetic sau nu.
Metoda de rezolvare: Un vector v = (v1, v2, , vn) are elementele n progresia aritmetic dac
v +v
( vi = i 1 i +1 pentru orice i = 2,, n-1 acele elemente care au vecini n stnga i n
2
dreapta). O metod de descriere a algoritmului ar fi aceea n care la nceput se presupune c
vectorul v = (v1, v2, , vn) are elementele n progresie aritmetic, apoi se parcurge vectorul cu
v +v
i = 2,, n-1 i n cazul n care vi =/ i 1 i +1 , atunci nu are elemntele n progresie
2
aritmetic. n C/C++ apare decalajul de indici: pentru vectorul v[0], , v[n-1], se parcurge
vectorul cu i=1,,n-2 i n cazul n care v[i] !=(v[i-1]+v[i+1])/2, atunci vectorul nu are
elementele n proresie aritmetic (pentru aceasta putem folosi o variabil care va avea
valoarea 1 n cazul n care vectorul are elementele n progresie aritmetic i valoarea 0 n
cazul n care vectorul nu are elementele n progresie aritmetic).
#include <iostream>
using namespace std;
int main() {
int n,i,p_a;
float v[20];
cout<<"n="; cin>>n;
cout<<"Dati elementele vectorului: "<<endl;
for (i=0;i<n;i++)
{
cout<<"v["<<i+1<<"]=";
cin >> v[i];
}
p_a = 1; // Presupunem ca vectorul este crescator
for (i=1;i<=n-2;i++) //componentele care au vecini
if (v[i] != (v[i-1]+v[i+1])/2) ////elementele sunt "pe dos"
{
p_a = 0;
//este clar ca nu este progresie aritmetica
break;
//se iese din for (nu mergem mai departe)
}
if (p_a) //sau if (p_a==1)
cout<<"Este progresie aritmetica"<<endl;
else
cout<<"Nu este progresie aritmetica"<<endl;
return 0;
}
ASD17AlgVectLab
Rulare:
Dati
Dati
v[1]
v[2]
v[3]
v[4]
v[5]
Este