You are on page 1of 18

Bài 9

NỘI DUNG BÀI 9


Lớp vector: kiểu đối tượng dữ liệu với ngữ nghĩa
mảng
Sử dụng vector cho các thao tác trên mảng số liệu:
1. Các cách sử dụng vector khai báo và tạo mảng.
Dùng các hàm trong lớp vector để thực hiện các
thao tác nhập vào, in ra, sửa, chèn, xóa, sắp xếp
các phần tử của mảng
2. Các bài toán liên quan đến mảng hay vector:
 Tính toán thống kê (tổng, trung bình, max, min, phân
loại)
 Tính độ dài vector, tổng, tích vô hướng của 2 vector
 Tìm kiếm các phần tử thỏa mãn điều kiện cho trước.
 Kiểm tra một mảng có thỏa mãn một tính chất không
 Tạo mảng mới từ các phần tử của mảng cũ thỏa mãn
một / một số tính chất cho trước
Bài 9

Các thao tác trên mảng – sử dụng vector


 Trong các bài toán kinh tế hay kỹ thuật, cần phải thu nhận
phân tích và xử lí các dữ liệu có liên quan đến một phép
đo hay sự mô phỏng và phân tích, chúng ta thường phải
nhập, sửa dữ liệu, tính toán trên dữ liệu, thêm vào, bỏ đi một
số dữ liệu, và cần một cách để lưu trữ và quản lý chúng.
Điều này giống như công việc của một mảng các phần tử.
 Việc đưa khái niệm vector cột trong toán học vào kiểu
vector trong thư viện chuẩn của C++, và cụ thể hơn là vào
vector< double > dường như rất có lí. Nhưng một vector
trong C++ không cung cấp một ý niệm nào về "hàng" hay
"cột". vector trong C++ chỉ lưu trữ một dãy các phần tử.
Nếu ta cố ý xem một dãy như vậy là một vector cột thì đó
chỉ là cách hiểu của ta khi giải thích thuật toán, chứ không
phải là cách hiểu của ngôn ngữ C++.
Bài 9

Các hàm thao tác trên vector


Hàm thành viên Ý nghĩa
w.push_back(e) Đẩy phần tử e vào cuối vector w
w.pop_back() Xóa phần tử cuối của vector w
w.clear() Làm rỗng vector w và đặt lại cỡ của w bằng 0
w.empty() Trả về true nếu vector w rỗng
w.begin() Lấy danh sách các phần tử của w từ vị trí đầu
w.end() Lấy danh sách của phần tử cuối cùng của w
w.erase(loc) Xóa một phần tử của w tại loc trong danh sách
w.erase(start, end) Xóa các phần tử của w từ start đến trước end
w.insert(loc, e) Chèn e vào w tại vị trí loc trong danh sách
w.insert(loc, n, e) Chèn n p. tử e vào w từ vị trí loc trong d sách
w.assign(n, e) Gán n phần tử e vào vector w
w.swap(v) Đổi các phần tử (và cỡ) của w cho v
sort(start, end) Sắp xếp các phần tử của w từ start đến end
v=w Gán vector w cho vector v
w.size() Trả về số phần tử của vector w
w.resize(n) Đặt lại cỡ của vector w
Bài 9

Các thủ tục nhập vào và in ra một vector


template <class T>
void nhapVector(vector < T > & v, unsigned N) { // N là cỡ của v
T phanTu;
for (unsigned i = 0; i < N; i++) {
cout << "Phan tu thu " << i << ": " ;
cin >> phanTu;
v.push_back( phanTu ) ; // Đẩy phanTu vào cuối vector
}
}

template <class T> void inVector(vector<T> & w) {


for (unsigned i = 0; i < w.size(); i++)
cout <<w[ i ] << “\t“ ; // In các phần tử cách nhau 1 tab
}
Bài 9

Các cách chèn thêm phần tử vào vector


- Khai báo 2 vector kiểu nguyên, rỗng
vector <double> v1, v2;
- Gán năm phần tử 0.5 cho v2
v2.assign(5, 0.5) ;
- Chèn một phần tử vào trước một phần tử trong danh sách
v1.insert(v1.begin() + 3, -2.5) ;
v1.insert(v1.begin(), 2, -1.5) ;
- Chèn các phần tử vào sau một phần tử trong danh sách
v1.push_back(1) ;
v1.insert(v1.end() -1, 4.5) ;
v1.insert(v1.end(), 3, 4) ;
- Ghép vector v2 vào cuối vector v1
v1.insert(v1.end(), v2.begin(), v2.end());
Bài 9

Cách gán, sắp xếp, xóa các phần tử vector


• Xóa toàn bộ các phần tử của vector
v.clear();
• Xóa phần tử cuối cùng của vector
v.pop_back();
• Xóa một phần tử bên trong danh sách
v.erase(v.begin()+3); // Xóa phần tử thứ 4
• Xóa các phần tử theo danh sách
v.erase(v.begin()+2, v.end()-2);
• Sắp xếp vector theo thứ tự tăng dần
sort(v.begin(), v.end());
• Đổi các phần tử (và cỡ) của 2 vector có cùng kiểu dữ
liệu
v.swap(u);
• Phép gán một vector cho vector khác cùng kiểu
vector <T> u = v;
Bài 9

Tông hai vector, tích vô hướng hai vector


Ví dụ : Viết các hàm tính tổng và tích vô hướng của hai
vector N chiều các số nguyên / thực

template <class T> vector < T > tongVector (vector < T > a,
vector < T > b) {
vector < T > c;
c.resize(a.size());
for (unsigned i = 0 ; i < a.size() ; i++) c[i] = a[i] + b[i];
return c;
}

template <class T> T tichVector (vector < T > a, vector < T > b) {
T tich = 0;
for (unsigned i = 0 ; i < a.size() ; i++) tich = tich + a[i] * b[i];
return tich;
}
Bài 9

Tìm kiếm – tính toán trên dãy số


Ví dụ 1: Tìm số lớn nhất trong một dãy số
double timMax(vector <double> v) {
double max = v[0];
for (unsigned i = 1; i < v.size(); i++)
if ( max < v[i]) max = v[i];
return max;
}
Ví dụ 2: Tính trung bình cộng của một dãy số
double TBC(vector <double> v) {
double S = 0;
assert(v.size()); // Xác nhận vector không rỗng
for (unsigned i = 0; i < v.size(); i++) S = S + v[i];

return S / v.size();
}
Bài 9

Kiểm tra điều kiện của một dãy số


Ví dụ: Kiểm tra một dãy số có phải là dãy Fibonaci - dãy số
nguyên có hai phần tử đầu tiên đều là 1, các phần tử khác là
tổng của hai phần tử đứng trước nó, ví dụ: 1, 1, 2, 3, 5, 8, 13, …
bool dayFibonaci(vector <unsigned> v) {
bool OK = true;
unsigned i = 2;
assert(v.size() != 0 && v[0] == 1 && v[1] == 1); // KT đ/k đầu
while (i < v.size()) {
if (v[i] != v[i-1] + v[i-2]) {
OK = false;
break;
}
i++;
}
return OK;
}
Bài 11

Tạo mới, sửa đổi dãy số theo điều kiện (1)


Ví dụ 1: Viết hàm chèn số phần tử dương của một dãy số
(nguyên hay thực) cho trước vào vị trí đầu tiên và tổng các
phần tử dương vào vị trí cuối cùng của dãy này (để KT).
template <class T> void chenDay (vector <T> & v) {
int demDuong = 0;
T tongDuong = 0;
for (unsigned i = 0; i < v.size(); i++)
if (v[i] > 0) {
demDuong = demDuong + 1;
tongDuong = tongDuong + v[i];
}
v.insert(v.begin(), demDuong);
v.push_back(tongDuong);
}
Bài 9

Tạo mới, sửa đổi dãy số theo điều kiện (2)


Ví dụ 2: Viết hàm tạo dãy mới gồm toàn các số chia hết cho 3
từ một dãy số nguyên cho trước.
vector <int> dayChiaHet (vector <int> v) {//ham tra ve mot vector
assert(v.size()); vector <int> w;
for (unsigned i = 0; i < v.size(); i++)
if (v[ i ] % 3 == 0) w.push_back(v[ i ] ) ;
return w;
}
Ví dụ 3: Viết hàm loại bỏ khỏi một dãy số (nguyên hay thực)
cho trước tất cả các phần tử 0.
template <class T> void dayKhac0 (vector <T> & v) {
assert(v.size()); vector <int> w = v; unsigned k=0;
for (unsigned i = 0; i < w.size(); i++)
if (w[ i ] == 0) { v.erase(v.begin() + i - k); k++; }
}
Bài 9

Tạo mới, sửa đổi dãy số theo điều kiện (3)


Ví dụ 4 Viết chương trình tạo dãy số nguyên tố trong N số tự nhiên
#include <iostream>
#include <vector>
using namespace std;
void inVector(vector< unsigned > & w);
bool soNguyenTo(unsigned x);
int main () {
vector < unsigned > v(1, 1); // Khởi tạo vector v với số NT = 1
unsigned N = 100;
cout << “N = “ ; cin >> N;
for (unsigned i = 2; i <= N; i++)
if (soNguyenTo(i)) v.push_back(i);
cout << "Co " << v.size() << " so NT trong " << N << " so dau:” ;
inVector(v);
return 0;
}
Bài 9

Tạo mới, sửa đổi dãy số theo điều kiện (4)


Ví dụ 5: Viết hàm tạo một dãy nhận các phần tử của một dãy
số
thực đã cho theo thứ tự đảo ngược.
Thuật toán:
•Tạo vector w rỗng.
•Nhập một vector v có n phần tử là các số thực.
•Duyệt qua v, bắt đầu từ phần tử cuối cùng ( i = chỉ số cuối )
•Trong khi (chưa duyệt đến phần tử đầu tiên) lặp các việc:
Gán cho e giá trị của phần tử thứ i của dãy v
Đẩy e vào vector w
Duyệt đến phần tử thứ i-1 của v
void daoNguoc(vector < double > & v, vector < double > & w) {
double e;
for (int i = v.size()-1; i >= 0 ; i--) { // vòng lặp lùi
e = v[i];
w.push_back(e);
}
}
Bài 9

Tạo mới, sửa đổi dãy số theo điều kiện (5)


Ví dụ 5 (tiếp): Viết chương trình kiểm tra hàm daoNguoc
void daoNguoc(vector < double > & v, vector < double > & w) ;
int main () {
vector <double> v1, v2;
cout << "Cho biet co cua vector v1: “ ;
unsigned n;
cin >> n;
nhapVector(v1, n);
cout << "\nVector v1: " << endl;
inVector(v1);
// Gọi thủ tục tạo vector đảo ngược
daoNguoc(v1, v2);
cout << "\nVector dao nguoc: " << endl;
inVector(v2);
return 0;
}
Bài 9

Làm trơn dữ liệu (1)


Đặt vấn đề:
• Rời rạc hóa hay số hóa là một kỹ thuật bắt buộc của máy
tính hữu hạn để mô phỏng các dữ liệu quan sát được.
• Làm trơn là một kỹ thuật sử dụng trong mô phỏng, làm nhỏ
đi các khác biệt.
• Làm trơn được sử dụng để dự đoán xu hướng, loại bỏ các
giá trị nhiễu.
Thuật toán trung bình trượt:
•Giá trị trơn Di của một điểm di, quan hệ với các điểm liền kề
trước di-1 và sau di+1 được xác định theo công thức trung bình
của 3 điểm.
• Giá trị trơn D1 và Dn tại hai đầu mút được xác định theo
công thức trung bình của 2 điểm như sau.
d i 1  d i  d i 1 d1  d 2 d n1  d n
Di  D1  Dn 
3 2 2
Bài 9

Làm trơn dữ liệu (2)


Ví dụ: Kết quả làm trơn số lượng hàng bán ra trong 12 tháng

Tháng 1 2 3 4 5 6 7 8 9 10 11 12
200 135 195 207 310 175 155 130 220 277 235 263
Lượng
hàng
167.5 176.7 179 237.3 230.7 213.3 153.3 168.3 209 244 258.3 249
TB trượt

Lương hàng Trung bình


bán ra trượt

350

300

250

200

150

100

50

0
0 2 4 6 8 10 12 14
Bài 9

Làm trơn dữ liệu (3)


void tbTruot(const vector< double > & d, vector< double > & D)
{
for (unsigned i = 1; i < d.size() - 1; i++)
D[i] = ( d[i-1] + d[i] + d[i+1] ) / 3. ;
D[0] = (d[0] + d[1] ) / 2..;
D[D.size()] = (d[d.size()] + d[d.size()-1]) / 2. ;
}
int main() {
unsigned N = 12; // số tháng lấy TB trượt
vector< double > hang, TB;
nhapVector(hang, N);
TB.resize(hang.size()); // Hai vector phải có cùng cỡ
tbTruot(hang, TB); // Gọi thủ tục tính TB trượt
inVector(TB);
return 0;
}
Bài 9

Bài tập buổi 9

• Chạy lại các ví dụ trong bài giảng


• Trả lời các câu hỏi 20 và 21
• Làm bài tập chương số 6 của chương 6
• Tải bài tập thực hành buổi 7 ở trang web
môn học về làm.

You might also like