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;
}

posted @ 2021-11-04 13:01  kingwzun  阅读(241)  评论(0编辑  收藏  举报