zoj3441 Searching the String

本文详细介绍AC自动机的构建过程及其在字符串匹配问题中的应用。通过实例演示如何使用AC自动机解决覆盖串和非覆盖串的问题,并提供了一个完整的C++实现代码。适合对字符串匹配算法感兴趣的读者。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

对于可以覆盖的串,直接上模板。
对于不能覆盖的串,可以记录字典树中当前节点在询问串中的上一次询问的位置。然后对于不能覆盖的询问,用当前串的位置减去上一次询问字典树中当前节点的位置和当前深度比较一下就行了。

#include<bits/stdc++.h>
using namespace std;
const int maxn  = 6e5+5;
int res[maxn][2];
struct AC{
	int tot, root, nex[maxn][26];
	int f[maxn], deep[maxn], last[maxn];
	int newnode() {
		for(int i = 0; i < 26; i++) {
			nex[tot][i] = -1;
		}
		return tot++;
	}
	void init() {
		tot = 0;deep[0] = 0;
		root = newnode();
		memset(last, -1, sizeof(last));
		memset(res, 0, sizeof(res));
	}
	int insert(char *s) {
		int u = root;
		for(int i = 0; i < strlen(s); i++) {
			int ch = s[i]-'a';
			if(nex[u][ch] == -1){
				nex[u][ch] = newnode();
				deep[nex[u][ch]] = deep[u] + 1;
			}
			u = nex[u][ch];
		}
		return u;
	}
	void getfail() {
        queue<int>Q;
        f[root] = root;
        for(int i = 0; i < 26; i++) {
            if(nex[root][i] != -1) {
                f[nex[root][i]] = root;
                Q.push(nex[root][i]);
            }
            else nex[root][i] = root;
        }
        while (!Q.empty()) {
            int u = Q.front();Q.pop();
            for(int i = 0; i < 26; i++) {
                if(nex[u][i] == -1) {
                    nex[u][i] = nex[f[u]][i];
                }
                else {
                    f[nex[u][i]] = nex[f[u]][i];
                    Q.push(nex[u][i]);
                }
            }
        }
    }
	void query(char *s) {
        int u = root;
        int len = strlen(s);
        for(int i = 0; i < len; i++) {
            int ch = s[i]-'a';
            u = nex[u][ch];
            int t = u;
            while(t != root) {
                res[t][0]++;
                if(i-last[t] >= deep[t]) {
                	res[t][1]++;
                	last[t] = i;
                }
                t = f[t];
            }
        }
    }
}ac;
char ss[maxn], s[maxn];
int op[maxn], n;
int p[maxn], T = 0;
void solve() {
	ac.init();
	scanf("%d", &n);
	int cnt = 0;
	for(int i = 1; i <= n; i++) {
		scanf("%d%s", &op[i], s);
		p[i] = ac.insert(s);
	}
	ac.getfail();
	ac.query(ss);
	printf("Case %d\n", ++T);
	for(int i = 1; i <= n; i++) {
		printf("%d\n", res[p[i]][op[i]]);
	}
	cout<<endl;
}
int main() {
	int Case = 1;
	//scanf("%d", &Case);
	while(scanf("%s", ss) == 1)
		solve();
}
内容概要:本文档是关于基于Tecnomatix的废旧智能手机拆解产线建模与虚拟调试的毕业设计任务书。研究内容主要包括:分析废旧智能手机拆解工艺流程;学习并使用Tecnomatix软件搭建拆解产线的三维模型,包括设备、输送装置等;进行虚拟调试以模拟各种故障情况,并对结果进行分析提出优化建议。研究周期为16周,涵盖了文献调研、拆解实验、软件学习、建模、调试和论文撰写等阶段。文中还提供了Python代码来模拟部分关键流程,如拆解顺序分析、产线布局设计、虚拟调试过程、故障模拟与分析等,并实现了结果的可视化展示。 适合人群:本任务书适用于机械工程、工业自动化及相关专业的本科毕业生,尤其是那些对智能制造、生产线优化及虚拟调试感兴趣的学生。 使用场景及目标:①帮助学生掌握Tecnomatix软件的应用技能;②通过实际项目锻炼学生的系统建模和虚拟调试能力;③培养学生解决复杂工程问题的能力,提高其对废旧电子产品回收再利用的认识和技术水平;④为后续的研究或工作打下坚实的基础,比如从事智能工厂规划、生产线设计与优化等工作。 其他说明:虽然文中提供了部分Python代码用于模拟关键流程,但完整的产线建模仍需借助Tecnomatix商业软件完成。此外,为了更好地理解和应用这些内容,建议学生具备一定的编程基础(如Python),并熟悉相关领域的基础知识。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值