其他分享
首页 > 其他分享> > KMP,Trie,&&洛谷P2580

KMP,Trie,&&洛谷P2580

作者:互联网

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