Pangram (chuỗi hoàn hảo) là câu chứa tất cả 26 chữ cái của bảng chữ cái tiếng Anh ít nhất một lần. Ví dụ kinh điển: "The quick brown fox jumps over the lazy dog".
Mã nguồn (LINQ - ngắn gọn)
using System;
using System.Linq;
namespace Demo {
public class Program {
public static void Main(string[] args) {
string str = "The quick brown fox jumps over the lazy dog";
bool isPangram = CheckPangram(str);
Console.WriteLine($"{isPangram}: \"{str}\" is pangram");
Console.ReadKey();
}
static bool CheckPangram(string str) {
// Chuyển thường, lọc chỉ chữ cái, nhóm distinct, đếm
return str.ToLower()
.Where(ch => char.IsLetter(ch))
.GroupBy(ch => ch)
.Count() == 26;
}
}
}
Kết quả
True: "The quick brown fox jumps over the lazy dog" is pangram
Giải thích LINQ
ToLower(): Chuẩn hóa về chữ thường.Where(ch => char.IsLetter(ch)): Lọc chỉ giữ chữ cái (bỏ số, space, dấu câu).GroupBy(ch => ch): Nhóm các ký tự giống nhau.Count(): Đếm số nhóm distinct = số chữ cái khác nhau.- So sánh với 26.
Cách tối ưu O(n) không dùng LINQ (Bitmask)
static bool IsPangramFast(string s) {
int mask = 0;
foreach (char c in s) {
if (char.IsLetter(c)) {
int bit = char.ToLower(c) - 'a';
if (bit >= 0 && bit < 26) mask |= (1 << bit);
if (mask == 0x3FFFFFF) return true; // 26 bit thấp đều = 1
}
}
return mask == 0x3FFFFFF;
}
So sánh
| Phương pháp | Độ phức tạp | Bộ nhớ | Ghi chú |
|---|---|---|---|
| LINQ GroupBy | O(n log n) | O(k) | Dễ đọc, đủ nhanh cho chuỗi ngắn |
| Bitmask (int 32-bit) | O(n) | O(1) | Nhanh nhất, không cấp phát |
| HashSet<char> | O(n) | O(k) | Cân bằng |
| bool[26] array | O(n) | O(1) | Đơn giản, dễ hiểu |
Lưu ý
char.IsLetterhỗ trợ Unicode — nếu chỉ muốn A-Z, dùngc >= 'a' && c <= 'z'sau ToLower.- Pangram tiếng Việt: cần 29 chữ cái (a-z + ă, â, đ, ê, ô, ơ, ư) — logic tương tự nhưng mask 32-bit vẫn đủ.
- Perfect pangram: mỗi chữ cái xuất hiện đúng 1 lần (26 ký tự chữ cái chính xác).