Files
mir_server/server/LogicServer/base/AcAuto.cpp
aixianling 5c9f1dae4a init
2025-01-09 17:45:40 +08:00

116 lines
2.3 KiB
C++

#include "StdAfx.h"
AcAuto::node::node(bool bUseAsAux)
: fail(nullptr)
, count(0)
, m_bUseAsAux(bUseAsAux)
{ //构造函数初始化
memset(next, 0, sizeof(next));
}
AcAuto::node::~node(){
if (! m_bUseAsAux){
for (int i = 0; i < kind; ++i){
node*& p = next[i];
if (p){
delete p;
p = nullptr;
}
}
}else{
element = nullptr;
nextAuxNode = nullptr;
}
}
AcAuto::AcAuto(void)
: m_Root(new node)
, m_bBuild(false)
{
}
AcAuto::~AcAuto(void)
{
if (m_Root){
delete m_Root;
m_Root = nullptr;
}
}
/// @param str 输入的字符串
/// @param bOnlyCheckHasKeyWorld 只是简单检查是否有关键字,不需要统计共有多少个
int AcAuto::Query(const char* str, bool bOnlyCheckHasKeyWorld ){
if (! m_bBuild){
return 0;
}
unsigned int i(0), cnt(0), len(strlen(str));
unsigned char index ;
node *p(m_Root);
while(index = str[i++]){ // 取一个字节
while(p->next[index] == nullptr && p != m_Root) p = p->fail;
p = p->next[index];
p= (p==nullptr) ? m_Root : p;
node *temp(p);
while(temp != m_Root && temp->count != -1){
cnt += temp->count;
temp->count = -1;
temp = temp->fail;
if(bOnlyCheckHasKeyWorld && cnt)return cnt;
}
}
return cnt;
}
void AcAuto::InsertKeyWord(const char* keyWord){
node *p(m_Root);
unsigned int i(0);
unsigned char index;
while(index = keyWord[i]){ // 构造关键字树
node*& next = p->next[index];
if( ! next) next = new node();
p = next;
++i;
}
++p->count;
}
/// 设置 fail 指针
void AcAuto::BuildAcAutomation(){
m_Root->fail = nullptr;
node* auxList = new node(true);
auxList->element = m_Root;// 插入首个
node* temp;
node* firstNode(auxList), *lastNode(auxList);
while(firstNode && (temp = firstNode->element)){ // 取一个
node* p(nullptr);
for(int i = 0; i < kind; ++i){
node* tnext(temp->next[i]);
if(tnext){
if(temp == m_Root) tnext->fail = m_Root;
else{
p = temp->fail;
while(p){
if(p->next[i]){
tnext->fail = p->next[i];
break;
}
p = p->fail;
}
if( ! p) tnext->fail = m_Root;
}
// 插入个新的
node* auxNode(new node(true));
auxNode->element = tnext;
lastNode->nextAuxNode = auxNode;
lastNode = auxNode;
}
}
node* cur(firstNode);
firstNode = firstNode->nextAuxNode;
delete cur;
}
m_bBuild = true;
}