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.每读入一个括号,若是右括号,则要看是否匹配。当栈不空时,如果匹配,则栈顶元素出栈,如果不匹配(即不合法),说明缺少右括号,输出左符号-?(因为如果是右括号,说明之前已经读入左括号,但是两个括号不匹配)。当栈为空时,说明缺少左括号,输出?-右括号。若是左括号,则压入栈中。
3.对于/*符号,可用“<”代替,读到/时记得先i++;
4.算法的开始于结束,栈都应该为空
//5.题目当中没有考虑输入为())这种情况,所以要在输出时加一些判断,实现自己看代码(这段我给注释掉了)。因为本题给的样例不需要考虑这个问题,所以你考虑可能就错了,但是知道有这么回事最好。
#include<cstdio>
#include<bits/stdc++.h>
#define STACK_INIT_SIZE 10000
#define STACKINCREMENT 10
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
//#define OVERFLOW -2
using namespace std;
typedef char SElemType,Status;
typedef struct
{
SElemType *base;
SElemType *top;
int stacksize;
} SqStack;
Status InitStack(SqStack &S)
{
S.base=(SElemType *)malloc(sizeof(SElemType)*STACK_INIT_SIZE);
if(!S.base)
exit(OVERFLOW);
S.top=S.base;
S.stacksize=STACK_INIT_SIZE;
return OK;
}
Status Push(SqStack &S,SElemType e)
{
if(S.top-S.base>=S.stacksize)
{
S.base=(SElemType*)malloc(sizeof(SElemType)*(S.stacksize+STACKINCREMENT));
if(!S.base)
exit(OVERFLOW);
S.top=S.base+S.stacksize;
S.stacksize+=STACKINCREMENT;
}
*S.top++=e;
return OK;
}
Status Pop(SqStack &S)
{
if(S.top==S.base)
return ERROR;
S.top--;
return OK;
}
Status GetTop(SqStack &S,SElemType &e)
{
if(S.base==S.top)
return ERROR;
e=*(S.top-1);
return OK;
}
void judge(char ch)//统一处理缺少右符号的情况
{
if(ch == '(')
cout<<"(-?"<<endl;
else if(ch == '[')
cout<<"[-?"<<endl;
else if(ch == '{')
cout<<"{-?"<<endl;
else if(ch == '<')//用<代替/*
cout<<"/*-?"<<endl;
}
char s[1005];
int main()
{
SqStack S;
InitStack(S);
int flag = 1,i;
while(cin>>s)
{
if(s[0]=='.')
break;
int len = strlen(s);
for(int i = 0; i<len; i++)
{
if(s[i]=='('||s[i]=='['||s[i]=='{')
Push(S,s[i]);
else if(s[i]=='/'&&s[i+1]=='*'&&i+1<len)
{
++i;
Push(S,'<');
}
else if(s[i]==')')
{
if(S.top!=S.base)//如果栈不空
{
SElemType e;
GetTop(S,e);
if(e == '(')//说明匹配,则出栈
Pop(S);
else if(flag)//如果匹配的东西不合法时
{
cout<<"NO"<<endl;
flag = 0;
judge(e);//缺e这个右括号
//break;
}
}
else if(flag)//栈空,不合法,缺(
{
cout<<"NO"<<endl;
flag = 0;
cout<<"?-)"<<endl;
}
}
else if(s[i]==']')
{
if(S.top!=S.base)
{
SElemType e;
GetTop(S,e);
if(e == '[')
Pop(S);
else if(flag)
{
cout<<"NO"<<endl;
flag = 0;
judge(e);
}
}
else if(flag)//栈空,不合法,缺[
{
cout<<"NO"<<endl;
flag = 0;
cout<<"?-]"<<endl;
}
}
else if(s[i]=='}')//都同理
{
if(S.top!=S.base)
{
SElemType e;
GetTop(S,e);
if(e=='{')
Pop(S);
else if(flag)
{
cout<<"NO"<<endl;
flag=0;
judge(e);
}
}
else if(flag)//栈空,不合法,缺{
{
cout<<"NO"<<endl;
flag = 0;
cout<<"?-}"<<endl;
}
}
else if(s[i]=='*'&&s[i+1]=='/'&&i+1<len)
{
++i;//跳过*
if(S.top!=S.base)
{
SElemType e;
GetTop(S,e);
if(e=='<')
Pop(S);
else if(flag)
{
cout<<"NO"<<endl;
flag=0;
judge(e);
}
}
else if(flag)//栈空,不合法,缺/*
{
cout<<"NO"<<endl;
flag=0;
cout<<"?-*/"<<endl;
}
}
}
}
if(flag)
{
if(S.base == S.top)//最后如果栈空说明都匹配
cout<<"YES"<<endl;
//else if(s[i])//排除())这种情况
//{
//cout<<"No"<<endl;
//}
else//否则不匹配
{
SElemType e;
GetTop(S,e);
cout<<"NO"<<endl;
judge(e);
}
}
}