到目前为止,我已经想出了这个。我试图最小化字符串操作并将解决方案隔离到内置数据类型,数组和整数操作。
我在java中寻找更优雅的方法来检查pangram字符串。
优雅,就像在最小的代码行中一样,其他有效的算法也是受欢迎的。
请提供没有lambda表达式的建议。
private static boolean isPangrams(String ip) {
char[] characterArray = ip.toLowerCase().toCharArray();
int map[] = new int[26];
int sum = 0;
for(char current : characterArray) {
int asciiCode = (int) current;
if (asciiCode >= 97 && asciiCode <= 122) {
if (map[122 - asciiCode] == 0) {
sum += 1;
map[122 - asciiCode] = 1;
}
}
}
return sum == 26;
}
答案 0 :(得分:4)
如果你想要难以理解的几行答案:
private static boolean isPangrams(String ip) {
return 26== (new HashSet(Arrays.asList(ip.toUpperCase().replaceAll("[^A-Z]", "").toCharArray()))).size();
}
<强>解释强>
char[]
Collection
Set
以删除所有双重您应该意识到此代码不易阅读且不具备效果。
答案 1 :(得分:2)
您可以使用按位操作:
private static boolean isPangrams(String ip) {
int flags = 0;
for(char current : ip.toLowerCase().toCharArray()) {
if (current >= 'a' && current <= 'z') {
flags |= 0x01<<(current-'a');
}
}
return flags == 0x3ffffff;
}
代码的工作原理如下:我们考虑一个32位数的int。每个最多26位是一个标志(可以说是boolean
)。最初所有标记都是false
,因为我们使用flags
初始化0
。
现在我们迭代字符串的字符。如果字符是小写字母,我们将相应标志的标志设置为true
(无论之前是否已设置为true
)。
最后,我们检查最低26位是否都设置为true
。如果是,flags
等于0x3ffffff
(这是一个等于1111111111111111111111
二进制的十六进制数。如果是,我们返回true
。否则我们返回false
。
通常按位运算比if
语句和布尔值更快,所以我希望这个程序更快一点。
答案 2 :(得分:2)
如果字符串包含int变量中的给定字母,则可以“打包”数据。
static boolean pangram (String s) {
int check = 0;
String lowerCase = s.toLowerCase();
for (int i = 0; i < lowerCase.length(); i++) {
char ch = lowerCase.charAt(i);
if (ch >= 'a' && ch <= 'z') {
check |= (1 << s.charAt(i) - 'a');
}
}
return check == 67108863;
}
最后的幻数是0b00000011111111111111111111111111
答案 3 :(得分:0)
如果找到,可以使用return false语句停止整个方法 map [122 - asciiCode]不等于零,因为从那以后它再也没有pangram而你剩下的for() - 我是对的吗? 我知道这不是你所期望的改进(特别是只有26步),但只是让我想到的东西
if (map[122 - asciiCode] == 0) {
sum += 1;
map[122 - asciiCode] = 1;
} else return false;
答案 4 :(得分:0)
最有效的解决方案O(n)时间复杂度:
HashMap
(key: letter, value: count
)