1. 概述
在本教程中,我们将探讨如何使用 Java 判断一个字符串是否包含全部 26 个英文字母。
举个 🌰:
“Farmer jack realized that big yellow quilts were expensive.” —— 这句话就包含了所有英文字母。
我们会讲解三种不同的实现方式:
- 使用传统的命令式编程(Imperative)方式实现;
- 利用正则表达式(Regular Expression);
- 使用 Java 8 的 Stream API 实现更现代、更声明式的写法。
同时,我们也会分析每种方法的时间复杂度(Big-O)。
2. 命令式算法实现
我们先来看最直观的实现方式:使用布尔数组来记录每个字母是否出现过。
✅ 大小写不敏感:A
和 a
被视为同一个字母。
public class EnglishAlphabetLetters {
public static boolean checkStringForAllTheLetters(String input) {
int index = 0;
boolean[] visited = new boolean[26];
for (int id = 0; id < input.length(); id++) {
if ('a' <= input.charAt(id) && input.charAt(id) <= 'z') {
index = input.charAt(id) - 'a';
} else if ('A' <= input.charAt(id) && input.charAt(id) <= 'Z') {
index = input.charAt(id) - 'A';
}
visited[index] = true;
}
for (int id = 0; id < 26; id++) {
if (!visited[id]) {
return false;
}
}
return true;
}
}
🔍 时间复杂度:O(n)
,其中 n
是字符串长度。
⚠️ 虽然这个算法不是最优的,但它足够清晰,适合理解问题本质。
3. 正则表达式实现
如果你喜欢“一行代码搞定”的风格,可以用正则表达式来简化逻辑:
public static boolean checkStringForAllLetterUsingRegex(String input) {
return input.toLowerCase()
.replaceAll("[^a-z]", "")
.replaceAll("(.)(?=.*\\1)", "")
.length() == 26;
}
📌 步骤说明:
- 先统一转小写;
- 去掉所有非字母字符;
- 去重(正则去重技巧);
- 最后判断是否刚好 26 个字符。
⚠️ 性能上不如第一种方法,时间复杂度同样是 O(n)
,但常数项更大。
4. Java 8 Stream 实现
使用 Stream API 可以写出更简洁、更具可读性的代码:
public static boolean checkStringForAllLetterUsingStream(String input) {
long c = input.toLowerCase().chars()
.filter(ch -> ch >= 'a' && ch <= 'z')
.distinct()
.count();
return c == 26;
}
✅ 使用了 chars()
、filter()
、distinct()
和 count()
,代码简洁明了。
🔍 时间复杂度同样是 O(n)
。
5. 单元测试示例
我们来写一个测试用例验证算法是否正确:
@Test
void givenString_whenContainsAllCharacter_thenTrue() {
String sentence = "Farmer jack realized that big yellow quilts were expensive";
assertTrue(EnglishAlphabetLetters.checkStringForAllTheLetters(sentence));
}
✅ 字符串确实包含全部字母,测试应通过。
6. 小结
本文介绍了三种方式来判断字符串是否包含全部英文字母:
- ✅ 命令式方法:直观、易懂,性能好;
- ✅ 正则表达式:代码简洁,但性能略差;
- ✅ Java 8 Stream:现代写法,可读性强。
你可以根据实际场景选择最适合的方式。
完整代码见 GitHub:https://github.com/eugenp/tutorials/tree/master/algorithms-modules/algorithms-miscellaneous-4