План:
Използване на вектори за съхраняване на данни
Индекси на вектори
Векторите като параметри и стойности на функции
Вектор като връщана стойност на функция
Прости алгоритми за вектори - вмъкване и изтриване
Успоредни вектори и вектор от обекти
** Използване на вектори за съхраняване на данни
* Векторът е множество от данни от един и същи тип (обект),
като данните са номерирани с последователни неотрицателни цели
числа.
Пример: Дефиниция на вектор с 10 елемента тип double
(конструиране на обект salaries):
vector<double> salaries(10);
Клас-шаблон (vector) и параметър на шаблона (double).
Пример: Достъп до елементите на вектора - на елемента с
индекс 4 се задава стойност 355.
salaries[4] =
355;
Елементите на вектора се номерират, започвайки от 0 (както
позициите в низа).
salaries[0] - първи елемент
salaries[1] - втори елемент
salaries[2] - трети елемент
salaries[3] - четвърти елемент
...
salaries[9] - десети елемент
Последователни клетки в паметта на
компютъра.
Индекс |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
Стойност |
? |
? |
? |
? |
355 |
? |
? |
? |
? |
? |
// salvect.cpp
#include <iostream>
#include <vector>
using namespace std;
int main()
{ vector<double> salaries;
// въвеждане на стойности на елементите на вектора
bool more = true;
while (more)
{ double s;
cout << "Please enter a salary, 0 to quit: ";
cin >> s;
if (s == 0) more = false;
else salaries.push_back(s);
}
// намиране на най-големия елемент на вектора
double highest = salaries[0];
int i;
for (i = 1; i < salaries.size(); i++)
if (salaries[i] > highest)
highest = salaries[i];
// извеждане на стойностите на елементите на вектора с отбелязване на най-големия елемент
for (i = 0; i < salaries.size(); i++)
{ if (salaries[i] == highest)
cout << "highest value => ";
cout << salaries[i] << "\n";
}
return 0;
}
nkirov@cpp % ./a.out Please enter a salary, 0 to quit: 2500 Please enter a salary, 0 to quit: 3200 Please enter a salary, 0 to quit: 1850 Please enter a salary, 0 to quit: 3000 Please enter a salary, 0 to quit: 2300 Please enter a salary, 0 to quit: 0 2500 highest value => 3200 1850 3000 2300 |
/* v е параметър-променлива */ //
константен псевдоним
/* v is a variable parameter */ // constant reference
double average(vector<double>
v) // const vector<double>&
v
{
if (v.size() == 0) return 0;
int i;
double sum = 0;
for (i = 0; i <
v.size(); i++) sum = sum + v[i];
return sum / v.size();
}
int main()
{
vector<double> salaries(5);
salaries[0] = 35000.0;
salaries[1] = 63000.0;
salaries[2] = 48000.0;
salaries[3] = 78000.0;
salaries[4] = 51500.0;
double avgsal =
average(salaries);
cout << "The
average salary is " << avgsal << "\n";
return 0;
}
The average salary is 55100 |
Пример: Промяна на стойностите на елементите на вектор - заплатите се увеличават с 4.5 процента. (Използва се параметър-псевдоним!)
// raisesal.cpp
#include <iostream>
#include <vector>
using namespace std;
/* s е параметър-псевдоним */
void
raise_salaries(vector<double>& s, double p)
{
int i;
for (i=0; i<s.size();
i++) s[i] = s[i]*(1 + p/100);
}
int main()
{
vector<double> salaries(5);
salaries[0] = 35000.0;
salaries[1] = 63000.0;
salaries[2] = 48000.0;
salaries[3] = 78000.0;
salaries[4] = 51500.0;
raise_salaries(salaries,
4.5);
int i;
for (i = 0; i <
salaries.size(); i++)
cout
<< salaries[i] << "\n";
return 0;
}
36575 65835 50160 81510 53817.5 |
* Вектор като връщана стойност на функция
Пример: Намиране на всички стойности, които попадат в
определен интервал.
Функцията връща стойност от тип vector<double>.
// between.cpp
#include <iostream>
#include <vector>
using namespace std;
/* връщаната
стойност
на функцията е от тип vector */
vector<double>
between(vector<double>
v, double low, double high)
{
vector<double> result;
int i;
for (i = 0; i < v.size();
i++)
if (low <= v[i] and v[i]
<= high) result.push_back(v[i]);
return result;
}
int main()
{
vector<double> salaries(5);
salaries[0] = 35000.0;
salaries[1] = 63000.0;
salaries[2] = 48000.0;
salaries[3] = 78000.0;
salaries[4] = 51500.0;
vector<double>
midrange_salaries
=
between(salaries, 45000.0, 65000.0);
int i;
for (i = 0; i <
midrange_salaries.size(); i++)
cout
<< midrange_salaries[i] << "\n";
return 0;
}
63000 48000 51500 |
// matches.cpp
#include <iostream>
#include <vector>
using namespace std;
vector<int> find_all_between(vector<double> v,
double low, double high)
/* ЦЕЛ:
намира
елементите на вектора a
със
стойност по-голяма от low и по-малка от high
ПОЛУЧАВА: вектор a и
число t
ВРЪЩА:
вектор с индексите на намерените елементи,
по-големи
от t
*/
{
vector<int> pos;
for (int i = 0; i < v.size(); i++)
if (low <= v[i] && v[i] <= high) pos.push_back(i);
return pos;
}
int main()
{
vector<double> salaries(5);
salaries[0] = 35000.0;
salaries[1] = 63000.0;
salaries[2] = 48000.0;
salaries[3] = 78000.0;
salaries[4] = 51500.0;
vector<int> matches
= find_all_between(salaries, 45000.0, 65000.0);
for (int j = 0; j < matches.size(); j++)
cout << salaries[matches[j]] << "\n";
return 0;
}
63000 48000 51500 |
void erase(vector<string>&
a, int pos)
/* ЦЕЛ:
отстранява елемент с индекс pos
от вектор a
ПОЛУЧАВА: вектор a и
индекс pos
ЗАБЕЛЕЖКА: редът на
оставащите елементи се запазва
*/
{
int i;
for (i = pos; i <
a.size()-1; i++) a[i] = a[i+1];
a.pop_back();
}
void print(vector<string> a)
{
int i;
for (i = 0; i <
a.size(); i++)
cout
<< "[" << i << "] " << a[i] <<
"\n";
}
int main()
{
vector<string> staff(5);
staff[0] = "Cracker,
Carl";
staff[1] = "Hacker,
Harry";
staff[2] = "Lam, Larry";
staff[3] = "Reindeer,
Rudolf";
staff[4] = "Sandman,
Susan";
print(staff);
int pos;
cout << "Remove
which element? ";
cin >> pos;
erase(staff, pos);
print(staff);
return 0;
}
[0] Cracker, Carl [1] Hacker, Harry [2] Lam, Larry [3] Reindeer, Rudolf [4] Sandman, Susan Remove which element? 2 [0] Cracker, Carl [1] Hacker, Harry [2] Reindeer, Rudolf [3] Sandman, Susan |
Пример:
Вмъкване на елемент във вектор.
Целта е да се вмъкне нов елемент на вектора на зададена позиция
и всички елементи след него да се преместят с една позиция
напред - т.е. индексите на елементите след новия елемент да се
увеличат с 1.
// insert.cpp
#include <iostream>
#include <string>
#include <vector>
using namespace std;
void
insert(vector<string>& a, int pos, string s)
/* ЦЕЛ:
вмъква елемент s с индекс pos във вектора a
ПОЛУЧАВА: вектор a,
индекс pos и елемент s
ЗАБЕЛЕЖКА: редът на
останалите елементи се запазва
*/
{
int last = a.size() - 1;
a.push_back(a[last]);
int i;
for (i = last; i >
pos; i--) a[i] = a[i - 1];
a[pos] = s;
}
void print(vector<string> a)
{
int i;
for (i = 0; i <
a.size(); i++)
cout
<< "[" << i << "] " << a[i] <<
"\n";
}
int main()
{
vector<string> staff(5);
staff[0] = "Cracker,
Carl";
staff[1] = "Hacker,
Harry";
staff[2] = "Lam, Larry";
staff[3] = "Reindeer,
Rudolf";
staff[4] = "Sandman,
Susan";
print(staff);
int pos;
cout << "Insert
before which element? ";
cin >> pos;
insert(staff, pos, "New,
Nina");
print(staff);
return 0;
}
[0] Cracker, Carl [1] Hacker, Harry [2] Lam, Larry [3] Reindeer, Rudolf [4] Sandman, Susan Insert before which element? 1 [0] Cracker, Carl [1] New, Nina [2] Hacker, Harry [3] Lam, Larry [4] Reindeer, Rudolf [5] Sandman, Susan |
** Успоредни вектори и вектор от обекти
* Два вектора са успоредни, ако съществува логическа
(смислова) връзка между елементите им с еднакви индекси.
// bestval1.cpp
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
vector<string> names;
vector<double> prices;
vector<int> scores;
double best_price = 1;
int best_score = 0;
int best_index = -1;
bool more = true;
while (more)
{
string next_name;
cout << "Please enter the model name: ";
getline(cin, next_name);
names.push_back(next_name);
double next_price;
cout << "Please enter the price: ";
cin >> next_price;
prices.push_back(next_price);
int next_score;
cout << "Please enter the score: ";
cin >> next_score;
scores.push_back(next_score);
string remainder; /* read remainder of line */
getline(cin, remainder);
if (next_score / next_price > best_score / best_price)
{ best_index = names.size() - 1;
best_score = next_score;
best_price = next_price;
}
cout << "More data? (y/n) ";
string answer;
getline(cin, answer);
if (answer != "y") more = false;
}
for (int i = 0; i < names.size(); i++)
{
if (i == best_index) cout << "best value => ";
cout << names[i]
<< " Price: " << prices[i]
<< " Score: " << scores[i] << "\n";
}
return 0;
}
nkirov@cpp % c++ bestval1.cpp nkirov@cpp % ./a.out Please enter the model name: abc Please enter the price: 1000 Please enter the score: 75 More data? (y/n) y Please enter the model name: xyz 23 Please enter the price: 1200 Please enter the score: 85 More data? (y/n) n best value => abc Price: 1000 Score: 75 xyz 23 Price: 1200 Score: 85 |
* Успоредните вектори обикновено създават проблеми и трябва да
се избягват.
Пример: Задачата за най-добро отношение цена-качество на
компютри с отбелязване на най-добрата оферта в списъка от входа -
решение без успоредни вектори и с класове (вектор от обекти).
// bestval2.cpp
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class Product {
public:
Product();
void read();
bool is_better_than(Product b) const;
void print() const;
private:
string name;
double price;
int score;
};
Product::Product()
{
price = 0;
score = 0;
}
void Product::read()
{
cout << "Please enter the model name: ";
getline(cin, name);
cout << "Please enter the price: ";
cin >> price;
cout << "Please enter the score: ";
cin >> score;
string remainder; /* read remainder of line */
getline(cin, remainder);
}
bool Product::is_better_than(Product b) const
{
if (price == 0) return false;
if (b.price == 0) return true;
return score / price > b.score / b.price;
}
void Product::print() const
{
cout << name
<< " Price: " << price
<< " Score: " << score << "\n";
}
int main()
{
vector<Product> products;
Product best_product;
int best_index = -1;
bool more = true;
while (more)
{
Product next_product;
next_product.read();
products.push_back(next_product);
if (next_product.is_better_than(best_product))
{
best_index = products.size() - 1;
best_product = next_product;
}
cout << "More data? (y/n) ";
string answer;
getline(cin, answer);
if (answer != "y") more = false;
}
for (int i = 0; i < products.size(); i++)
{
if (i == best_index) cout << "best value => ";
products[i].print();
}
return 0;
}