vector<>. Sume parțiale pe matrice.vector<>
Până acum cunoașteți tipurile tradiționale de tablou,
care se declară cu sintaxa TipDeBază nume[dimensiune].
Ele funcționează, dar sunt moștenite din limbajul C (1972).
Au deci câteva neajunsuri:
În C++, spre deosebire de C, biblioteca standard ne pune la
dispoziție o alternativă, șablonul (template-ul) de tipuri
(clase) numit vector. Spre deosebire de tablourile
tradiționale:
size;
vector este în antetul
<vector> și în spațiul de nume
std (dacă avem using namespace std;
nu trebuie să scriem asta).
vector<int> name;
intint N;
cin >> N;
struct Structure {
int a, b;
}
vector<Structure> p(N);
p care memorează valori de tipul
Structure. Inițial are N
elemente, care sunt inițializate cu 0.
vector<short int> alphabet(26, -1);
short int, având valoarea inițială
de -1.
vector<int> x = y;
vector<vector<int>> x(N, vector<int>(M));
vector<int> a(5);
a[0]
a[1] = 67
a.size()
a.capacity()
a.resize(9)
a.resize(1)
a.reserve(32)
a.push_back(8)
a.pop_back()
Iteratorul este un obiect care indică o poziție din vector.
Este de tipul vector<TipDeBază>::iterator;
putem scrie auto pentru a nu folosi tot
numele.
a.begin()
a.end()
a.begin() + 1
a.end() - a.begin()
++a
a.erase(a.begin())
a.insert(a.begin(), 5)
a.insert(a.begin(), b.begin(), b.end())
a.begin().
Definim de acum funcția safe_get care va
returna valoarea de la indicele dat dintr-un vector, dacă
indicele e valid; în caz contrar, va returna 0. O folosim
pentru a nu fi nevoiți să testăm mereu dacă urmează să
scădem din poziția -1.
inline int safe_get(vector<int> const &a, int const i) {
if (i < 0 || a.size() <= i) {
return 0;
}
return a[i];
}
inline int safe_get(vector<vector<int>> const &a, int const i, int const j) {
if (i < 0 || a.size() <= i || j < 0 || a[0].size() <= j) {
return 0;
}
return a[i];
}
Să luăm ca exemplu matricea a:
| 12 | 0 | -4 | -8 | 3 |
| -1 | 6 | 7 | 8 | 10 |
| 4 | -3 | 9 | 1 | 4 |
| 11 | 7 | 9 | 8 | 12 |
Se calculează, pentru fiecare i și j, suma elementelor aflate
pe rânduri până la i și coloane până la j. Matricea
ps:
| 12 | 12 | 8 | 0 | 3 |
| 11 | 17 | 20 | 20 | 27 |
| 15 | 18 | 30 | 31 | 42 |
| 26 | 36 | 57 | 66 | 89 |
Cum calculăm această sumă?
| 20 | 20 | |||
| 30 | 31 | |||
Putem trece la suma pentru o anumită celulă folosind sumele anterioare:
ps[i][j] =
a[i][j]
+ safe_get(ps, i - 1, j)
+ safe_get(ps, i, j - 1)
- safe_get(ps, i - 1, j - 1);
Mai rămâne să calculăm suma pentru o anumită interogare.
De exemplu, de la (1; 1) până la
(3; 2). Notăm (i0; j0; i1; j1).
| 12 | 12 | 8 | 0 | 3 |
| 11 | 17 | 20 | 20 | 27 |
| 15 | 18 | 30 | 31 | 42 |
| 26 | 36 | 57 | 66 | 89 |
Putem să o calculăm folosind doar sumele calculate deja.
int get_sum(vector<vector<int>> &ps, int const i0, int const j0) {
return safe_get(ps, i1, j1)
- safe_get(ps, i1 - 1, j1)
- safe_get(ps, i1, j1 - 1)
+ safe_get(ps, i1 - 1, j1 - 1);
}