Hướng dẫn giải của Ký tự liền sau
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.
Lời giải này đang bị ẩn cho đến khi bạn chọn mở ra.
Chúng tôi khuyên bạn nên tự thử giải bài trước. Việc mở lời giải có thể làm lộ mất ý tưởng chính trước khi bạn có cơ hội tự giải.
Bạn phải đăng nhập để mở lời giải này.
Đăng nhậpTác giả: , , ,
Editorial for nextchar: Ký tự liền sau
Hiểu bài toán
Bài toán yêu cầu tìm ký tự liền sau một ký tự cho trước trong bảng chữ cái tiếng Anh. Đầu vào là một ký tự thường từ 'a' đến 'z'. Nếu ký tự đầu vào là 'z', ký tự trả về phải là 'a'. Ví dụ: 'd' -> 'e', 'z' -> 'a'.
Các cách tiếp cận
Cách Conditional Branching
#include <stdio.h>
int main() {
char c;
scanf("%c", &c);
if (c == 'z') {
printf("a");
} else {
printf("%c", c + 1);
}
return 0;
}
- Time Complexity: O(1)
- Space Complexity: O(1)
Phương pháp này sử dụng câu lệnh if-else để kiểm tra điều kiện đặc biệt. Nếu ký tự là 'z', in ra 'a'. Ngược lại, sử dụng toán tử cộng (+1) để lấy ký tự tiếp theo trong bảng mã ASCII và in ra.
Cách Range Check Logic
#include <stdio.h>
#include <ctype.h>
int main() {
char s;
scanf("%c", &s);
if (s >= 'a' && s < 'z') {
printf("%c", s + 1);
} else {
printf("a");
}
return 0;
}
- Time Complexity: O(1)
- Space Complexity: O(1)
Tiếp cận này kiểm tra xem ký tự có nằm trong khoảng từ 'a' đến 'y' hay không (s >= 'a' && s < 'z'). Nếu có, in ra ký tự tiếp theo. Nếu không (tức là 'z'), in ra 'a'.
Cách Modulo Arithmetic
#include <stdio.h>
int main() {
char c;
scanf("%c", &c);
printf("%c", (c - 'a' + 1) % 26 + 'a');
return 0;
}
- Time Complexity: O(1)
- Space Complexity: O(1)
Phương pháp này chuyển đổi ký tự về số nguyên (0 cho 'a', 25 cho 'z') bằng cách trừ đi 'a'. Sau đó cộng thêm 1. Để xử lý trường hợp tràn số ở 'z', ta lấy kết quả chia lấy dư cho 26 (% 26). Cuối cùng cộng lại 'a' để chuyển về ký tự. Công thức này hoạt động cho mọi ký tự trong bảng chữ cái mà không cần nhánh if.
Phân tích độ phức tạp
| Cách tiếp cận | Time | Space | Tên |
|---|---|---|---|
| 1 | O(1) | O(1) | Conditional Branching |
| 2 | O(1) | O(1) | Range Check Logic |
| 3 | O(1) | O(1) | Modulo Arithmetic |
Bài học kinh nghiệm
- Các ký tự trong C được lưu trữ dưới dạng số ASCII. 'a' = 97, 'z' = 122.
- Có thể thực hiện phép toán số học trên các biến ký tự (ví dụ: 'a' + 1 sẽ cho ra mã ASCII của 'b').
- Phép chia lấy dư (Modulo) là một cách hiệu quả để xử lý các bài toán quay vòng (wrap-around) như 'z' quay lại 'a'.
Lỗi thường gặp
- Quên xử lý trường hợp đặc biệt là ký tự 'z', dẫn đến in ra ký tự không mong muốn (thường là ký tự có mã ASCII 123 là '{').
- Đọc sai định dạng đầu vào (ví dụ: dùng
scanf("%s")thay vìscanf("%c")có thể gây lỗi whitespace). - Biến 'z' thành 'a' là logic wrap-around, nhưng nếu input không giới hạn trong 'a'-'z' thì cần xử lý cẩn thận hơn.
Bình luận