递归实现Blurb验证程序异常:输入xyyyy误判为true求助
问题分析与修正
问题背景
外星文字的Blurb格式规则:
- Blurb:由一个Whoozit后跟至少一个Whatzit组成
- Whoozit:字符'x'后跟0个或多个'y'
- Whatzit:字符'q'后跟'z'或'd',再跟一个Whoozit
现有Java代码输入xyyyy时输出true,但根据规则,这个字符串只有Whoozit,没有后续的至少一个Whatzit,正确结果应为false。
错误根源
- Blurb核心逻辑缺失:原
isValidBlurb仅验证了开头的Whoozit,未强制要求后续必须存在至少一个Whatzit,直接将剩余字符串交给允许空串返回true的isValidWhoozit处理,导致纯Whoozit被误判为有效Blurb。 - Whatzit验证逻辑错误:原
isValidWhatzit仅检查前3个字符是否为qz或qd,但实际上Whatzit是q+z/d+完整Whoozit的结构,需要验证q后的z/d,再验证后续完整的Whoozit,而非仅截取前三位判断。 - 方法职责混淆:原
isValidWhoozit错误地将Whatzit的检查纳入自身逻辑,混淆了两种结构的边界。
修正后的代码
import java.util.Scanner; public class Blurb { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); System.out.print("输入字符串判断是否为有效Blurb:"); String input = scanner.nextLine(); boolean isValid = isValidBlurb(input); System.out.println(isValid); scanner.close(); } // 验证是否为有效Blurb:Whoozit + 至少一个Whatzit,且完全匹配整个字符串 public static boolean isValidBlurb(String str) { if (str.isEmpty()) { return false; } // 匹配开头的Whoozit,获取匹配长度 int whoozitLength = matchWhoozit(str); if (whoozitLength == 0) { // 开头不是合法Whoozit return false; } String remaining = str.substring(whoozitLength); // 剩余部分必须至少匹配一个Whatzit,且最终耗尽字符串 return isValidAtLeastOneWhatzit(remaining); } // 匹配完整Whoozit,返回匹配长度,失败返回0 private static int matchWhoozit(String str) { if (str.isEmpty() || str.charAt(0) != 'x') { return 0; } int length = 1; // 至少包含'x' while (length < str.length() && str.charAt(length) == 'y') { length++; } return length; } // 验证是否有至少一个Whatzit,且完全耗尽字符串 private static boolean isValidAtLeastOneWhatzit(String str) { if (str.isEmpty()) { return false; // 无Whatzit,不符合要求 } // 匹配一个Whatzit,获取匹配长度 int whatzitLength = matchWhatzit(str); if (whatzitLength == 0) { return false; } String remaining = str.substring(whatzitLength); // 剩余部分可空(刚好一个Whatzit)或继续匹配更多Whatzit return remaining.isEmpty() || isValidAtLeastOneWhatzit(remaining); } // 匹配完整Whatzit,返回匹配长度,失败返回0 private static int matchWhatzit(String str) { if (str.length() < 2 || str.charAt(0) != 'q') { return 0; } // 检查q后是否为z或d char secondChar = str.charAt(1); if (secondChar != 'z' && secondChar != 'd') { return 0; } // 匹配后续的Whoozit int whoozitLength = matchWhoozit(str.substring(2)); if (whoozitLength == 0) { return 0; } // Whatzit总长度:1(q) +1(z/d) + whoozit长度 return 2 + whoozitLength; } }
代码说明
matchWhoozit:专注匹配完整Whoozit,返回匹配长度,明确结构边界,避免递归中频繁截取字符串。matchWhatzit:先验证q+z/d前缀,再验证后续完整Whoozit,确保Whatzit结构合法。isValidBlurb:先匹配开头Whoozit,再强制要求剩余部分至少包含一个Whatzit,完全符合Blurb定义。isValidAtLeastOneWhatzit:确保至少有一个Whatzit,同时支持连续匹配多个Whatzit,最终耗尽整个字符串。
内容的提问来源于stack exchange,提问作者Sean Anderson
相关产品推荐
相关产品推荐

