Bài 12.2: Bài tập thực hành xử lý mảng 1 chiều cơ bản trong C++

Chào mừng trở lại với chuỗi bài viết về C++ của FullhouseDev! Hôm nay, chúng ta sẽ không chỉ học lý thuyết mà còn cùng nhau xắn tay áo lên để thực hành những kỹ năng xử lý mảng 1 chiều - một cấu trúc dữ liệu không thể thiếu trong bất kỳ ngôn ngữ lập trình nào, đặc biệt là C++. Nếu bạn đã nắm được khái niệm về mảng, thì đây chính là lúc để biến lý thuyết thành hành động!

Bài viết này tập trung vào các thao tác cực kỳ cơ bản nhưng cũng cực kỳ quan trọng: từ việc khai báo, nhập xuất dữ liệu cho mảng, cho đến những phép xử lý đơn giản như tính tổng, tìm kiếm phần tử lớn nhất/nhỏ nhất, hay đếm số lần xuất hiện của một giá trị nào đó. Hãy cùng bắt đầu hành trình làm quen với mảng 1 chiều một cách thực tế nhất trong C++ nhé!

1. Khai báo và Khởi tạo Mảng 1 Chiều

Trước khi làm bất cứ điều gì với mảng, chúng ta cần khai báo nó. Mảng 1 chiều trong C++ có kích thước cố định tại thời điểm khai báo (trừ khi dùng mảng động, nhưng đó là chủ đề sau này).

Đây là cách bạn khai báo một mảng:

#include <iostream>

int main() {
    // Khai báo mot mang so nguyen co 5 phan tu
    int arr[5];

    // Khai bao va khoi tao gia tri ban dau
    int numbers[] = {10, 20, 30, 40, 50};

    // Khai bao va khoi tao tat ca cac phan tu bang 0 (cho mang co kich thuoc lon)
    int data[100] = {0};

    // Ban cung co the khai bao voi kich thuoc la hang so
    const int SIZE = 7;
    double temperatures[SIZE];

    cout << "Mang numbers co kich thuoc la: " << sizeof(numbers) / sizeof(numbers[0]) << endl;
    cout << "Phan tu dau tien cua numbers: " << numbers[0] << endl; // Truy cap phan tu theo index (bat dau tu 0)

    return 0;
}

Giải thích code:

  • int arr[5];: Khai báo một mảng tên là arr có thể chứa 5 số nguyên. Các giá trị ban đầu của các phần tử này là không xác định (rác).
  • int numbers[] = {10, 20, 30, 40, 50};: Khai báo và khởi tạo ngay mảng numbers với các giá trị đã cho. C++ sẽ tự động tính kích thước mảng là 5 dựa trên số lượng phần tử bạn cung cấp.
  • int data[100] = {0};: Khai báo mảng data 100 phần tử và khởi tạo tất cả chúng bằng 0. Nếu bạn chỉ để {} thì chỉ phần tử đầu tiên là 0, còn lại không xác định. Với {0} thì tất cả là 0.
  • const int SIZE = 7; double temperatures[SIZE];: Sử dụng một hằng số để xác định kích thước mảng là một cách làm tốt, giúp code dễ đọc và dễ thay đổi kích thước sau này. Mảng này chứa các số thực (double).
  • sizeof(numbers) / sizeof(numbers[0]): Đây là một "mẹo" nhỏ để tính kích thước (số lượng phần tử) của mảng khi nó được khai báo và khởi tạo ngay lập tức. sizeof(numbers) trả về tổng kích thước của mảng tính bằng byte, sizeof(numbers[0]) trả về kích thước của một phần tử. Chia hai giá trị này ta được số lượng phần tử. Lưu ý: Cách này chỉ hoạt động với mảng được khai báo như biến cục bộ hoặc biến toàn cục.
  • numbers[0]: Để truy cập một phần tử trong mảng, ta dùng tên mảng và chỉ số (index) của phần tử đặt trong cặp ngoặc vuông []. Chỉ số của phần tử đầu tiên luôn là 0.

2. Nhập dữ liệu từ người dùng vào Mảng

Một trong những thao tác phổ biến là cho phép người dùng nhập dữ liệu vào mảng. Chúng ta thường sử dụng vòng lặp for và đối tượng cin.

Ví dụ: Nhập 3 số nguyên vào một mảng:

#include <iostream>

int main() {
    const int SIZE = 3;
    int my_array[SIZE]; // Khai bao mang

    cout << "Hay nhap " << SIZE << " so nguyen vao mang:" << endl;

    // Dung vong lap de nhap tung phan tu
    for (int i = 0; i < SIZE; ++i) {
        cout << "Nhap phan tu thu " << i << ": ";
        cin >> my_array[i]; // Nhap gia tri cho phan tu tai index i
    }

    cout << "\nBan vua nhap xong." << endl;
    // De kiem tra, co the in ra sau khi nhap (xem phan tiep theo)

    return 0;
}

Giải thích code:

  • Chúng ta dùng hằng số SIZE để dễ dàng quản lý kích thước mảng.
  • Vòng lặp for (int i = 0; i < SIZE; ++i) sẽ chạy từ i = 0 đến i = SIZE - 1, tương ứng với các chỉ số hợp lệ của mảng.
  • Trong mỗi lần lặp, cout thông báo cho người dùng biết họ đang nhập phần tử thứ mấy (theo index).
  • cin >> my_array[i]; đọc giá trị người dùng nhập từ bàn phím và lưu vào phần tử tại vị trí i của mảng my_array.

3. Xuất (In) dữ liệu từ Mảng

Để xem nội dung của mảng, chúng ta cũng sử dụng vòng lặp for, nhưng lần này là với đối tượng cout.

Ví dụ: In tất cả các phần tử của một mảng:

#include <iostream>

int main() {
    int scores[] = {85, 90, 78, 95, 88};
    const int SIZE = sizeof(scores) / sizeof(scores[0]); // Tinh kich thuoc

    cout << "Cac diem trong mang la:" << endl;

    // Dung vong lap de in tung phan tu
    for (int i = 0; i < SIZE; ++i) {
        cout << scores[i] << " "; // In gia tri cua phan tu tai index i, kem theo khoang trang
    }
    cout << endl; // In xuong dong ket thuc

    return 0;
}

Giải thích code:

  • Chúng ta xác định kích thước mảng bằng cách chia sizeof(scores) cho sizeof(scores[0]).
  • Vòng lặp for duyệt qua tất cả các chỉ số từ 0 đến SIZE - 1.
  • cout << scores[i] << " "; in giá trị của phần tử tại chỉ số i, theo sau là một khoảng trắng để phân tách các số.
  • cout << endl; in ký tự xuống dòng sau khi in hết mảng, giúp output gọn gàng hơn.

4. Thực hành Xử lý Dữ liệu Cơ bản trên Mảng

Giờ là lúc thực sự "xử lý"! Chúng ta sẽ xem xét một vài bài tập cơ bản thường gặp.

4.1. Tính Tổng các Phần tử trong Mảng

Bài tập này giúp bạn làm quen với việc duyệt mảng và tích lũy giá trị.

#include <iostream>

int main() {
    int numbers[] = {10, 25, 5, 30, 15};
    const int SIZE = sizeof(numbers) / sizeof(numbers[0]);

    int sum = 0; // Bien de luu tong, khoi tao bang 0

    // Duyet mang va cong don vao bien sum
    for (int i = 0; i < SIZE; ++i) {
        sum += numbers[i]; // Tuong duong voi sum = sum + numbers[i];
    }

    cout << "Tong cac phan tu trong mang la: " << sum << endl; // Output: 85

    return 0;
}

Giải thích code:

  • Chúng ta khởi tạo một biến sum bằng 0. Biến này sẽ "gom góp" tổng giá trị của các phần tử.
  • Vòng lặp for duyệt qua từng phần tử của mảng.
  • Trong mỗi lần lặp, sum += numbers[i]; cộng giá trị của phần tử hiện tại (numbers[i]) vào biến sum.
4.2. Tìm Phần tử Lớn nhất và Nhỏ nhất trong Mảng

Để tìm giá trị lớn nhất và nhỏ nhất, chúng ta thường giả định phần tử đầu tiên là max/min ban đầu, sau đó duyệt các phần tử còn lại và cập nhật nếu tìm thấy giá trị "cực đoan" hơn.

#include <iostream>
#include <limits> // Can de dung numeric_limits ( tuy chon, nhung good practice)

int main() {
    int temperatures[] = {-5, 10, -2, 15, 8, 0, 20};
    const int SIZE = sizeof(temperatures) / sizeof(temperatures[0]);

    if (SIZE == 0) {
        cout << "Mang rong, khong the tim max/min." << endl;
        return 1; // Thoat neu mang rong
    }

    // Gia su phan tu dau tien la max va min
    int max_val = temperatures[0];
    int min_val = temperatures[0];

    // Duyet tu phan tu thu hai (index 1) tro di
    for (int i = 1; i < SIZE; ++i) {
        if (temperatures[i] > max_val) {
            max_val = temperatures[i]; // Cap nhat neu tim thay gia tri lon hon
        }
        if (temperatures[i] < min_val) {
            min_val = temperatures[i]; // Cap nhat neu tim thay gia tri nho hon
        }
    }

    cout << "Phan tu lon nhat trong mang la: " << max_val << endl; // Output: 20
    cout << "Phan tu nho nhat trong mang la: " << min_val << endl; // Output: -5

    return 0;
}

Giải thích code:

  • Chúng ta kiểm tra xem mảng có rỗng không để tránh lỗi.
  • Khởi tạo max_valmin_val bằng temperatures[0]. Việc này là cần thiết vì max/min chắc chắn nằm trong mảng.
  • Vòng lặp bắt đầu từ i = 1 (phần tử thứ hai), vì phần tử đầu tiên đã được xét làm giá trị khởi tạo.
  • Trong vòng lặp, chúng ta so sánh temperatures[i] với max_valmin_val hiện tại để cập nhật chúng nếu cần.
4.3. Tìm kiếm một Phần tử trong Mảng

Bạn muốn biết liệu một giá trị cụ thể có tồn tại trong mảng hay không? Vòng lặp lại là người bạn đồng hành!

#include <iostream>

int main() {
    int student_ids[] = {101, 105, 110, 108, 112};
    const int SIZE = sizeof(student_ids) / sizeof(student_ids[0]);
    int target_id = 108; // ID can tim

    bool found = false; // Bien co (flag) de ghi nhan viec tim thay
    int found_index = -1; // Bien luu vi tri tim thay (mac dinh la -1)

    // Duyet mang de tim kiem
    for (int i = 0; i < SIZE; ++i) {
        if (student_ids[i] == target_id) {
            found = true; // Tim thay roi!
            found_index = i; // Ghi lai vi tri
            break; // Quan trong: dung vong lap ngay khi tim thay de tiet kiem thoi gian
        }
    }

    if (found) {
        cout << "Da tim thay ID " << target_id << " trong mang tai vi tri (index): " << found_index << endl; // Output: ... tai vi tri 3
    } else {
        cout << "Khong tim thay ID " << target_id << " trong mang." << endl;
    }

    return 0;
}

Giải thích code:

  • Biến found là một cờ (flag) kiểu boolean, ban đầu là false. Nó sẽ chuyển thành true nếu tìm thấy phần tử.
  • Biến found_index lưu lại vị trí (index) của phần tử được tìm thấy.
  • Vòng lặp duyệt qua mảng. Nếu student_ids[i] bằng với target_id, chúng ta đặt found thành true, lưu lại i vào found_index, và dùng lệnh break; để thoát ngay khỏi vòng lặp. Điều này rất hiệu quả khi mảng lớn và bạn chỉ cần biết phần tử đó có tồn tại hay không, hoặc vị trí đầu tiên của nó.
  • Cuối cùng, chúng ta kiểm tra giá trị của found để thông báo kết quả.
4.4. Đếm số lần xuất hiện của một Phần tử

Thay vì chỉ kiểm tra sự tồn tại, đôi khi bạn cần biết một giá trị xuất hiện bao nhiêu lần trong mảng.

#include <iostream>

int main() {
    int data[] = {1, 2, 3, 2, 4, 2, 5, 1};
    const int SIZE = sizeof(data) / sizeof(data[0]);
    int target_value = 2; // Gia tri can dem so lan xuat hien

    int count = 0; // Bien dem, khoi tao bang 0

    // Duyet mang va dem
    for (int i = 0; i < SIZE; ++i) {
        if (data[i] == target_value) {
            count++; // Tang bien dem moi khi gap target_value
        }
    }

    cout << "Gia tri " << target_value << " xuat hien " << count << " lan trong mang." << endl; // Output: ... xuat hien 3 lan ...

    return 0;
}

Giải thích code:

  • Chúng ta khởi tạo biến count bằng 0.
  • Vòng lặp duyệt qua tất cả các phần tử của mảng.
  • Nếu data[i] bằng với target_value, chúng ta tăng biến count lên 1.
  • Sau khi vòng lặp kết thúc, count sẽ chứa tổng số lần target_value xuất hiện trong mảng.

Comments

There are no comments at the moment.