xxxx
7-1 【模板】KMP字符串匹配 (20 分)
点击查看代码
给出两个字符串text和pattern,其中pattern为text的子串,求出pattern在text中所有出现的位置。为了减少骗分的情况,接下来还要输出子串的前缀数组next。
输入格式:
第一行为一个字符串,即为text。
第二行为一个字符串,即为pattern。
输出格式:
若干行,每行包含一个整数,表示pattern在text中出现的位置。
接下来1行,包括length(pattern)个整数,表示前缀数组next[i]的值,数据间以一个空格分隔,行尾无多余空格。
输入样例:
ABABABC
ABA
结尾无空行
输出样例:
1
3
0 0 1
#include<bits/stdc++.h> using namespace std; string text; string pattern; long long nex[100000]; int outne[100000]; int len; int n; void getnext() { nex[0]=-1; int plen=0; int i=1; outne[0]=0; while(i<n) { if(pattern[i]==pattern[plen]) { plen++; outne[i]=plen; i++; } else { if(plen>0) { plen= outne[plen-1]; } else { outne[i]=plen; i++; } } } nex[0]=-1; for(i=0;i<n;i++) { nex[i+1]=outne[i]; } } void indexkmp() { getnext(); int i=0; int j=0; while(i<len) { if(j==n-1&&text[i]==pattern[j]) { cout<<i-j+1<<endl; // i=i-j+1; j=nex[j]; } if(j==-1||text[i]==pattern[j]) { i++; j++; } else { j=nex[j]; } } } int main() { cin>>text; cin>>pattern; len=text.length(); n=pattern.length(); indexkmp(); for(int i=0;i<n;i++) { if(i==n-1) cout<<outne[i]<<endl; else cout<<outne[i]<<" "; } return 0; }
7-2 串的模式匹配 (25 分)
点击查看代码
给定两个由英文字母组成的字符串 String 和 Pattern,要求找到 Pattern 在 String 中第一次出现的位置,并将此位置后的 String 的子串输出。如果找不到,则输出“Not Found”。
本题旨在测试各种不同的匹配算法在各种数据情况下的表现。各组测试数据特点如下:
数据0:小规模字符串,测试基本正确性;
数据1:随机数据,String 长度为 10
5
,Pattern 长度为 10;
数据2:随机数据,String 长度为 10
5
,Pattern 长度为 10
2
;
数据3:随机数据,String 长度为 10
5
,Pattern 长度为 10
3
;
数据4:随机数据,String 长度为 10
5
,Pattern 长度为 10
4
;
数据5:String 长度为 10
6
,Pattern 长度为 10
5
;测试尾字符不匹配的情形;
数据6:String 长度为 10
6
,Pattern 长度为 10
5
;测试首字符不匹配的情形。
输入格式:
输入第一行给出 String,为由英文字母组成的、长度不超过 10
6
的字符串。第二行给出一个正整数 N(≤10),为待匹配的模式串的个数。随后 N 行,每行给出一个 Pattern,为由英文字母组成的、长度不超过 10
5
的字符串。每个字符串都非空,以回车结束。
输出格式:
对每个 Pattern,按照题面要求输出匹配结果。
输入样例:
abcabcabcabcacabxy
3
abcabcacab
cabcabcd
abcabcabcabcacabxyz
结尾无空行
输出样例:
abcabcacabxy
Not Found
Not Found
#include<bits/stdc++.h> using namespace std; string S; string T; int slen; int tlen; int nex[1100000]; void getnext() { int pre=-1; nex[0]=-1; int j=0; while(j<tlen) { if(pre==-1||T[pre]==T[j]) { j++; pre++; nex[j]=pre; } else pre=nex[pre]; } /* for( j=0;j<tlen;j++) { cout<<nex[j]; }*/ } void index_KMP() { getnext(); int i=0; int j=0; while(i<slen) { if(j==tlen-1&&S[i]==T[j]) { for(i-=j;i<slen;i++) { cout<<S[i]; } return; } if(j==-1||S[i]==T[j]) { i++; j++; } else { j=nex[j]; } } cout<<"Not Found"; } int main() { cin>>S; slen=S.length(); int n; cin>>n; for( int i=0;i<n;i++) { cin>>T; tlen=T.length(); index_KMP(); cout<<endl; } return 0; }
7-3 字符串模式匹配 (5 分)
点击查看代码
给定主串s和模式串p,编写程序输出p在s中出现的首位置,若p不在s中则输出-1。字符串下标从0开始。输入格式:
输入为2行,第1行主串s,第2行为模式串p。主串和模式串长度不超过100000。
输出格式:
输出为2行,第1行为若干整数,表示模式串p的失败函数值,每个整数后一个空格;第2行为一个整数,表示p在s中出现的首位置,若p不在s中则输出-1。
输入样例:
qwerabcabhlk
abcab
输出样例:
-1 -1 -1 0 1
4
#include<bits/stdc++.h> using namespace std; string S; string T; int slen; int tlen; void getnext(int next[]) { int pre=0; next[0]=0; int j=1; while(j<tlen) { if(T[pre]==T[j]) { pre++; next[j]=pre; j++; } else { if(pre>0) pre=next[pre-1]; else { next[j]=pre; j++; } } } for(int i=0;i<tlen;i++) { if(i==tlen-1) { cout<<next[i]-1<<" "<<endl; } else{ cout<<next[i]-1<<" "; } } for(int i=tlen-1;i>0;i--) { next[i+1]=next[i]; } next[0]=-1; } void indexkmp() { int next[10000]; getnext(next); int i=0; int j=0; while(i<slen) { if(j==tlen-1&&S[i]==T[j]) { cout<<i-j<<endl; return; } if(j==-1||S[i]==T[j]) { i++; j++; } else { j=next[j]; } } cout<<-1<<endl; } int main() { cin>>S>>T; slen=S.length(); tlen=T.length(); indexkmp(); return 0; }
好中缀
点击查看代码
我们称一个字符串S的子串T为好中缀,如果T是去除S中满足如下条件的两个子串p和q后剩余的字符串。(1)p是S的前缀,q是S的后缀;
(2)p=q;
(3)p和q是满足条件(1)(2)的所有子串中的第二长者。
注意一个字符串不能称为自己的前缀或后缀。好中缀至少为空串,其长度大于等于0,不能为负数。
输入格式:
输入为一个字符串S,包含不超过100000个字母。
输出格式:
输出为一个整数,表示好中缀的长度。
输入样例1:
abcabcxxxabcabc
输出样例1:
9
输入样例2:
xacbacba
输出样例2:
8
输入样例3:
aaa
输出样例3:
1
#include<bits/stdc++.h> using namespace std; string s; int nnex[100100]; int ans[100100]; void getnext(int n) { nnex[0]=-1; int pre=-1; int j=0; while(j<n) { if(pre==-1||s[pre]==s[j]) { pre++; j++; nnex[j]=pre; } else { pre=nnex[pre]; } } } int main() { cin>>s; getnext(s.length()); int len=s.length(); int j=nnex[len]; int c=0; int cnt=0; while(j>0) { ans[c++]=j; j=nnex[j]; } sort(ans,ans+len,greater<int>()); int x=len-ans[1]*2; if(x<0) x=0; cout<<x<<endl; return 0; }
7-5 三元组顺序表表示的稀疏矩阵转置Ⅱ (10 分)
点击查看题目
三元组顺序表表示的稀疏矩阵转置Ⅱ。设a和b为三元组顺序表变量,分别表示矩阵M和T。要求按照a中三元组的次序进行转置,并将转置后的三元组置入b中恰当的位置。
输入格式:
输入第1行为矩阵行数m、列数n及非零元素个数t。 按行优先顺序依次输入t行,每行3个数,分别表示非零元素的行标、列标和值。
输出格式:
按置入b中的顺序输出置入的位置下标,转置后的三元组行标、列标和值,数据之间用空格分隔,共t行。
输入样例1:
3 4 3
0 1 -5
1 0 1
2 2 2
结尾无空行
输出样例1:
1 1 0 -5
0 0 1 1
2 2 2 2
#include<stdio.h> typedef struct { int p,i, j; int data; }triple; typedef struct { triple data[10]; int n, m, num; }TSMATRIX; TSMATRIX ChangeMatr(TSMATRIX M, TSMATRIX T) { T.m = M.n; T.n = M.m; T.num = M.num; if (T.num) { int q = 0; int col; for (col = 0; col <= M.m; ++col) { int p; for (p = 0; p < M.num; ++p) { if (M.data[p].j == col) { T.data[q].i = M.data[p].j; T.data[q].j = M.data[p].i; T.data[q].data = M.data[p].data; q++; } } } } return T; } int main() { TSMATRIX M; int k=0; scanf("%d %d %d",&M.m,&M.n,&M.num); while(k!=M.num){ scanf("%d %d %d",&M.data[k].i,&M.data[k].j,&M.data[k].data); k++; } TSMATRIX T; int k1; for (k1 = 0; k1 <=M.num; k1++) { T.data[k1].i = 0; T.data[k1].j = 0; T.data[k1].data = 0; } T = ChangeMatr(M, T); int i; for (i = 0; i < T.num; i++) { T.data[i].p = i; } for (i = 0; i < T.num; i++) { int j; int k = M.data[i].data; for(j = 0; j < T.num; j++){ if(T.data[j].data == k){ printf((i+1 == T.num) ? "%d %d %d %d":"%d %d %d %d\n", T.data[j].p, T.data[j].i, T.data[j].j, T.data[j].data); } } } return 0; }
本文作者:kingwzun
本文链接:https://www.cnblogs.com/kingwz/p/15507690.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步