字符串匹配算法之Sunday search
字符串匹配算法之Sunday searchC++编写#include<cstring>#include<vector>#include<iostream>#include<queue>using namespace std;class Node{public:Node* fail;//失败指针Node* child[26];//26个小写字母,26个
·
字符串匹配算法之Sunday search
C++编写
#include<cstring>
#include<vector>
#include<iostream>
#include<queue>
using namespace std;
class Node {
public:
Node* fail; //失败指针
Node* child[26]; //26个小写字母,26个子节点
vector<int> len; //在结尾字符存放单词的长度
Node()
{
fail = NULL;
memset(child, NULL, 26*sizeof(Node*));
}
};
void insert(string, Node*);
void build_fail(Node* root);
void AC_search(string txt, Node* root);
int main()
{
Node* root = new Node(); //初始化root根节点,root->fail=NULL
string str[5] = {"his","she","is","he","hers"}; //多匹配模式的字符串
for(int i=0; i<5; i++) {
cout<<str[i]<<" ";
insert(str[i], root); //创建字典树
}
string txt = "ahishersheishiser"; //文本串txt
cout<<endl << txt<<endl;
cout<<"********************************************"<<endl;
build_fail(root); //根据创建的字典树找到每个存在节点的fail指针
AC_search(txt, root); //根据文本串匹配多匹配串
return 0;
}
void insert(string s, Node* root)
{
Node* temp = root;
for(int i=0; i<s.size(); i++) {
int index = s[i] - 'a';
if(NULL == temp->child[index]) //在此之前没有s[i]字符
temp->child[index] = new Node();
temp = temp->child[index];
}
temp->len.push_back(s.size()); //结尾单词标注单词长度信息
}
/*
build_fail():将建立好的字典树确定其fail信息
*/
void build_fail(Node* root)
{
queue<Node*> que; //bfs层序遍历
for(int i=0; i<26; ++i) {
if(root->child[i]) { //每个匹配串的首字符的fail指向root
root->child[i]->fail = root; //root子节点的fail指针指向root
que.push(root->child[i]);
}
}
while(!que.empty()) //只要队列不为空就继续fail寻找操作
{
Node* curr = que.front(); //curr表示当前的节点
que.pop();
for(int i=0; i<26; i++) {
if(curr->child[i]) { //当前节点的子节点存在,加入queue中等待处理
Node* x = curr->child[i];
Node* fafail = curr->fail; //fafail表示当前节点的fail指针指向节点
que.push(x);
while(fafail && NULL==fafail->child[i])
fafail = fafail->fail; //继续往上一层寻找
if(fafail == NULL)
x->fail = root; //如果是因为找到了root还未找到待匹配节点,就将此节点的fafail指向root,意为从头开始匹配
else {
x->fail = fafail->child[i]; //到这一步意味着找到了当下节点X的fail了,就是fafail指向的child[i],和x节点代表的字符相同
if(x->fail->len.size()) //若fail指向的节点是一个单词的结尾,记录到X中,方便接下来的输出cout操作
for(int k=0; k<x->fail->len.size(); k++)
x->len.push_back(x->fail->len[k]);
}
}
}
}
}
/*
AC_search(),根据已经建好的字典树,给出txt文本串进行多模匹配
*/
void AC_search(string txt, Node* root)
{
cout<<txt<<endl; //输出文本串
Node* p = root;
for(int i=0; i<txt.size(); i++) //txt逐个匹配
{
int index = txt[i]-'a';
while(NULL==p->child[index] && p->fail)
p = p->fail;
if(p->child[index])
p = p->child[index];
else
continue; //继续for循环
if(p->len.size()) { //查询到一个单词的结尾字符
for(int k=0; k<p->len.size(); k++) {
int length = p->len[k];
int j = 0;
for(; j<i-length+1; j++)
cout<<' ';
for(int t=0; t<length; t++)
cout<<txt[j+t];
cout<<endl;
}
}
}
}
点击阅读全文
更多推荐
活动日历
查看更多
直播时间 2025-02-26 16:00:00


直播时间 2025-01-08 16:30:00


直播时间 2024-12-11 16:30:00


直播时间 2024-11-27 16:30:00


直播时间 2024-11-21 16:30:00


所有评论(0)