ac自动机俩模板

AC自动机详解
本文深入讲解AC自动机的实现细节,包括插入操作、失败指针的建立及模式匹配过程。通过对两个不同实现方式的对比,帮助读者理解AC自动机的工作原理。

ac自动机算法正确性还没有理解,算法导论也看不懂。。等懂了回来发算法专题。

 1 #include <cstdio>
 2 #include <cstring>
 3 using namespace std;
 4 
 5 const int maxn=1e6+5;
 6 
 7 int n;
 8 char s[maxn];
 9 
10 class AC{
11 public:
12     struct node{
13         node *son[26], *fail;
14         int mark;
15     }root, *now, *nowson, *p;
16     AC(){}
17     void insert(char *s, int len){ //trie,没什么好说的
18         now=&root;
19         int v;
20         for (int i=0; i<len; ++i){
21             v=s[i]-'a';
22             if (!now->son[v]) now->son[v]=new node();
23             now=now->son[v];
24         }
25         ++now->mark;
26     }
27     void get_fail(){ //建立失败指针
28         int head=0, tail=1;
29         q[head]=&root;
30         while (head<tail){ //宽搜
31             now=q[head];
32             for (int i=0; i<26; ++i) //遍历每个儿子
33             if (now->son[i]){
34                 for (p=now->fail; p&&!p->son[i]; p=p->fail); //通过父亲来找失败指针
35                 //p是0,意味着连root都不行,那只能去root
36                 now->son[i]->fail=(p?p->son[i]:&root);
37                 q[tail++]=now->son[i];
38             } //else now->son[i]=now->fail->son[i]; //如果没有这个子节点,意味着肯定失配
39             ++head;
40         }
41     }
42     int count(char *s, int len){ //计算有多少个串出现
43         int ans=0;
44         now=&root;
45         int v;
46         for (int i=0; i<len; ++i){
47             //确定适配的树的结点位置
48             for (v=s[i]-'a'; now&&!now->son[v]; now=now->fail);
49             now=now?now->son[v]:&root; //如果一直到根还不匹配,那就跳到根
50             //对于一个匹配串的所有后缀检查
51             //如果这里ans没设置为-1,那就是求出现次数之和
52             for (p=now; p&&~p->mark; p=p->fail) {
53                 ans+=p->mark;
54                 p->mark=-1;
55             }
56         }
57         return ans;
58     }
59 private:
60     node *q[maxn], head, tail;
61 };
62 
63 AC ac;
64 
65 int main(){
66     scanf("%d", &n);
67     for (int i=0; i<n; ++i){
68         scanf("%s", s);
69         int t=strlen(s);
70         ac.insert(s, t);
71     }
72     ac.get_fail();
73     scanf("%s", s);
74     printf("%d\n", ac.count(s, strlen(s)));
75     return 0;
76 }
  1 #include <cstdio>
  2 #include <cstring>
  3 using namespace std;
  4 
  5 const int maxn=155, maxl1=75, maxl2=1e6+5;
  6 
  7 int n, cnt, ans[maxn];
  8 char p[maxn][maxl1];
  9 char t[maxl2];
 10 
 11 struct node{
 12     node *son[26], *fail;
 13     int id, mark;
 14 }*mem[maxn*maxl1];
 15 class AC{
 16 public:
 17     node *root, *now, *nowson, *p;
 18     AC(){ root=new node(); }
 19     void fresh(){
 20         cnt=0;
 21         delete root;
 22         root=new node();
 23         for (int i=0; i<memlen; ++i) delete mem[i];
 24         memlen=0;
 25     }
 26     void insert(char *s, int len){ //trie,没什么好说的
 27         now=root;
 28         int v;
 29         for (int i=0; i<len; ++i){
 30             v=s[i]-'a';
 31             if (!now->son[v]) {
 32                 now->son[v]=new node();
 33                 mem[memlen++]=now->son[v];//内存回收表
 34             }
 35             now=now->son[v];
 36         }
 37         //如果不去重,这里写成等于1
 38         now->id=cnt++;
 39         ++now->mark;
 40     }
 41     void get_fail(){ //建立失败指针
 42         int head=0, tail=1;
 43         q[head]=root;
 44         while (head<tail){ //宽搜
 45             now=q[head];
 46             for (int i=0; i<26; ++i) //遍历每个儿子
 47             if (now->son[i]){
 48                 for (p=now->fail; p&&!p->son[i]; p=p->fail); //通过父亲来找失败指针
 49                 //p是0,意味着连root都不行,那只能去root
 50                 now->son[i]->fail=(p?p->son[i]:root);
 51                 q[tail++]=now->son[i];
 52             } //else now->son[i]=now->fail->son[i]; //如果没有这个子节点,意味着肯定失配
 53             ++head;
 54         }
 55     }
 56     void count(char *s, int len){ //计算有多少个串出现
 57         now=root;
 58         int v;
 59         for (int i=0; i<len; ++i){
 60             //确定适配的树的结点位置
 61             for (v=s[i]-'a'; now&&!now->son[v]; now=now->fail);
 62             now=now?now->son[v]:root; //如果一直到根还不匹配,那就跳到根
 63             //对于一个匹配串的所有后缀检查
 64             //如果这里ans没设置为-1,那就是求出现次数之和
 65             for (p=now; p&&~p->mark; p=p->fail) {
 66                 ans[p->id]+=p->mark;
 67                 //p->mark=-1;
 68             }
 69         }
 70     }
 71 private:
 72     node *q[maxn*maxl1]; //这里忘记加了
 73     int memlen;
 74 };
 75 
 76 AC ac;
 77 
 78 int main(){
 79     scanf("%d", &n);
 80     while (n){
 81         memset(ans, 0, sizeof(ans));
 82         for (int i=0; i<n; ++i){
 83             scanf("%s", p[i]);
 84             int t=strlen(p[i]);
 85             ac.insert(p[i], t);
 86         }
 87         ac.get_fail();
 88         scanf("%s", t);
 89         ac.count(t, strlen(t));
 90         int maxm=0;
 91         for (int i=0; i<n; ++i)
 92             if (ans[i]>maxm) maxm=ans[i];
 93         printf("%d\n", maxm);
 94         for (int i=0; i<n; ++i)
 95             if (ans[i]==maxm) printf("%s\n", p[i]);
 96         scanf("%d", &n);
 97         ac.fresh();
 98     }
 99     return 0;
100 }

 

转载于:https://www.cnblogs.com/MyNameIsPc/p/7513545.html

内容概要:本文介绍了一个基于MATLAB实现的无人机三维路径规划项目,采用蚁群算法(ACO)与多层感知机(MLP)相结合的混合模型(ACO-MLP)。该模型通过三维环境离散化建模,利用ACO进行全局路径搜索,并引入MLP对环境特征进行自适应学习与启发因子优化,实现路径的动态调整与多目标优化。项目解决了高维空间建模、动态障碍规避、局部最优陷阱、算法实时性及多目标权衡等关键技术难题,结合并行计算与参数自适应机制,提升了路径规划的智能性、安全性和工程适用性。文中提供了详细的模型架构、核心算法流程及MATLAB代码示例,涵盖空间建模、信息素更新、MLP训练与融合优化等关键步骤。; 适合人群:具备一定MATLAB编程基础,熟悉智能优化算法与神经网络的高校学生、科研人员及从事无人机路径规划相关工作的工程师;适合从事智能无人系统、自动驾驶、机器人导航等领域的研究人员; 使用场景及目标:①应用于复杂三维环境下的无人机路径规划,如城市物流、灾害救援、军事侦察等场景;②实现飞行安全、能耗优化、路径平滑与实时避障等多目标协同优化;③为智能无人系统的自主决策与环境适应能力提供算法支持; 阅读建议:此资源结合理论模型与MATLAB实践,建议读者在理解ACO与MLP基本原理的基础上,结合代码示例进行仿真调试,重点关注ACO-MLP融合机制、多目标优化函数设计及参数自适应策略的实现,以深入掌握混合智能算法在工程中的应用方法。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值