状态机的核心是转换表,它将状态和符号(您称之为事件的内容)转换为新状态。这只是一个双索引状态数组。为了保持理智和类型安全,请将状态和符号声明为枚举。我总是以某种方式(特定于语言)添加一个“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
}
};