3.3 在C语言下构造马尔科夫链数据结构
在文章的开头,我们要强调一下文章的目的和整体脉络,以便在长文中丢失自我。
1.目的
我们给定一个输入(前缀),算法将自动匹配它的后缀,并根据选定的后缀更新前缀再重选后缀直至文档结束
2.脉络
对于我们期望的这种数据结构,我们要明白的是,它要服务马尔科夫链算法。回忆这个算法,我们不难发现算法中需要通过前缀去寻找后缀。而这之中,状态(State)又是一个很重要的存在。因为散列表(也就是哈希表)中对应的元素就是“状态”。
由此,我们可以先定义状态,它是和散列表相对应的,我们可以通过散列函数来定位到“状态”;(lookup函数)
状态中包含着前缀(两个单词)和数量未明确的后缀(后缀是一个单词);(结构体)
随着我们对文本的读取,我们需要增加“状态“的数量,也就是增加前缀和其对应的后缀。(add与addsuffix函数)
3.主体
我们首先定义一些常量:
enum
{
NPREF = 2, /*前缀中词的数量*/
NHASH = 4093, /*哈希表(散列表)大小*/
MAXGEN = 10000 /*录入的最大单词数量*/
};
我们设定一个很大的数组,这是因为我们预计程序可能会读取很大的文件,或许是一整本书。我们也选择了一个很大的散列表,这样,即使有10,000个前缀(词对)散列表中的平均链长依旧会很短(大概是两到三个前缀那么长)。数组越大,链的期望长度越短,查询进行的也就更快。过短的散列表会使得链长过长,查询时间变慢;过长的散列表则会导致储存空间的溢出。
对于整个输入来讲,我们希望其能达到如下的目标:
1.散列表中元素以状态(state)类型进行储存
2.状态中包含前缀以及数量不能确定的后缀(Suffix)
3.每个前缀和其对应的后缀都可以很好的联系在一起
因此,我们定义如下几个结构体:
typedef struct State