首页 > 其他分享 >第二题-塔子哥的编译原理实验【KMP】

第二题-塔子哥的编译原理实验【KMP】

时间:2024-05-23 22:31:30浏览次数:19  
标签:塔子哥 int text back st 编译 && KMP

本题的模式串可以展开,使用栈来模拟即可,每次一个(放入栈中对应的位置以及前面的数量,每次)弹出栈顶元素,然后将栈顶元素的数量乘以当前的字符串加上栈顶元素的前面的字符串加入到模式串中即可。

需要注意有可能模式串非常长,所以中间需要判断是否已经超过了匹配串的长度,超过则直接返回。

有了模式串和匹配串之后,就可以使用KMP算法来进行匹配了。

#include<bits/stdc++.h>

using namespace std;
const int N = 2e5+100;

char ta[N],a[N],b[N];
int Next[N];
//getNext求解长度为len的字符串s的next数组
void getNext(char s[],int len)
{
	int j=-1;
	Next[0]=-1;                //初始化j=next[0]=-1;
//	cout<<next[0]<<endl;
	for(int i=1;i<len;i++)     //求解next[1]~next[len-1]
	{
		while(j!=-1&&s[i]!=s[j+1])
		{
			j=Next[j];      //反复令j=next[j];
		}  //直到j回退到-1,或是s[i]==s[j+1]
		if(s[i]==s[j+1])
			j++;  //则next[i]=j+1,先令j指向这个位置
		Next[i]=j;    //令next[i]=j
	}
}

//KMP算法,判断pattern是否是text的子串
int KMP(char text[],char pattern[])
{
	int n=strlen(text),m=strlen(pattern);   //求字符串长度
	getNext(pattern,m);     //计算pattern的next数组
	int j=-1;    //初始化j为-1,表示当前还没有任意一位被匹配
	for(int i=0;i<n;i++)  
	{     //这里i是从0开始
//		while(j!=-1&&text[i]!=pattern[j+1])   //试图匹配text[i]
//			j=Next[j];   //不断回退,直到j回到-1或text[i]==pattern[j+1]
//		if(text[i]==pattern[j+1])
//			j++;        //text[i]与pattern[j+1]匹配成功,令j加1
		while(j!=-1&&((pattern[j+1]=='N'&&!(text[i]>='0'&&text[i]<='9'))||(pattern[j+1]=='A'&&(text[i]>='0'&&text[i]<='9'))))   //试图匹配text[i]
			j=Next[j];   //不断回退,直到j回到-1或text[i]==pattern[j+1]
		if((pattern[j+1]=='N'&&(text[i]>='0'&&text[i]<='9'))||(pattern[j+1]=='A'&&!(text[i]>='0'&&text[i]<='9')))
			j++;        //text[i]与pattern[j+1]匹配成功,令j加1
		if(j==m-1)    //pattern完全匹配,说明pattern是text的子串
			return i;
	}
	return -1;   //执行完text还没匹配成功,说明pattern不是text的子串
}
signed main(){
	scanf("%s%s",a,b);
	int alen=strlen(a);
	deque<int> st; 
	int num=0;
	for(int i=0;i<alen;i++){
		if(a[i]>='0'&&a[i]<='9'){
			num=num*10+(int)(a[i]-'0');
		}else if(a[i]=='('){
			st.push_back(num);
			num=0;
		}else if(a[i]==')'){
			vector<int> p;p.clear();
			while(st.size()&&(st.back()==-1||st.back()==-2)){
				p.push_back(st.back());
				st.pop_back();
			}
			int num=st.back();st.pop_back();
//			cout<<"num:"<<num<<endl;
			reverse(p.begin(),p.end());
			for(int j=0;j<num;j++){
				for(int k=0;k<p.size();k++){
					st.push_back(p[k]);
				}
			}
		}else{
			if(a[i]=='A') st.push_back(-1);
			else st.push_back(-2);
		}
	}
	int cnt=0;
	
	while(!st.empty()){
		if(st.front()==-1)
			ta[cnt]='A';
		else
			ta[cnt]='N';
		cnt++;
		st.pop_front();
	}
//	reverse(ta,ta+cnt);
//	for(int i=0;i<strlen(ta);i++) cout<<ta[i];cout<<endl;
	int pos = KMP(b,ta);
//	cout<<pos<<endl;2(ab)
	for(int i=pos-strlen(ta)+1;i<=pos;i++) cout<<b[i];
	return 0;
}
/*
2(ab) => abab
2(av)2(ab)=>avavabab
*/

标签:塔子哥,int,text,back,st,编译,&&,KMP
From: https://www.cnblogs.com/pengge666/p/18209494

相关文章

  • vscode使用colcon build编译ros2工程时报错:The current CMakeCache.txt directory...i
    之前已经编译好了一个文件夹A下的工程然后复制出一个文件夹B,再次编译时出现了问题,报错ThecurrentCMakeCache.txtdirectory...isdifferentfrom...其实也能猜到就是当路径从A变到B,不匹配导致报错,但是不知道应该在哪里改CSDN上有个文章给出回答:删除build文件夹,当然把log和ins......
  • 编译安装pcre2-10.39 zlib-1.3.1 openssl-3.0.13
    #!/bin/bash#auth:chenjf#func:installnginxstandalone#version:v2.0#sys:CentOSLinuxrelease7.9.2009(Core)#installerversion:pcre2-10.39zlib-1.3.1openssl-3.0.13PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin##要用root安装[$......
  • Android JNI/NDK环境的配置与Demo编译
    一、背景​JNI(JavaNativeInterface)和NDK(NativeDevelopmentKit)在Android开发中扮演着重要的角色。JNI,即Java本地接口,是Java平台的一部分,它允许Java代码与其他语言写的代码进行交互。通过JNI,Java代码可以调用本地应用程序或库中的代码,也可以被本地代码调用。这主要使得......
  • 编译安装nginx 1.26.0、openssl 3.0.13 常见报错
    报错1[[email protected]]#./config--prefix=/usr/local/openssl--openssldir=/usr/local/opensslsharedCan'tlocateIPC/Cmd.pmin@INC(@INCcontains:/root/nginx-install/openssl-3.0.13/util/perl/usr/local/lib64/perl5/usr/lo......
  • Android11快速编译并替换framework.jar
    Android11快速编译并替换framework.jar在Android11之前修改了framework相关代码,只需makeframework就可以编译出framework.jar。在Android11,这个编译命令不起作用了,根据framework/base/目录下Android.bp中的提示:java_library{name:"framework-minus-apex",defaults:......
  • 使用interface化解一场因操作系统不同导致的编译问题
    场景描述起因:因项目需求,需要编写一个agent,需支持Linux和Windows操作系统。Agent里面有一个功能需要获取到服务器上所有已经被占用的端口。实现方式:针对不同的操作系统,实现方式有所不同linux:使用服务器自带的netstat指令,然后使用os/exec库来调用shell脚本实现wind......
  • LaTeX 交叉引用的三次编译
    源文件main.tex\documentclass{article}\begin{document}Hereisacitation\cite{example}.\bibliographystyle{plain}\bibliography{references}\end{document}references.bib@article{example,author={AuthorName},title={TitleofthePap......
  • 3562-Qt工程编译说明、GPU核心使用说明
     ......
  • RK3308 SDK 编译 --- ubuntu 22
    ./build.shbuildroot编译问题controller-enumtypes.c:6:1:error:stray'\'inprogram\#include"gstinterpolationcontrolsource.h"^controller-enumtypes.c:6:2:error:stray'#'inprogram\#include"gstinterpolationco......
  • kmp算法java
    KMP是三位大牛:D.E.Knuth、J.H.Morris和V.R.Pratt同时发现的。其中第一位就是《计算机程序设计艺术》的作者!!KMP算法要解决的问题就是在字符串(也叫主串)中的模式(pattern)定位问题。说简单点就是我们平时常说的关键字搜索。模式串就是关键字(接下来称它为P),如果它在一个主串(接下来......