Bài tập C/C++ cho người mới

Tìm giá trị lớn thứ hai trong mảng bằng C, C++

Trong bài học này, bạn sẽ tìm giá trị lớn thứ hai khác nhau trong mảng chỉ với một lần duyệt, không cần sắp xếp.

Giới thiệu

Cách dễ nghĩ nhất để tìm giá trị lớn thứ hai là sắp xếp mảng, nhưng làm vậy tốn thời gian không cần thiết. Thay vào đó, ta chỉ cần theo dõi hai giá trị lớn nhất trong một lần duyệt mảng, đồng thời bỏ qua các giá trị trùng với giá trị lớn nhất.

Những điểm quan trọng

  • Luôn bật cảnh báo của trình biên dịch (compiler warning) và sửa hết các cảnh báo.
  • Hiểu rõ kiểu dữ liệu và thời gian tồn tại (lifetime) của từng giá trị.
  • Luôn kiểm tra dữ liệu đầu vào và giới hạn chỉ số của mảng.

Code ví dụ bằng C và C++

C
Chạy code →
main.c
#include <limits.h>
#include <stdio.h>
int main(void) {
    int values[] = {7, 23, 12, 23, 9}, first = INT_MIN, second = INT_MIN;
    // Maintain the two largest distinct values.
    for (int i = 0; i < 5; ++i) { int value = values[i]; if (value > first) { second = first; first = value; } else if (value > second && value != first) second = value; }
    printf("second=%d\n", second);
}
Kết quả khi chạy
second=12
C++
Chạy code →
main.cpp
#include <iostream>
#include <limits>
#include <vector>
int main() {
    std::vector values{7, 23, 12, 23, 9}; int first = std::numeric_limits<int>::min(), second = first;
    // Maintain the two largest distinct values.
    for (int value : values) { if (value > first) { second = first; first = value; } else if (value > second && value != first) second = value; }
    std::cout << "second=" << second << '\n';
}
Kết quả khi chạy
second=12

So sánh C và C++

Hai biến first và second bắt đầu bằng INT_MIN, giá trị nhỏ nhất của kiểu int. Khi gặp giá trị lớn hơn first, giá trị cũ của first được chuyển xuống second. Khi gặp giá trị nằm giữa hai số và khác first, chỉ second được cập nhật. Vì vậy số 23 xuất hiện hai lần không làm sai kết quả, và giá trị lớn thứ hai là 12.

C

C dùng các hàm thủ tục gọn nhẹ và thể hiện rõ cách dữ liệu được biểu diễn trong bộ nhớ.

C++

C++ vẫn cho phép làm việc ở mức thấp nhưng bổ sung các kiểu dữ liệu thư viện và công cụ trừu tượng an toàn hơn.

Bài tập mở rộng

Hãy chạy cả hai phiên bản, sau đó thử thay đổi code để quan sát sự khác biệt về mức độ an toàn mà mỗi ngôn ngữ mang lại.

  • Thử nhập dữ liệu sai và các giá trị ở biên.
  • Biên dịch với các cờ -Wall -Wextra -Wpedantic để bật thêm cảnh báo.
  • Tách phần khai báo dùng chung ra file header và phần cài đặt ra file riêng.

Luyện tập với thử thách

Áp dụng kiến thức của bài học này để giải một bài toán thực tế. Mỗi thử thách chạy ngay trên trình duyệt, có kiểm thử tức thì và AI nhận xét.

Tất cả thử thách