微软编辑器的代码高亮(伤脑的模拟)

微软的一款代码编辑器 VS Code 需要在编辑代码时将代码高亮。其中,有一个子问题是判断一串文本是否是 一个合法字符串。一个合法字符串是指由一对单引号或一对双引号包裹的文本字符集,字符集包括所有英文小写字母、单引号、双引号和斜杠(\)。

比如"abc"、'ab"c’都是一个合法的字符串,而"abc"de"、‘ab’'c’和abc都不是一个合法的字符串。

字符串中可能有转义字符,转义字符只有 33 种:"、’ 和 \,分别表示:字符串中的双引号、单引号和斜杠。

当字符串由 双引号 包裹时,字符串中的 双引号 必须以转义字符出现,否则会被认为是不合法字符串;

当字符串由 单引号 包裹时,字符串的 单引号 必须以转义字符出现,否则会被认为是不合法字符串;

字符串中的斜杠(\)必须以转义字符出现,否则会被认为是不合法字符串。

输入格式

只有一行,表示输入的文本,文本的长度 lenlen 满足 1 \leq len \leq 100001≤len≤10000。保证输入只包含英文小写字母、单引号、双引号和斜杠(\)。

输出格式

如果输入的一串文本是一个合法的字符串,则输出Yes,否则输出No。

样例输入1
“abc”
样例输出1
Yes
样例输入2
“abc”“def”
样例输出2
No
样例输入3
“ab\c”
样例输出3
No
这道题相当的坑,考虑的比较多,首先你需要知道如何判断第一个字符是不是左单引号,判断方法是 if(a=='\'') 其中 \''的转义字符,本质上是相同的,还有就是\的转义字符为\\,其次要考虑一种情况是这个样例:"ab\\"a",普通的判断的话吗,这个样例很难过,我的解决方法是把已经配对过的字符给改变了,标记的话应该也可以,还需要注意是在双引号的包裹下,还是在单引号的包裹下,这两种需要考虑的情况是不一样的,比如在双引号下可以有单引号,在单引号包裹下可以有双引号,我当时写的时候没过的样例有:'\' ,"ab\\"a","\"","","好了接下来就上代码吧:

#include<stdio.h>
#include<string.h>
int main()
{
	int i,j,flag,len,flag1,f1,f2;
	char str[20000];
	while(~scanf("%s",str))
	{
		flag=flag1=f1=f2=0;
		len=strlen(str);
		if(len<2)
			printf("No\n");
		else if(str[0]=='"'&&str[len-1]=='"'||str[0]=='\''&&str[len-1]=='\'')
		{
			if(str[0]=='"')
				f1=1;//表示的是在双引号的包裹下
			if(str[0]=='\'')
				f2=1;//表示的是在单引号的包裹下
			flag=1;
		}
		if(flag==0&&len>=2)//首尾对不上的情况下则直接输出
			printf("No\n");
		if(len==2&&flag==1)
			printf("Yes\n");
		if(flag==1&&len>2)
		{
			for(i=1;i<len-1;i++)//注意我这里是直接从中间开始的跳过了首尾字符
			{
				if(str[i]=='#')
					continue;
				if(f1==1)//在双引号包裹的情况
				{
					/*如果中间出现了双引号,并且其前一
					个字符不为\,就表示这个双引号不是以转义字符出现*/
					if(str[i]=='"'&&str[i-1]!='\\')
						flag1=1;
					if(str[i]=='"'&&str[i-1]=='\\')//把已配对的转义字符给换成其他的字符    
					{
						str[i]='#';
						str[i-1]='#';
					}                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
				}
				if(f2==1)
				{
					if(str[i]=='\''&&str[i-1]!='\\')
						flag1=1;
					if(str[i]=='\''&&str[i-1]=='\\')
					{
						str[i]='#';
						str[i-1]='#';
					}
				}
				if(str[i]=='\\')//如果这个字符是\
				{
					if(str[i+1]!='\''&&str[i+1]!='"'&&str[i+1]!='\\')//就需要知道它的下一个字符是否能跟它构成转义字符
						flag1=1;
					if(str[i+1]=='\''||str[i+1]=='"'||str[i+1]=='\\')
					{
						if(i+1==len-1)
							flag1=1;//这里就是为了过'\'这个样例
						str[i]='#';
						if((i+1)!=len-1)
						str[i+1]='#';
					}
				}
			}
			if(flag1==0)
				printf("Yes\n");
			else
				printf("No\n");
		}
	}
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/weixin_44313771/article/details/105012733
今日推荐