Hàm đệ quy: Đếm ngược
Thuộc phần Logic và luồng điều khiển trong hành trình Dart của Coddy. Bài học 48 trên 65.
Giờ là lúc thực hành đệ quy với một hàm đếm ngược đơn giản. Bài tập này sẽ giúp bạn hiểu cách trường hợp cơ sở và bước đệ quy phối hợp với nhau trong code thực tế.
Hàm đếm ngược bắt đầu từ một số và in ra từng số giảm dần đến 0. Đây là cách đệ quy giúp thực hiện việc này: nếu số đó lớn hơn 0, hãy in số đó rồi gọi lại chính hàm ấy với một số nhỏ hơn. Khi số đó đạt đến 0, hãy dừng lại.
void countdown(int number) {
if (number <= 0) {
print("Done!");
return; // Trường hợp cơ sở: dừng tại đây
}
print(number);
countdown(number - 1); // Bước đệ quy
}Trường hợp cơ sở (base case) kiểm tra xem number <= 0 hay không. Đây là lúc ta ngừng gọi hàm (function). Bước đệ quy gọi countdown(number - 1), đây là cùng một bài toán nhưng với đầu vào nhỏ hơn, dần đưa ta đến trường hợp cơ sở.
Khi gọi countdown(3), hàm in ra 3, sau đó gọi countdown(2), hàm in ra 2, rồi gọi countdown(1), hàm in ra 1, tiếp theo gọi countdown(0), hàm in ra "Done!" rồi dừng lại.
Thử thách
DễTạo một chương trình triển khai bộ đếm ngược đệ quy với thông báo tùy chỉnh. Chương trình sẽ minh họa đệ quy bằng cách đếm ngược từ một số đã cho và hiển thị thông báo cá nhân hóa ở mỗi bước.
- Đọc một chuỗi đầu vào biểu thị số bắt đầu của bộ đếm ngược
- Đọc một chuỗi đầu vào biểu thị tiền tố thông báo tùy chỉnh (ví dụ:
"Launch in","Timer"hoặc"Countdown") - Chuyển đầu vào thứ nhất thành số nguyên bằng
int.parse() - Tạo một hàm (function) đệ quy có tên
customCountdownnhận hai tham số: - Một số nguyên
numberbiểu thị giá trị hiện tại của bộ đếm ngược - Một chuỗi
messagePrefixdùng cho thông báo tùy chỉnh - Hàm cần triển khai logic sau:
- Trường hợp cơ sở: Nếu số nhỏ hơn hoặc bằng 0, in ra
"Countdown complete!"rồi trả về - Bước đệ quy: In tiền tố thông báo theo sau là số hiện tại, sau đó gọi lại hàm với
number - 1 - Gọi hàm
customCountdownvới số đã chuyển đổi và tiền tố thông báo - Hiển thị kết quả theo đúng định dạng bên dưới
Ví dụ, nếu đầu vào là "5" và "Launch in", chương trình sẽ in ra:
Starting countdown from: 5
Message prefix: Launch in
========================
Launch in 5
Launch in 4
Launch in 3
Launch in 2
Launch in 1
Countdown complete!Nếu đầu vào là "3" và "Timer", chương trình sẽ in ra:
Starting countdown from: 3
Message prefix: Timer
========================
Timer 3
Timer 2
Timer 1
Countdown complete!Nếu đầu vào là "0" và "Ready", chương trình sẽ in ra:
Starting countdown from: 0
Message prefix: Ready
========================
Countdown complete!Chương trình phải triển khai hàm đệ quy customCountdown, hàm này tự gọi lại với số giảm dần cho đến khi đạt đến trường hợp cơ sở. Ở mỗi lần gọi đệ quy, hàm cần in thông báo tùy chỉnh cùng số hiện tại để minh họa cách đệ quy chia bài toán thành các bài toán con nhỏ hơn nhưng giống hệt nhau. Dùng nội suy chuỗi để định dạng thông báo đếm ngược thành "$messagePrefix $number".
Tự làm thử
import 'dart:io';
// TODO: Tạo hàm (function) customCountdown tại đây
// Nhớ xử lý trường hợp cơ sở (number <= 0) và bước đệ quy
void main() {
// Đọc đầu vào
String? startingNumber = stdin.readLineSync();
String? messagePrefix = stdin.readLineSync();
// Chuyển chuỗi thành số nguyên
int number = int.parse(startingNumber!);
// Hiển thị thông tin ban đầu
print('Starting countdown from: $number');
print('Message prefix: $messagePrefix');
print('========================');
// TODO: Gọi hàm customCountdown tại đây
// Nhớ xử lý an toàn null cho messagePrefix
}Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.
Tất cả bài học trong Logic và luồng điều khiển
1Thao tác nâng cao với danh sách
Thuộc tính danh sách: đầu và cuốiTrạng thái danh sách: isEmpty và isNotEmpĐảo ngược danh sáchThêm vào danh sách: insertXóa khỏi danh sách: removeWhereTìm trong danh sách: indexOfSắp xếp danh sáchXáo trộn danh sáchÔn tập: trình sắp xếp danh sách4Thao tác nâng cao với Map
Duyệt qua MapKiểm tra khóa và giá trịCác thuộc tính của Map: khóa và giá trịThêm có điều kiện: putIfAbsentXóa mục khỏi MapMap lồng nhauÔn tập: Cập nhật kho hàng7Hàm nâng cao
Hàm ẩn danhTruyền hàm làm đối sốTìm hiểu về bao đóngGiới thiệu về đệ quyHàm đệ quy: Đếm ngượcHàm đệ quy: Giai thừaÔn tập: Bộ xử lý danh sách2Thao tác hàm trên danh sách
Biến đổi bằng 'map'Lọc bằng 'where'Dùng '.toList()'Kiểm tra điều kiện bằng 'any'Điều kiện với 'every'Tìm phần tử bằng 'firstWhere'Ôn tập: lọc dữ liệu5Dự án: Tính tiền giỏ hàng
Thiết lập dự ánThêm mặt hàng vào giỏ8Dự án: Trình phân tích văn bản đơn giản
Tổng quan và thiết lập dự ánĐếm ký tự3Tập hợp
Tập hợp là gì?Tạo tập hợpThêm và xóa phần tử khỏi tập hợpKiểm tra phần tử trong tập hợpChuyển danh sách thành tập hợpPhép hợp của các tập hợpPhép giao của các tập hợpPhép hiệu của các tập hợpÔn tập: danh sách khách mời không trùng lặpTự luyện tập: Trình biên dịch Dart online