【AC自动机 】(KMP+Trie|多模式串匹配|BFS|串排序、检索|非持久化)

导入头文件|定义常量

#include <cctype>
#include <cstring>

#include <vector>
#include <string>
#include <queue>

enum CV{
	DIGIT = 10,
	LETTER = 26,
};
constexpr int MAX_NODE{(int)(1e3)},
			SIGMA{CV::DIGIT+(CV::LETTER<<1|1)};

结构体定义

struct Trie{

	int ch[MAX_NODE+1][SIGMA]{{0,},};

	int val[MAX_NODE+1][MAX_NODE+1]{{0,},};

	int Next[MAX_NODE+1]{0,};

	int cnt[MAX_NODE+1]{0,};

	int tot{1};

    Trie(void):
        size(1)
    {
        memset(ch,-1,sizeof ch);
        memset(val,-1,sizeof val);
    }
	
	static inline int idxOfChar(const char c);
   	static inline char idxToChar(const int idx):

	inline void MNode(int u,int ich);

   	void insert(const char *s,int v);
	void bfs(void);
	int pattern(const char *s);
	void find(const char *s,std::vector<int>& res);
	
    using STAT = std::pair<std::string,int>;
	void sort(int o,std::vector< STAT > &res,std::string s);
};

函数实现


static inline 
    int Trie::idxOfChar(const char c){
        return isdigit(c)?c-'0':
            (isupper(c)?c-'A'+CV::DIGIT:
                c-'a'+CV::DIGIT+CV::LETTER);
    }
static inline 
    char idxToChar(const int idx){
        return idx < CV::DIGIT?'0'+idx:
            (idx < CV::LETTER+CV::DIGIT?idx+'A':
                idx+'a');
    }
inline 
    void MNode(int u,int ich){
        ch[u][ich] = (tot++);
    }
void insert(const char *s,int v){
 	int u = 0,
        ich = s[0],
        i;
    for(i = 0;s[i];u = ch[u][ich],++i)
   		if(!~ch[u][ich = idxOfChar(s[i])])
            MNode(u,ich);
    val[u][cnt[u]++] = u;
}
void bfs(void){
	std::queue<int> Q;Q.push(0);
	while(!Q.empty()){
		int x = Q.front();Q.pop();
		int i;
		for(i = 0;i < SIGMA;++i){
			if(!~ch[x][i]){
				Q.push(ch[x][i]);
				Next[ch[x][i]] = (!x)?0:ch[Next[x]][i];
			}
			else ch[x][i] = ch[Next[x]][i];
		}
	}
}
int pattern(const char *s){
	int x = 0,
        res = 0,
        i;
	for(i = 0;s[i];++i)
        res+=cnt[x],
        x = ch[x][idxOfChar(s[i])];
	return 0;
}
void find(const char *s,std::vector<int>& res){
	int u = 0,
        ich = idxOfChar(s[0]),
        len = strlen(s),
        i;
	for(i = 0;s[i] && !~ch[u][ich];++i)
        u = ch[u][ich = idxOfChar(s[i])];
	return (void)(i == len?res.assign(val[u],val[u]+cnt[u]):(void)-1);
}

using STAT = std::pair<std::string,int>;
void sort(int o,std::vector< STAT > &res,std::string s){
	if(o + 1 > MAX_NODE)return;
	if(o && cnt[o])res.push_back((STAT){s,cnt[o]});
	int i;
	for(i = 0;i < SIGMA;++i)
		if(!~ch[o][i])
			iterate(ch[o][i],res,s+idxToChar(Next[o][i]));
}
};

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

XNB's Not a Beginner

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值