7-2 符号配对

7-2 符号配对 (20 分)
请编写程序检查C语言源程序中下列符号是否配对://、(与)、[与]、{与}。

输入格式:
输入为一个C语言源程序。当读到某一行中只有一个句点.和一个回车的时候,标志着输入结束。程序中需要检查配对的符号不超过100个。

输出格式:
首先,如果所有符号配对正确,则在第一行中输出YES,否则输出NO。然后在第二行中指出第一个不配对的符号:如果缺少左符号,则输出?-右符号;如果缺少右符号,则输出左符号-?。

输入样例1:
void test()
{
int i, A[10];
for (i=0; i<10; i++) /*/
A[i] = i;
}
.

输出样例1:
NO
/*-?
输入样例2:
void test()
{
int i, A[10];
for (i=0; i<10; i++) /**/
A[i] = i;
}]
.

输出样例2:
NO
?-]
输入样例3:
void test()
{
int i
double A[10];
for (i=0; i<10; i++) /**/
A[i] = 0.1*i;
}
.

输出样例3:
YES

思路

这个题一看到的时候我想用双端队列,那个时候我没考虑全面,如果说这个错误符号在最后面,那么更难了。基本思路就是遇到前符号就入栈,遇到后符号就查看栈顶是不是相同,如果栈顶不相同,那么这个符号和栈顶符号有一个是错的。这时候接着判断栈顶下面那个符号,如果这个符号和当前符号相同,那么就是栈顶错了。
下面直接上代码,其中踩坑的地方在于
1.一开始就没有把所有情况想到,以至于我没有判空,导致第二个例子就过不去。
2.程序编写过程中,的那个/*,我判断的时候应该是两个,这个没错,我想要在其中if语句上面多一个i++,来防止之后不会重新判断 星号(不知道为什么csdn这里打星号是斜体),但是我后面又用了个if语句,还是判断的与之前的i有关的数,这导致后面直接就全错了,所以这个下次要注意if else语句的使用,如果想加快 i 的遍历,那么改变了 i 之后,后面最好就不要有与之前 i 相关的东西了。
3.最后还有一点就是,pta好像是只判断你的输出是什么,我是直接找出错误符号就停止程序了,以至于后面的点都输入不进去。但是也给过了。
这个代码还需要优化。不能那么多中断main。。。

#include<cstdio>

#include<string>
#include<stdlib.h>
#define initsize 50
#define changesize 10
using namespace std;
struct stack{
	char *base;
	char *top;
	int stacksize;
}; 
stack fuhao;
char index[8]={'(','[','{','<','>','}',']',')'};

void push(char a){
	if((fuhao.top-fuhao.base)>=fuhao.stacksize){
		fuhao.base=(char *)realloc(fuhao.base,sizeof(char)*(fuhao.stacksize+changesize));
		fuhao.top=fuhao.base+fuhao.stacksize;
		fuhao.stacksize+=changesize;
	}
	*fuhao.top++=a;
}
char pop(){
	return *(--fuhao.top);
}
bool isempty(stack a){
	if(a.base==a.top){
		return true;
	}
	else return false;
}
char gettop(){
	return *(fuhao.top-1);
}
//int getindex(char a){
//	for(int i=0;i<8;i++){
//		if(strcmp(index[i],a)==0)
//		return i;
//	}
//}
int main(){
	char str[1000];
	while(1){
		scanf("%s",str);
	if(str[0]=='.'&&isempty(fuhao)){
		printf("YES\n");
		return 0;
	}
	

	for(int i=0;str[i];i++){
		if(str[i]=='('||str[i]=='{'||str[i]=='['){
			push(str[i]);
		}
		else if(str[i]=='/'&&str[i+1]=='*'){
			push('<');
		
			i++;
		}
		else if(str[i]==')'){
			if(isempty(fuhao)){
				printf("NO\n");
				printf("?-%c",str[i]);
				return 0;
			}
			else if(gettop()=='('){
				pop();
			}
			else if(*(fuhao.top-2)=='('){
				printf("NO\n");
				if(*(fuhao.top-1)=='<'){
					printf("/*-?");
					return 0;
				}
				else {
					printf("%c-?",*(fuhao.top-1));
				return 0;
				}
				
			}
			else {
				printf("NO\n");
				printf("?-%c",str[i]);
				return 0;
			}
		}
		else if(str[i]==']'){
			if(isempty(fuhao)){
				printf("NO\n");
				printf("?-%c",str[i]);
				return 0;
			}
			else if(gettop()=='['){
				pop();
			}
			else if(*(fuhao.top-2)=='['){
				printf("NO\n");
					if(*(fuhao.top-1)=='<'){
					printf("/*-?");
					return 0;
				}
				else {
					printf("%c-?",*(fuhao.top-1));
				return 0;
				}
			}
			else {
				printf("NO\n");
				printf("?-%c",str[i]);
				return 0;
			}
		}
		else if(str[i]=='}'){
			if(isempty(fuhao)){
				printf("NO\n");
				printf("?-%c",str[i]);
				return 0;
			}
			else if(*(fuhao.top-1)=='{'){
				pop();
			}
			else if(*(fuhao.top-2)=='{'){
				printf("NO\n");
					if(*(fuhao.top-1)=='<'){
					printf("/*-?");
					return 0;
				}
				else {
				printf("%c-?",*(fuhao.top-1));
				return 0;
				}
			}
			else {
				printf("NO\n");
				printf("?-%c",str[i]);
				return 0;
			}
		}
		else if(str[i]=='*'&&str[i+1]=='/'){
			if(isempty(fuhao)){
				printf("NO\n");
				printf("?-*\\");
				return 0;
			}
			else if(gettop()=='<'){
				pop();
			}
			else if(*(fuhao.top-2)=='<'){
				printf("NO\n");
					if(*(fuhao.top-1)=='<'){
					printf("/*-?");
					return 0;
				}
				else {
					printf("%c-?",*(fuhao.top-1));
				return 0;
				}
			}
			else {
				printf("NO\n");
				printf("?-*\\");
				return 0;
			}
		}
		
			
	}
	}
	
}

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值