我正在使用CodingBat上课,无法弄清楚为什么我的代码无法正常工作。它通过了列出的所有测试,但是没有通过“其他测试”。如果您能帮助我找出问题所在,那将非常有帮助。这是问题所在: 给定一个字符串,计算以'y'或'z'结尾的单词数-因此,“ heavy”中的“ y”和“ fez”中的“ z”进行计数,但不计算“ yellow”中的“ y” (不区分大小写)。如果在单词的末尾没有紧跟字母,我们将说y或z在单词的末尾。 (注意:Character.isLetter(char)测试字符是否为字母。)
这是列出的测试,我通过了。
countYZ("fez day")
countYZ("day fez")
countYZ("day fyyyz")
countYZ("day yak")
countYZ("day:yak")
countYZ("!!day--yaz!!")
countYZ("yak zak")
countYZ("DAY abc XYZ")
countYZ("aaz yyz my")
countYZ("y2bz")
countYZ("zxyx")
这是我到目前为止的代码。 (我知道我可以通过转换为小写字母来使它更干净,但我后来才意识到。)
public int countYZ(String str) {
int count = 0;
str = str.toLowerCase();
for (int i=0; i<str.length()-1; i++) {
if (!Character.isLetter(str.charAt(i)) && i>0 && (str.substring(i-1,i).equals("y") || str.substring(i-1,i).equals("z")))
{ count++; }
}
if (str.endsWith("y") || str.endsWith("z")) { count++; }
return count;
}
答案 0 :(得分:1)
问题:按照您设置逻辑的方式,循环查找到String
末尾的一个字符,然后用{{ 1}}语句。 但是,您的循环仅有效检查if
之前的字符,因此您没有检查字符。失败的i
是:
String
(请注意末尾有多余的空格。它可以是任何其他非字母字符,定义为前一个单词的结尾)
此"y z "
应该返回2,但返回1。简单的解决方法是将循环更改为:
String
也许是更好的方法:
现在,您遇到了一堆布尔条件,以查看之前的字符是否为非字母,如果for (int i=0; i<str.length(); i++)
处的字符为字母,依此类推。如果您是我,则只需使用i
,然后将其拆分为任何非字母字符。然后,对于拆分数组中的每个toLower()
,使用String
函数可以轻松地检查其是否以endsWith
或z
结尾。这是一种可能的解决方案:
y
或者Java 8+,您可以轻松做到:
public int countYZ(String str) {
if(str == null) return 0;
str = str.toLowerCase();
int count = 0;
for(String s : str.split("[^a-z]")) {
if(s.endsWith("y") || s.endsWith("z")) {
count++;
}
}
return count;
}
答案 1 :(得分:0)
清理代码将使其更易于阅读和调试。
Don't Repeat Yourself!每当您发现自己编写同一段代码时,由于简单的键入错误,都会引入潜在的错误。相反,您可以将所有检查移到一个方法中,并使用equalsIgnoreCase
检查给定字符是否匹配Y或Z:
public static boolean isYOrZ(String s) {
if(s.equalsIgnoreCase("y") || s.equalsIgnoreCase("z")) return true;
else return false;
}
现在,您的代码无法输入空字符串和空字符串,因此请在执行任何处理之前添加检查:
int count = 0;
if(str == null || str.length() == 0) //check null first or you will get NPE!
return count;
最后,您可以使用创建的新帮助器方法来更新代码。如果您了解正则表达式的工作原理,那么使用String.split()
来处理您的单词会更容易:
public static int countYZ(String str) {
int count = 0;
if(str == null || str.length() == 0) {
return count;
}
String[] words = str.split("[^A-z]"); //"not an alphabetic letter immediately following it"
for(String word : words) {
if(word.length() > 0) { //sanity check
if(isYOrZ(word.substring(word.length()-1))) {
++count;
}
}
}
return count;
}
现在您可以进行测试,编写您可以想到的许多奇怪的测试用例。例如,一个很大的空格字符串,一个空字符串等。以下是我尝试过的一些示例:
System.out.println(countYZ("heavY yummy TASTY yellow zed buzz"));
System.out.println(countYZ(""));
System.out.println(countYZ(null));
System.out.println(countYZ("fiZz yay"));
System.out.println(countYZ("zzzZZza yyy"));
System.out.println(countYZ("z"));
System.out.println(countYZ(" "));
System.out.println(countYZ("heavy&testy@!@#BuzZ")); //3
哪个给:
4
0
0
2
1
1
0
3