如何实现FSM - Java中的有限状态机

我有工作要做,我需要你的帮助。我们想要实现一个,以识别char序列(如:A,B,C,A,C),并判断它是否被接受。FSM - Finite State Machine

我们认为要实现三个类:、 和 。该类在 中呈现一个节点,我们认为用它来实现它,每个节点都将从抽象类状态扩展,每个类将处理不同类型的事件并指示到新状态的转换。在你看来,这是个好主意吗?StateEventMachinestateFSMState design pattern

第二件事,我们不知道如何保存所有过渡。我们再次想到用某种,保持起点并获得具有下一个状态的某种向量来实现它,但我不确定这是一个好主意。map

我很乐意获得一些如何实现它的想法,或者你可以给我一些起点。

我应该如何保存FSM,这意味着我应该如何在程序开始时构建树?我用谷歌搜索了它,发现了很多例子,但没有帮助我。

多谢。


答案 1

状态机的核心是转换表,它将状态和符号(您称之为事件的内容)转换为新状态。这只是一个双索引状态数组。为了保持理智和类型安全,请将状态和符号声明为枚举。我总是以某种方式(特定于语言)添加一个“length”成员来检查数组边界。当我手动编码FSM时,我用空格摆弄以行和列格式格式化代码。状态机的其他元素是初始状态和接受状态集。接受状态集的最直接实现是由状态索引的布尔数组。但是,在 Java 中,枚举是类,您可以在声明中为每个枚举值指定一个参数“accepting”,并在枚举的构造函数中对其进行初始化。

对于计算机类型,可以将其编写为泛型类。它将需要两个类型参数,一个用于状态,一个用于符号,一个数组参数用于转换表,单个状态用于初始。唯一的其他细节(尽管这很关键)是你必须调用Enum.ordinal()来获取一个适合索引过渡数组的整数,因为你没有语法可以直接声明一个具有枚举索引的数组(尽管应该有)。

要抢占一个问题,将不适用于转换表,因为所需的键是一对枚举值,而不是单个枚举值。EnumMap

enum State {
    Initial( false ),
    Final( true ),
    Error( false );
    static public final Integer length = 1 + Error.ordinal();

    final boolean accepting;

    State( boolean accepting ) {
        this.accepting = accepting;
    }
}

enum Symbol {
    A, B, C;
    static public final Integer length = 1 + C.ordinal();
}

State transition[][] = {
    //  A               B               C
    {
        State.Initial,  State.Final,    State.Error
    }, {
        State.Final,    State.Initial,  State.Error
    }
};

答案 2

EasyFSM是一个动态的Java库,可用于实现FSM。

你可以在以下位置找到相同的文档:Java中的有限状态机

另外,您可以在以下位置下载该库:Java FSM库:DynamicEasyFSM


推荐