You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

递归实现Blurb验证程序异常:输入xyyyy误判为true求助

问题分析与修正

问题背景

外星文字的Blurb格式规则:

  • Blurb:由一个Whoozit后跟至少一个Whatzit组成
  • Whoozit:字符'x'后跟0个或多个'y'
  • Whatzit:字符'q'后跟'z'或'd',再跟一个Whoozit

现有Java代码输入xyyyy时输出true,但根据规则,这个字符串只有Whoozit,没有后续的至少一个Whatzit,正确结果应为false。

错误根源

  1. Blurb核心逻辑缺失:原isValidBlurb仅验证了开头的Whoozit,未强制要求后续必须存在至少一个Whatzit,直接将剩余字符串交给允许空串返回true的isValidWhoozit处理,导致纯Whoozit被误判为有效Blurb。
  2. Whatzit验证逻辑错误:原isValidWhatzit仅检查前3个字符是否为qz或qd,但实际上Whatzit是q+z/d+完整Whoozit的结构,需要验证q后的z/d,再验证后续完整的Whoozit,而非仅截取前三位判断。
  3. 方法职责混淆:原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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 21:30:21