有限自动机转换的时空有效编码
Space and Time Efficient Encoding of Transitions for Finite Automata
我一直在思考如何有效地对有限自动机的转换进行空间编码,并保证快速查找时间。对我来说,一个听起来不错的想法是,如果我知道每个状态最多有32个输出转换,那么使用int,有效地将转换符号编码为int位中的1或0。
那么,我有一个类将类型T(例如字符串)映射为int。ID(string)返回分配给字符串作为其整数编码的ID。将字符串"fish", "cat"answers"tree"依次添加到一个空ID对象中,将把"fish"赋值为0,"cat"赋值为1,"tree"赋值为2。
之后,我将2的幂与单个转换符号联系起来。功率由分配给过渡符号的ID决定。
如果ID类被输入的是英文字母,而不是"fish", "cat"answers"tree",那么得到的映射将是
a : 0
b : 1
c : 2
...
j : 9
...
z : 26
因此,具有"a","c","e"answers"f"的出边的状态的outgoing_symbols
场看起来像这样:
00000000 00000000 00000000 00110101
zy xwvutsrq ponmlkji hgfedcba
现在我可以简单地做state.outgoing_symbols+=pow(2,ID(transition_symbol))当添加一个过渡到一个现有的状态
我将执行state.outgoing_symbols+=pow(2,ID(j))
将2^9添加到outgoing_symbols,从而得到
00000000 00000000 00000010 00110101
zy xwvutsrq ponmlkji hgfedcba
这种表示的优点是我可以在一个int中存储32个符号,并且我可以在常量时间内查询状态是否与给定符号有转换:
假设是如下结构体的向量
┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
│ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │...│ │ │ │ │ │ │ │ │ │ │ n │
├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
└───┴───┴───┴───┴───┴───┴───┴─┬─┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘
│
│
│
│
│
├───────────────────────────────────────────────────────────────────────┐
│ sym_enc outgoing_symbols 00000000 00001000 10000010 00110100 │
│ │
│ T mapping_of_symbols_onto_target_states |
└───────────────────────────────────────────────────────────────────────┘
将状态id 0到n映射到outgoing_symbols
的结构体,以及从符号到目标状态的映射。然后我可以写这个函数:
bool has_outgoing_symbol(int state, int symbolID)
{
return delta[state].outgoing_symbols & pow(2, symbolID) == symbolID;
}
最大的问题是,到目前为止,我还没有将转换符号与目标状态联系起来,我想不出任何方法来使用这种非常有效的转换编码和必要的映射的有效编码。
我可以有2个向量,一个是转换符号id,一个是存储目标状态id的向量的向量。这两个向量将被"同步",因此对于所有i, vector1[i]
对应于vectpr2[i]
。在
struct transition
{
std::vector to_states;
int transition_symbol;
};
是利用一些我不明白的处理器魔法,显然有几个简单类型的向量比有一个简单类型的结构体的向量要好。
在任何情况下,必须以线性或对数查找方式查找目标状态,这使得通过编码作为2的幂来查找转换符号的恒定查找的优势被浪费了。但是我想不出任何方法来利用这种编码将符号映射到目标状态。
有没有人能给我建议,在哪里读到这样的东西,或者甚至直接有一个想法,如何做到这一点?
如果我理解正确的话,您希望为每个在位掩码中设置了位的符号在向量中存储一个条目,并有效地查找给定符号的条目。
在这种情况下,你可以通过计算掩码中小于你要检查的符号的位数来计算条目的索引:
int getSymbolIndex(int state, int symbolID)
{
if(symbolID == 0)
return 0;
return NumberOfSetBits(delta[state].outgoing_symbols & ((1 << symbolID) -1));
}
使用返回的索引在为状态存储的目标状态向量中查找条目。它只给出实际存在于集合中的符号的有效结果。
一个有效的计算整数位数的方法,参见这个问题:如何计算32位整数中设置的位数?
- 如何确定我已使用非编码文件到达 EOF?
- 欧拉项目#8答案是大以获得有效答案
- 调整大小后指向元素值的指针unordered_map有效?
- 为什么是0;C++中的有效语句
- 最高有效数字侧的第N位
- GCC对可能有效的代码抛出init list生存期警告
- 有效地使用std::unordered_map来插入或增加键的值
- c++中O(n^(1/3))中一个数的除数的有效计数
- 使用无符号字符数组有效存储内存
- 使用 MATLAB 编码器生成C++代码:编译错误"undefined reference to `rgb2gray_tbb_real64'"
- 自定义先决条件对移动分配运算符有效吗
- 在卡萨布兰卡形成编码参数的列表
- 为什么将值返回函数传递给重载=运算符对运算符函数有效,而对其他运算符无效
- 使用C++进行游程编码
- 如何将不同的可执行文件合并到一个窗口框架中进行编码?像浏览器一样
- 有哪些有效的方法可以消除一组 100 万个字符串>重复数据?
- 为什么这种直接初始化有效?(C++17)
- 递归函数有效,但无法记忆
- 如何有效地解压缩霍夫曼编码的文件
- 有限自动机转换的时空有效编码