Bài 13.5: Bài tập thực hành Vector và Pair trong C++

Chào mừng các bạn quay trở lại với series học C++ của chúng ta! Sau khi đã làm quen với các khái niệm cơ bản, hôm nay chúng ta sẽ đi sâu vào thực hành với hai công cụ cực kỳ mạnh mẽphổ biến trong C++ Standard Library (STL): vectorpair.

vectorpair không chỉ là những thành phần cơ bản mà còn là nền tảng để xây dựng nên các cấu trúc dữ liệu và thuật toán phức tạp hơn. Nắm vững cách sử dụng chúng sẽ giúp code của bạn trở nên ngắn gọn, hiệu quảdễ bảo trì hơn rất nhiều.

Hãy cùng bắt tay vào thực hành ngay nhé!

1. Khám Phá vector - Mảng Động Quyền Năng

Trong C++, mảng truyền thống có kích thước cố định khi khai báo. Điều này có thể gây khó khăn khi bạn không biết chính xác số lượng phần tử cần lưu trữ từ đầu, dẫn đến lãng phí bộ nhớ hoặc tràn bộ nhớ (buffer overflow). vector ra đời để giải quyết vấn đề này.

vector là một container (bộ chứa) cung cấp khả năng quản lý một mảng động. Tức là kích thước của nó có thể tự động co giãn trong quá trình chạy chương trình. Điều này vô cùng tiện lợi!

1.1. Khai báo và Thêm phần tử

Bạn có thể khai báo một vector rỗng và thêm phần tử vào sau:

#include <vector>
#include <iostream>

int main() {
    vector<int> v;
    v.push_back(10);
    v.push_back(25);
    v.push_back(5);
    v.push_back(42);
    cout << "Kich thuoc hien tai cua vector: " << v.size() << endl;
    return 0;
}

Output:

Kich thuoc hien tai cua vector: 4
1.2. Truy cập phần tử

Bạn có thể truy cập các phần tử trong vector giống như mảng thông thường, bằng cách sử dụng toán tử [] hoặc hàm at().

#include <vector>
#include <iostream>
#include <string> // Can thiet cho string

int main() {
    vector<string> ds = {"Alice", "Bob", "Charlie", "David"};
    cout << "Phan tu tai chi so 0: " << ds[0] << endl;
    cout << "Phan tu tai chi so 2: " << ds[2] << endl;
    try {
        cout << "Phan tu tai chi so 3: " << ds.at(3) << endl;
        // cout << "Phan tu tai chi so 5: " << ds.at(5) << endl;
    } catch (const out_of_range& e) {
        cerr << "Loi: " << e.what() << endl;
    }
    return 0;
}

Output:

Phan tu tai chi so 0: Alice
Phan tu tai chi so 2: Charlie
Phan tu tai chi so 3: David
1.3. Duyệt (Iterate) vector

Có nhiều cách để duyệt qua tất cả các phần tử trong vector. Hai cách phổ biến nhất là dùng vòng lặp for truyền thống và vòng lặp for dựa trên phạm vi (range-based for loop).

#include <vector>
#include <iostream>

int main() {
    vector<double> ds = {7.5, 8.0, 6.5, 9.0, 7.0};
    cout << "Duyet bang chi so:" << endl;
    for (size_t i = 0; i < ds.size(); ++i) {
        cout << "Diem [" << i << "]: " << ds[i] << endl;
    }
    cout << "\nDuyet bang range-based for:" << endl;
    for (double d : ds) {
        cout << "Diem: " << d << endl;
    }
    return 0;
}

Output:

Duyet bang chi so:
Diem [0]: 7.5
Diem [1]: 8
Diem [2]: 6.5
Diem [3]: 9
Diem [4]: 7

Duyet bang range-based for:
Diem: 7.5
Diem: 8
Diem: 6.5
Diem: 9
Diem: 7

vector còn có nhiều thao tác khác như xóa phần tử (erase, pop_back), chèn phần tử (insert), xóa tất cả phần tử (clear), kiểm tra rỗng (empty), v.v. Nhưng với các thao tác cơ bản trên, bạn đã có thể bắt đầu sử dụng vector một cách hiệu quả rồi!

2. Làm Quen Với pair - Bộ Đôi Hoàn Hảo

Đôi khi, bạn cần lưu trữ hai giá trị có liên quan với nhau như một đơn vị duy nhất. Ví dụ: tọa độ (x, y), tên và tuổi, mã sản phẩm và số lượng, khóa và giá trị trong một dictionary đơn giản. Lúc này, pair là một lựa chọn tuyệt vời.

pair là một struct đơn giản trong STL, dùng để gói gọn hai giá trị thành một đối tượng duy nhất. Hai giá trị này có thể có kiểu dữ liệu khác nhau.

2.1. Khai báo và Khởi tạo pair

Bạn có thể khai báo và khởi tạo pair theo nhiều cách:

#include <utility>
#include <string>
#include <iostream>

int main() {
    pair<string, int> sv;
    sv.first = "Nguyen Van A";
    sv.second = 20;

    pair<double, double> td = {3.14, 2.71};

    auto sp = make_pair("SP001", "Laptop Dell");

    cout << "Sinh vien: " << sv.first << ", Tuoi: " << sv.second << endl;
    cout << "Toa do: (" << td.first << ", " << td.second << ")" << endl;
    cout << "San pham: " << sp.first << ", Ten: " << sp.second << endl;
    return 0;
}

Output:

Sinh vien: Nguyen Van A, Tuoi: 20
Toa do: (3.14, 2.71)
San pham: SP001, Ten: Laptop Dell

3. Sức Mạnh Tổng Hợp: vectorpair Kết Hợp

Đây là lúc mọi thứ trở nên thú vị. vector có thể chứa bất kỳ kiểu dữ liệu nào, bao gồm cả pair. Và ngược lại, pair cũng có thể chứa vector. Sự kết hợp này mở ra khả năng tạo ra các cấu trúc dữ liệu linh hoạt và mạnh mẽ.

3.1. vector của pair

Đây là trường hợp rất phổ biến. Bạn muốn lưu trữ một danh sách các cặp dữ liệu.

Ví dụ: Danh sách các điểm thi của sinh viên, mỗi điểm thi là một cặp (Tên môn học, Điểm số).

#include <vector>
#include <utility>
#include <string>
#include <iostream>

int main() {
    vector<pair<string, double>> ds;
    ds.push_back({"Toan", 8.5});
    ds.push_back(make_pair("Ly", 7.0));
    ds.push_back({"Hoa", 9.2});

    cout << "Bang diem cua sinh vien:" << endl;
    for (const auto& d : ds) {
        cout << "- Mon: " << d.first << ", Diem: " << d.second << endl;
    }
    return 0;
}

Output:

Bang diem cua sinh vien:
- Mon: Toan, Diem: 8.5
- Mon: Ly, Diem: 7
- Mon: Hoa, Diem: 9.2

Ví dụ khác: Danh sách các điểm trên mặt phẳng 2D.

#include <vector>
#include <utility>
#include <iostream>

int main() {
    vector<pair<double, double>> ds;
    ds.push_back({1.0, 2.5});
    ds.push_back({-3.0, 0.0});
    ds.push_back({5.5, -1.2});

    cout << "Danh sach cac diem 2D:" << endl;
    for (const auto& d : ds) {
        cout << "  (" << d.first << ", " << d.second << ")" << endl;
    }
    return 0;
}

Output:

Danh sach cac diem 2D:
  (1, 2.5)
  (-3, 0)
  (5.5, -1.2)
3.2. pair chứa vector

Trường hợp này ít gặp hơn trong các bài tập cơ bản nhưng cũng là một khả năng mạnh mẽ. Bạn muốn gói gọn hai thứ, trong đó có một thứ là một danh sách.

Ví dụ: Thông tin của một học sinh bao gồm tên và một danh sách các điểm số.

#include <vector>
#include <utility>
#include <string>
#include <iostream>
#include <numeric> // Can thiet cho accumulate

int main() {
    pair<string, vector<int>> hs;
    hs.first = "Tran Thi B";
    hs.second = {7, 8, 9, 6, 10};

    cout << "Ten hoc sinh: " << hs.first << endl;

    cout << "Cac diem: ";
    for (int d : hs.second) {
        cout << d << " ";
    }
    cout << endl;

    double tong = accumulate(hs.second.begin(), hs.second.end(), 0.0);
    double dtb = tong / hs.second.size();
    cout << "Diem trung binh: " << dtb << endl;
    return 0;
}

Output:

Ten hoc sinh: Tran Thi B
Cac diem: 7 8 9 6 10 
Diem trung binh: 8

4. Một Vài Bài Tập Nhỏ Để Củng Cố

Hãy thử áp dụng những gì đã học vào các bài tập nhỏ sau:

  • Bài tập 1: Tạo một vector lưu trữ 5 số thực do người dùng nhập từ bàn phím. Sau đó, tìm và in ra số lớn nhất trong vector đó.
  • Bài tập 2: Tạo một vector lưu trữ các cặp (tên thành phố, dân số). Nhập dữ liệu cho 3-4 thành phố. In ra tên thành phố có dân số lớn nhất.
  • Bài tập 3: Tạo một pair chứa (Tên đội bóng, Danh sách điểm số trong các trận đấu). Khởi tạo dữ liệu và tính điểm trung bình của đội bóng đó.

Những bài tập này sẽ giúp bạn củng cố kiến thức về cách khai báo, thêm, truy cập và duyệt vector cũng như cách làm việc với các thành phần của pair.

vectorpair là những công cụ không thể thiếu trong hộp đồ nghề của một lập trình viên C++. Việc thực hành thường xuyên với chúng sẽ giúp bạn tự tin hơn khi xử lý các vấn đề lập trình thực tế.

Chúc các bạn học tốt và thực hành hiệu quả!

Comments

There are no comments at the moment.