📜  自动机中的转移表(1)

📅  最后修改于: 2023-12-03 15:11:47.461000             🧑  作者: Mango

自动机中的转移表

自动机是一种广泛应用于字符串匹配、编译器等领域的有限状态机。而自动机中的转移表是自动机实现中重要的组成部分。

什么是自动机中的转移表?

自动机中的转移表是一个二维数组,其中行表示自动机的状态,列表示自动机的输入字符。转移表中的每个元素表示从某个状态在接收某个输入字符后转移到的下一个状态。

转移表的实现

用代码实现自动机的转移表通常有两种方式:使用二维数组或使用哈希表。

二维数组

使用二维数组实现转移表时,可以声明一个 transitions 数组来存储转移表。例如:

transitions = [
    # 0  1  2   # 三个输入符号
    [1, 3, 0],   # 状态 0
    [1, 2, 0],   # 状态 1
    [1, 0, 2],   # 状态 2
    [0, 0, 0],   # 状态 3(终止状态)
]

在这个例子中,有四个状态,它们的编号从 0 到 3。输入符号有三个,分别为 0、1 和 2。转移到下一个状态时,若当前状态为 curr_state,输入字符为 ch,则下一个状态为 transitions[curr_state][ch]。例如,从状态 1 接收到字符 2 后转移到的状态为 transitions[1][2],即 0 状态。

哈希表

使用哈希表实现转移表时,可以声明一个 transitions 字典来存储转移表。例如:

transitions = {
    (0, '0'): 1, (0, '1'): 3, (0, '2'): 0,
    (1, '0'): 1, (1, '1'): 2, (1, '2'): 0,
    (2, '0'): 1, (2, '1'): 0, (2, '2'): 2,
    (3, '0'): 0, (3, '1'): 0, (3, '2'): 0,   # 终止状态
}

在这个例子中,状态使用从 0 开始的编号来标识。输入字符使用字符类型进行标识。转移到下一个状态时,若当前状态为 curr_state,输入字符为 ch,则下一个状态为 transitions[(curr_state, ch)]。例如,从状态 1 接收到字符 2 后转移到的状态为 transitions[(1, '2')],即 0 状态。

转移表的优化

对于较大的自动机,转移表会非常稀疏,浪费大量的空间。因此,可以使用 defaultdict 类型的哈希表来实现稠密转移表。例如:

from collections import defaultdict

transitions = defaultdict(lambda: 0)
transitions.update({
    (0, '0'): 1, (0, '1'): 3, (0, '2'): 0,
    (1, '0'): 1, (1, '1'): 2, (1, '2'): 0,
    (2, '0'): 1, (2, '1'): 0, (2, '2'): 2,
    (3, '0'): 0, (3, '1'): 0, (3, '2'): 0,   # 终止状态
})

在这个例子中,使用 defaultdict 类型来自动为缺失的键设置默认值。由于默认值为 0,因此对于稀疏的转移表,不必再进行额外的赋值。