VEXOBEN
Vexoben
Feb 8, 2018
It takes 11 minutes to read this article.

题目链接:http://acm.sgu.ru/problem.php?contest=0&problem=189

题意

http://blog.csdn.net/qq_20118433/article/details/42618825

题解

一道比杀蚂蚁清真到不知道哪去的字符串模拟题。

一开始读入字符串的时候整行读入,然后扫一遍去掉空格、分号和换行符。

代码中最核心的是string Substring(string &sx,int l,int r)函数,它将sx字符串中substr函数的串值算出来。l、r分别是substr函数左右两个括号的位置。参数表中的逗号,变量名前的’$’是绝佳的标识符。将变量名分离出来之后根据逗号个数分类讨论即可。 用string编写的话,substr可以直接支持不含负数的情况。

几个细节

没有出现过的变量名值是“”(空串),赋值的时候小心在已有变量中找不到RE

字符串的值中允许有空格,在去空格的时候要判断一下是否在引号内

谨慎处理好第一行的换行符,你可能需要在第一行使用scanf或cin。scanf可以很好地处理这个问题。

未出现过的空串可以赋值给各种串,小心RE

好好读题目

代码

#include<bits/stdc++.h>
using namespace std;
const int N=1e4+10;

int n,m,tot;
struct String {
	string nam,text;
}s[N];

void Remove_Space(string &s) {        // 移除s中的空格、分号和换行符
	string sx="";
	int t=0;
	for (int i=0;i<s.length();i++) {
		if (s[i]==';') break;
		if (s[i]=='\"') t^=1;
		if (t||s[i]!=' ') sx+=s[i];
	}
	s=sx;
}

int Get_Num(string &s,int l,int r) {  // 读取出s[l,r]中的数字 
	int x=0,f=1;
	for (int i=l;i<=r;i++) {
		if (s[i]=='-') f=-1;
		else x=x*10+s[i]-'0';
	}
	return x*f;
}

int Get_Order(string &sx) {           // 在s[i]中查找名字为sx的字符串的下标
	for (int i=1;i<=tot;i++) {
		if (s[i].nam==sx) return i;
	}
	return 0;
}

string Substring(string &sx,int l,int r) { // 返回sx中substr函数对应的字符串,l、r分别为左右括号的下标 
	int a[4],cnt=0;
	for (int i=l;i<=r;i++) {
		if (sx[i]==',') a[++cnt]=i;
	}
	int l1=l+2,r1=a[1]-1,len1=r1-l1+1;
	string sy=sx.substr(l1,len1);
	int num=Get_Order(sy);
	if (cnt==1) {
		int beg=Get_Num(sx,a[1]+1,r-1);
		if (beg<0) beg=s[num].text.length()+beg;
		return s[num].text.substr(beg);
	}
	else if (cnt==2) {
		int beg=Get_Num(sx,a[1]+1,a[2]-1);
		if (beg<0) beg=s[num].text.length()+beg;
		int len=Get_Num(sx,a[2]+1,r-1);
		if (len<0) len=s[num].text.length()-beg+len;
		return s[num].text.substr(beg,len);
	}
}

void New_String(string &sx) { // 读入一个新字符串
	int a=sx.find('=');
	s[tot+1].nam=sx.substr(1,a-1);
	if (sx[a+1]=='$') {
		string ss=sx.substr(a+2,sx.length()-a-2);
		int num=Get_Order(ss);
		s[tot+1].text=s[num].text;
	}
	else if (sx[a+1]=='\"') {
		s[tot+1].text=sx.substr(a+2,sx.length()-a-3);
	}
	else if (sx[a+1]=='s') {
		s[tot+1].text=Substring(sx,a+7,sx.length()-1);
	}
	tot++;
}

string Equal(string &sx) { // 求出表达式对应的字符串值
	if (sx[0]=='$') {
		string ss=sx.substr(1,sx.length()-1);
		int num=Get_Order(ss);
		return s[num].text;
	}
	else if (sx[0]=='\"') {
		string ss="";
		for (int i=1;i<=sx.length()-2;i++)	ss+=sx[i];
		return ss;
	}
	else if (sx[0]=='s') {
		return Substring(sx,6,sx.length()-1);
	}
}

void Replace(string &sx,string &ss,int l,int r) { sx[l,r]中的内容替换成ss
	int a[4],cnt=0;
	for (int i=l;i<=r;i++) {
		if (sx[i]==',') a[++cnt]=i;
	}
	int l1=l+2,r1=a[1]-1,len1=r1-l1+1;
	string sy=sx.substr(l1,len1);
	int num=Get_Order(sy);
	if (cnt==1) {
		int beg=Get_Num(sx,a[1]+1,r-1);
		if (beg<0) beg=s[num].text.length()+beg;
		s[num].text.erase(beg);
		s[num].text=s[num].text.replace(beg,s[num].text.length()-beg,ss);
	}
	else if (cnt==2) {
		int beg=Get_Num(sx,a[1]+1,a[2]-1);
		if (beg<0) beg=s[num].text.length()+beg;
		int len=Get_Num(sx,a[2]+1,r-1);
		if (len<0) len=s[num].text.length()-beg+len;
		s[num].text=s[num].text.replace(beg,len,ss);
	}
}

int main() {
	scanf("%d%d\n",&n,&m); tot=0;
	s[0].text="";
	for (int i=1;i<=n+m;i++) {
		string sx; getline(cin,sx);
		Remove_Space(sx);
		if (sx[0]=='$') {
			int a=sx.find('=');
			string ss=sx.substr(1,a-1);
			int num=Get_Order(ss);
			if (num) {
				string sr=sx.substr(a+1,sx.length()-a-1);
				s[num].text=Equal(sr);
			}
			else New_String(sx);
		}
		
		else if (sx[0]=='p') {
			string sy=sx.substr(6,sx.length()-7);
			cout<<Equal(sy)<<endl;
		}
		else if (sx[0]=='s') {
			int a=sx.find('=');
			string ss=sx.substr(a+1,sx.length()-a-1);
			string sy=Equal(ss);
			Replace(sx,sy,6,a-1);
		}
	}
}

几组数据

调试的时候用到的几个数据(非常弱),把我的程序粘下来就知道输出了

0 5
$ad = "0123456789"; 
$bxx = "abcdefghigklmn"; 
$c =   $ad;
$xjj = substr($ad,2);
$pqq = substr($ad,2,4)

0 4
$a = "0123456789";
print("abs");
print(substr($a, -5)); 
print(substr($a, -2, -1));

0 4
$a = "0123456789";
$b = "abcdefghigklmn";
substr($b, 0, 1) = $a;
print(substr($b,0));

0 4
$a = "0123456789";
$b = "abcdefghigklmn";
substr($b, -3,-1) = "233";
print(substr($b,0));

0 7
$a = "123456"
$a = $c
print($a)
print($c)
$b = "adsfdfsa"
$a = substr($b,-3,-1)
print($a)

0 2
$ab = "45 6"
print($ab)