我的代码通过了CodingBat的所有给定测试,但未通过“其他测试”。我不确定我的问题是什么

时间:2019-01-22 20:41:29

标签: java

我正在使用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;
}

2 个答案:

答案 0 :(得分:1)

问题:按照您设置逻辑的方式,循环查找到String末尾的一个字符,然后用{{ 1}}语句。 但是,您的循环仅有效检查if之前的字符,因此您没有检查字符。失败的i是:

String

(请注意末尾有多余的空格。它可以是任何其他非字母字符,定义为前一个单词的结尾)

"y z " 应该返回2,但返回1。简单的解决方法是将循环更改为:

String

也许是更好的方法:

现在,您遇到了一堆布尔条件,以查看之前的字符是否为非字母,如果for (int i=0; i<str.length(); i++) 处的字符为字母,依此类推。如果您是我,则只需使用i,然后将其拆分为任何非字母字符。然后,对于拆分数组中的每个toLower(),使用String函数可以轻松地检查其是否以endsWithz结尾。这是一种可能的解决方案:

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;
}

解决所有测试用例: enter image description here


Link to problem

答案 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