WM算法详解及C语言实现代码解析参考Word文档下载推荐.docx
- 文档编号:21353461
- 上传时间:2023-01-29
- 格式:DOCX
- 页数:16
- 大小:30.09KB
WM算法详解及C语言实现代码解析参考Word文档下载推荐.docx
《WM算法详解及C语言实现代码解析参考Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《WM算法详解及C语言实现代码解析参考Word文档下载推荐.docx(16页珍藏版)》请在冰豆网上搜索。
如果相等,让真正的模式串去和text匹配。
WM算法的代码参考:
下面给出对这份代码的详细注释以及流程图。
共包含wm.h文件和wm.c文件,首先给出的是对代码的详细注释:
//文件wm.h:
#ifndefWM_H
#defineWM_H
#include<
stdio.h>
stdlib.h>
string.h>
#defineHASHTABLESIZE(256*256)
#defineMAXLEN256
typedefstructwm_pattern_struct//每个模式串的结构
{
structwm_pattern_struct*next;
//指向下一个模式串
unsignedchar*psPat;
//patternarray//模式串数组
unsignedpsLen;
//lengthofpatterninbytes//模式串的长度
}WM_PATTERN_STRUCT;
#defineHASH_TYPEshort
#defineSHIFTTABLESIZE(256*256)
typedefstructwm_struct//模式串集的结构
WM_PATTERN_STRUCT*plist;
//patternlist模式子串列表
WM_PATTERN_STRUCT*msPatArray;
//arrayofpatterns模式子串数组(队列)
unsignedshort*msNumArray;
//arrayofgroupcounts,#ofpatternsineachhashgroup
intmsNumPatterns;
//numberofpatternsloaded//模式子串的个数
unsignedmsNumHashEntries;
//HASH表的大小
HASH_TYPE*msHash;
//last2characterspatternhashtable//HASH表
unsignedchar*msShift;
//badwordshifttable//SHIFT表
HASH_TYPE*msPrefix;
//first2charactersprefixtable//PREFIX表
intmsSmallest;
//shortestlengthofallpatterns//最短模式子串的长度
}WM_STRUCT;
//函数声明
WM_STRUCT*wmNew();
//创建模式串集函数
voidwmFree(WM_STRUCT*ps);
//释放空间函数
intwmAddPattern(WM_STRUCT*ps,unsignedchar*P,intm);
//添加子模式串函数
intwmPrepPatterns(WM_STRUCT*ps);
//预处理函数
voidwmSearch(WM_STRUCT*ps,unsignedchar*Tx,intn);
//模式匹配函数
#endif
//WM.c文件如下
#include"
wm.h"
ctype.h>
externintnline=1;
externintnfound=0;
#defineMAXN10001//模式串的最大长度MAXN-1
#defineMAXM51//单词最大长度为MAXM-1
/*****************************************************************
函数:
voidwmNew()
目的:
创建一个模式串集合
参数:
无
返回:
WM_STRUCT-创建的模式串集
****************************************************************/
WM_STRUCT*wmNew()
WM_STRUCT*p=(WM_STRUCT*)malloc(sizeof(WM_STRUCT));
if(!
p)return0;
p->
msNumPatterns=0;
//模式串的个数,初始为0
msSmallest=1000;
//最短模式串的长度
returnp;
}
voidwmFree(WM_STRUCT*)
释放模式串集占用空间
ps=>
模式串集
voidwmFree(WM_STRUCT*ps)//释放空间函数
if(ps->
msPatArray)//如果模式串集中存在子串,则先释放子串数组占用空间
{
if(ps->
msPatArray->
psPat)free(ps->
psPat);
//子串不为空,则释放
free(ps->
msPatArray);
}
msNumArray)free(ps->
msNumArray);
msHash)free(ps->
msHash);
msPrefix)free(ps->
msPrefix);
msShift)free(ps->
msShift);
free(ps);
intwmAddPattern(WM_STRUCT*,unsignedchar*,int)
向模式串集ps中新增一个长度为m的子串q
q=>
要新增的子串
m=>
子串长度
int*-新增成功0,失败-1
intwmAddPattern(WM_STRUCT*ps,unsignedchar*q,intm)
WM_PATTERN_STRUCT*p;
//定义一个子串结构
p=(WM_PATTERN_STRUCT*)malloc(sizeof(WM_PATTERN_STRUCT));
p)return-1;
psPat=(unsignedchar*)malloc(m+1);
//据子串数组的长度分配空间
memset(p->
psPat+m,0,1);
//最后一个位置设置为结束字符“/0”
memcpy(p->
psPat,q,m);
//拷贝q到子串结构数组中
psLen=m;
//子串长度赋值
ps->
msNumPatterns++;
//模式串集的子串个数增1
if(p->
psLen<
(unsigned)ps->
msSmallest)ps->
msSmallest=p->
psLen;
//重新确定最短字符串长度
next=ps->
plist;
//将新增子串加入字符串集列表中。
队列形式,新增在队列头部
plist=p;
return0;
staticunsignedHASH16(unsignedchar*)
对一串字符进行哈希计算。
计算方式为:
(((*T)<
<
8)|*(T+1)),
T=>
要哈希计算的字符串
unsigned-静态函数,返回对字符串T计算的哈希值
staticunsignedHASH16(unsignedchar*T)
/*/
printf("
T:
%c\n"
*(T));
getchar();
T+1:
*(T+1));
T<
8:
(int)((*T)<
8));
HASH16:
%d\n"
((*T)<
8)|*(T+1));
//*/
return(unsignedshort)(((*T)<
//对第一个字符左移8位,然后与第二个字符异或运算
sort(WM_STRUCT*)
对字符串集ps中的子串队列,根据子串串值的哈希值从小到大排序
无
voidsort(WM_STRUCT*ps)
intm=ps->
msSmallest;
//获取最短子串长度
inti,j;
unsignedchar*temp;
intflag;
//冒泡排序的标志位。
当一趟比较无交换时,说明已经完成排序,即可以跳出循环结束
for(i=ps->
msNumPatterns-1,flag=1;
i>
0&
&
flag;
i--)//循环对字符串集中的每个子串,根据其哈希值大小进行冒泡排序
flag=0;
for(j=0;
j<
i;
j++)
{
if(HASH16(&
(ps->
msPatArray[j+1].psPat[m-2]))<
HASH16(&
msPatArray[j].psPat[m-2])))//比较的为每个子串截取部分的最后两个字符的哈希值
{
flag=1;
temp=ps->
msPatArray[j+1].psPat;
ps->
msPatArray[j+1].psPat=ps->
msPatArray[j].psPat;
msPatArray[j].psPat=temp;
}
}
函数:
staticvoidwmPrepHashedPatternGroups(WM_STRUCT*)
目的:
计算共有多少个不同的哈希值,且从小到大
参数:
ps=>
返回:
****************************************************************/
staticvoidwmPrepHashedPatternGroups(WM_STRUCT*ps)
unsignedsindex,hindex,ningroup;
inti;
msNumHashEntries=HASHTABLESIZE;
//HASH表的大小
msHash=(HASH_TYPE*)malloc(sizeof(HASH_TYPE)*ps->
msNumHashEntries);
//HASH表
ps->
msHash)
printf("
NomemoryinwmPrepHashedPatternGroups()\n"
);
return;
for(i=0;
i<
(int)ps->
msNumHashEntries;
i++)//HASH表预处理初始化,全部初始化为(HASH_TYPE)-1
ps->
msHash[i]=(HASH_TYPE)-1;
msNumPatterns;
i++)//针对所有子串进行HASH预处理
hindex=HASH16(&
msPatArray[i].psPat[m-2]);
//对模式子串的最后两个字符计算哈希值(匹配)
sindex=ps->
msHash[hindex]=i;
ningroup=1;
//此时哈希表已经有序了
while((++i<
msNumPatterns)&
(hindex==HASH16(&
msPatArray[i].psPat[m-2])))//找后缀相同的子串数
ningroup++;
msNumArray[sindex]=ningroup;
//第i个子串,其后的子模式串与其后缀2字符相同子串的个数
i--;
staticvoidwmPrepShiftTable(WM_STRUCT*)
建立shift表,算出每个字符块要移动的距离
staticvoidwmPrepShiftTable(WM_STRUCT*ps)
unsignedshortm,k,cindex;
unsignedshift;
m=(unsignedshort)ps->
msShift=(unsignedchar*)malloc(SHIFTTABLESIZE*sizeof(char));
msShift)
SHIFTTABLESIZE;
i++)//初始化Shift表,初始值为最短字符串的长度
msShift[i]=(unsigned)(m-2+1);
i++)//针对每个子串预处理
for(k=0;
k<
m-1;
k++)
shift=(unsignedshort)(m-2-k);
cindex=((ps->
msPatArray[i].psPat[k]<
8)|(ps->
msPatArray[i].psPat[k+1]));
//B为2
if(shift<
msShift[cindex])
msShift[cindex]=shift;
//k=m-2时,shift=0,
staticvoidwmPrepPrefixTable(WM_STRUCT*)
建立Prefix表
无
staticvoidwmPrepPrefixTable(WM_STRUCT*ps)//建立Prefix表
msPrefix=(HASH_TYPE*)malloc(sizeof(HASH_TYPE)*ps->
msNumPatterns);
//分配空间长度为所有子串的个数*
msPrefix)
NomemoryinwmPrepPrefixTable()\n"
i++)//哈希建立Prefix表
msPrefix[i]=HASH16(ps->
msPatArray[i].psPat);
//对每个模式串的前缀进行哈希
voidwmGroupMatch(WM_STRUCT*,int,unsignedchar*,unsignedchar*)
后缀哈希值相同,比较前缀以及整个字符串匹配
lindex=>
Tx=>
要进行匹配的字符串序列
模式子串
voidwmGroupMatch(WM_STRUCT*ps,
intlindex,//lindex为后缀哈希值相同的那些模式子串中的一个模式子串的index
unsignedchar*Tx,
unsignedchar*T)
WM_PATTERN_STRUCT*patrn;
WM_PATTERN_STRUCT*patrnEnd;
inttext_prefix;
unsignedchar*px,*qx;
patrn=&
msPatArray[lindex];
patrnEnd=patrn+ps->
msNumArray[lindex];
text_prefix=HASH16(T);
for(;
patrn<
patrnEnd;
patrn++)
msPrefix[lindex++]!
=text_prefix)
continue;
else//如果后缀哈希值相同,则
px=patrn->
psPat;
//取patrn的字串
qx=T;
while(*(px++)==*(qx++)&
*(qx-1)!
='
\0'
//整个模式串进行比较
if(*(px-1)=='
)//匹配到了结束位置,说明匹配成功
printf("
Matchpattern\"
%s\"
atline%dcolumn%d\n"
patrn->
psPat,nline,T-Tx+1);
nfound++;
intwmPrepPatterns(WM_STRUCT*ps)
对模式串集预处理,由plist得到msPatArray
int-预处理成功0,失败-1
intkk;
msPatArray=(WM_PATTERN_STRUCT*)malloc(sizeof(WM_PATTERN_STRUCT)*ps->
if
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- WM 算法 详解 语言 实现 代码 解析 参考