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

Java状态机日期识别代码无法进入case 8的问题求助

日期格式验证状态机的执行问题

我们要识别DD/MM格式的日期(例:03/02代表2月3日),简化规则为每月30天,实现的Java代码如下:

package Tp2;

import java.util.Scanner;

public class EX2_Date_forme {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (true) {
            System.out.println("give a string or (exit) to leave : ");
            String input = sc.nextLine();
            if (input.equals("exit")) break;
            System.out.println();
            Date(input);
        }
    }

    public static void Date(String input) {
        int len = input.length();
        int state = 0;
        int tracker = 0;
        for (int i = 0; i < len; i++) {
            char c = input.charAt(i);
            boolean c_isBetween_zero_in_AndNine = Character.getNumericValue(c) >= 0 && Character.getNumericValue(c) <= 9;
            boolean c_isBetween_zero_out_AndNine = Character.getNumericValue(c) > 0 && Character.getNumericValue(c) <= 9;
            
            switch (state) {
                case 0:
                    if (c == '0') { state = 1; tracker++; }
                    else if (c == '1' || c == '2') { state = 2; tracker++; }
                    else if (c == '3') { state = 3; tracker++; }
                    else System.out.println("error");
                    break;
                case 1:
                    if (c_isBetween_zero_out_AndNine) { state = 4; tracker++; }
                    else System.out.println("error");
                    break;
                case 2:
                    if (c_isBetween_zero_in_AndNine) { state = 4; tracker++; }
                    else System.out.println("error");
                    break;
                case 3:
                    if (c == '0') { state = 4; tracker++; }
                    else System.out.println("error");
                    break;
                case 4:
                    if (c == '/') { state = 5; tracker++; }
                    else System.out.println("error");
                    break;
                case 5:
                    if (c == '0') { state = 6; tracker++; }
                    else if (c == '1') { state = 7; tracker++; }
                    else System.out.println("error");
                    break;
                case 6:
                    if (c_isBetween_zero_out_AndNine) { state = 8; tracker++; }
                    else System.out.println("error");
                    break;
                case 7:
                    if (c == '0' || c == '1' || c == '2') { tracker++; state = 8; }
                    else System.out.println("error");
                    break;
                case 8:
                    if (tracker == len) System.out.println("in the language");
                    else System.out.println("error");
                    break;
            }
        }
    }
}

调试输入"01/01"时,流程能走到state=8,但for循环从未进入case 8分支,出不来预期的"in the language"提示。目前在循环后加一段判断代码能正常运行,但希望让流程进入case 8处理:

if (state == 8 && tracker == len) {
    System.out.println("in the language");
} else {
    System.out.println("error");
}

问题根源

拿"01/01"举例,字符串长度是5,for循环的i从0到4共5次迭代:

  • 第5次迭代(i=4)处理最后一个字符'1'时,state从6切换为8,tracker变成5(等于字符串长度)
  • 这次迭代走的是case 6分支,执行完后循环直接结束,根本没机会进入case 8

解决办法

要让流程进入case 8,可以在for循环结束后,额外执行一次针对当前state的switch判断,补全终止状态的校验:

public static void Date(String input) {
    int len = input.length();
    int state = 0;
    int tracker = 0;
    for (int i = 0; i < len; i++) {
        // 原循环内代码完全保留
        char c = input.charAt(i);
        boolean c_isBetween_zero_in_AndNine = Character.getNumericValue(c) >= 0 && Character.getNumericValue(c) <= 9;
        boolean c_isBetween_zero_out_AndNine = Character.getNumericValue(c) > 0 && Character.getNumericValue(c) <= 9;
        
        switch (state) {
            case 0:
                if (c == '0') { state = 1; tracker++; }
                else if (c == '1' || c == '2') { state = 2; tracker++; }
                else if (c == '3') { state = 3; tracker++; }
                else System.out.println("error");
                break;
            case 1:
                if (c_isBetween_zero_out_AndNine) { state = 4; tracker++; }
                else System.out.println("error");
                break;
            case 2:
                if (c_isBetween_zero_in_AndNine) { state = 4; tracker++; }
                else System.out.println("error");
                break;
            case 3:
                if (c == '0') { state = 4; tracker++; }
                else System.out.println("error");
                break;
            case 4:
                if (c == '/') { state = 5; tracker++; }
                else System.out.println("error");
                break;
            case 5:
                if (c == '0') { state = 6; tracker++; }
                else if (c == '1') { state = 7; tracker++; }
                else System.out.println("error");
                break;
            case 6:
                if (c_isBetween_zero_out_AndNine) { state = 8; tracker++; }
                else System.out.println("error");
                break;
            case 7:
                if (c == '0' || c == '1' || c == '2') { tracker++; state = 8; }
                else System.out.println("error");
                break;
            case 8:
                if (tracker == len) System.out.println("in the language");
                else System.out.println("error");
                break;
        }
    }
    // 循环结束后补充终止状态判断
    switch(state) {
        case 8:
            // 进入case 8执行校验
            if (tracker == len) System.out.println("in the language");
            else System.out.println("error");
            break;
        default:
            // 未走到终止状态直接报错
            if (tracker != len) System.out.println("error");
            break;
    }
}

这样既保留了原状态机的逻辑,又能让流程进入case 8完成最终输出,同时避免了中途重复输出错误的问题。

内容的提问来源于stack exchange,提问作者BADR EL ADRAOUI

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 22:07:03