ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

KMP,Trie,&&洛谷P2580

2022-09-13 18:30:40  阅读:252  来源: 互联网

标签:洛谷 P2580 Trie ++ son char int maxn str


KMP:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=1e6+5;
 4 char a[maxn],b[maxn],aa[maxn],bb[maxn];
 5 //aa,bb为输入的字符串 
 6 //为了方便KMP的实现
 7 //另开a,b两个字符串为实际操作自符串
 8 //b为模式串 
 9 int nxt[maxn],cx[maxn];
10 //nxt【i】为b中以下标 i结尾“非前缀”的子串中
11 //与前缀相同的最大长度 
12 int main(){
13     cin>>aa>>bb;
14     int la=strlen(aa);
15     int lb=strlen(bb);
16     for(int i=0;i<la;i++)a[i+1]=aa[i];//使首字母下标为1 
17     for(int i=0;i<lb;i++)b[i+1]=bb[i];//同上 
18     int j=0;
19     for(int i=2;i<=lb;i++){//nxt非前缀,i从2开始枚举 
20         while(j>0&&b[i]!=b[j+1])j=nxt[j];
21         //无法继续匹配,j缩小至nxt【j】 
22         if(b[i]==b[j+1])j++;
23         nxt[i]=j;
24     }
25     j=0;//初始化 
26     for(int i=1;i<=la;i++){
27     //a与b匹配,无非前缀要求,i从一开始枚举
28         while(j>0&&(j==lb||a[i]!=b[j+1]))j=nxt[j];
29         if(a[i]==b[j+1])j++;
30         cx[i]=j;
31         if(cx[i]==lb){ 
32         // 连续出现最大长度 等于b长度
33         //b在a中出现一次,以i结尾 
34             printf("%d\n",i-j+1);
35         }
36     }
37     for(int i=1;i<=lb;i++){
38         printf("%d ",nxt[i]);
39     }
40     return 0;
41 } 

Trie(字典树):

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=1e5+5;
 4 char str[maxn];
 5 int n;
 6 int son[maxn][30],cnt[maxn],idx;
 7 void insert(char str[]){
 8     int p=0;
 9     for(int i=0;str[i];i++){
10         int u=str[i]-'a';
11         if(!son[p][u])son[p][u]=++idx;
12         p=son[p][u];
13     }
14     cnt[p]++;
15 }
16 int question(char str[]){
17     int p=0;
18     for(int i=0;str[i];i++){
19         int u=str[i]-'a';
20         if(!son[p][u])return 0;
21         p=son[p][u];
22     }
23     return cnt[p];
24 }
25 int main(){
26     scanf("%d",&n);
27     while(n--){
28         char op[2];
29         scanf("%s%s",&op,&str);
30         if(op[0]=='I')insert(str);
31         else 
32         printf("%d\n",question(str));
33     }
34     return 0;
35 } 

没来得及写注释,下次一定,回头补一下

洛谷P2580于是他错误的点名开始了

由判断一个字符串出现几次变为判断字符串是否出现,需要加特判,不然最后一个Hash毒瘤数据会被卡(但是被卡了也显示我是100,只不过不是Accept

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=2000005;
 4 int n,m,son[maxn][30],cnt[2000005],idx;
 5 char str[maxn];
 6 bool vis[2000005];
 7 void insert(char str[]){
 8     int p=0;
 9     for(int i=0;str[i];i++){
10         int u=str[i]-'a';
11         if(!son[p][u])son[p][u]=++idx;
12         p=son[p][u];
13     }
14     cnt[p]=1;
15 }
16 void find(char str[]){
17     int p=0;
18     for(int i=0;str[i];i++){
19         int u=str[i]-'a';
20         if(!son[p][u]){
21             printf("WRONG\n");
22             return ;
23         }
24         p=son[p][u];
25     }
26     if(vis[p]==1){
27         printf("REPEAT\n");
28         return ;
29     }
30     else if(cnt[p]){
31         vis[p]=1;
32         printf("OK\n");
33         return ;
34     }
35     printf("WRONG\n");
36 }
37 int main(){
38     scanf("%d",&n);
39     for(int i=1;i<=n;i++){
40         scanf("%s",str);
41         insert(str);
42     }
43     scanf("%d",&m);
44     for(int i=1;i<=m;i++){
45         scanf("%s",str);
46         find(str);
47     }
48     return 0;
49 }

同样没来得及写注释

姑且先记录一下

 

//我曾难自拔于世界之大

//也沉溺于其中梦话

//不得真假,不做挣扎,不惧笑话

//我曾将青春翻涌成她

//也曾指尖弹出盛夏

//心之所动,就随风去吧

//---《起风了》

 

愿我们能一直勇敢下去

标签:洛谷,P2580,Trie,++,son,char,int,maxn,str
来源: https://www.cnblogs.com/TFLSc1908lzs/p/16690308.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有