请编写程序检查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
?-]
参考代码:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct snode *stack;
struct snode{
char ch[100];
int top;
};
stack CreateStack(); //创建堆栈
void push(stack s,char cht); //入栈
void pop(stack s); //出栈
int IsEmpty(stack s); //判断堆栈是否为空,1非空,0空
int main()
{
char s[101]; //存储读入的每行字符串
char ans[100]; //存储需要配对的符号
int count=0; //需要配对的符号的个数
stack st=CreateStack();
while(1)
{
gets(s); //读入每行字符串
if(s[0]=='.'&&s[1]==0)//当读到某一行中只有一个句点.和一个回车的时候,输入结束
break;
int l=strlen(s);
for(int i=0;i<l;i++) //遍历每行字符串,将需要配对的符号保存在ans数组中
{
if(s[i]=='('||s[i]==')'||s[i]=='{'||s[i]=='}'||s[i]=='['||s[i]==']')
{
ans[count++]=s[i];
}
else if(s[i]=='/'&&s[i+1]=='*') //这里用a代表/*
{
ans[count++]='a';
i++;
}
else if(s[i]=='*'&&s[i+1]=='/') //这里用b代表*/
{
ans[count++]='b';
i++;
}
}
}
int flag=1;
for(int i=0;i<count;i++) //遍历ans数组
{
if(ans[i]=='('||ans[i]=='['||ans[i]=='{'||ans[i]=='a')
{
push(st,ans[i]);
}
else
{
if(IsEmpty(st)&&(ans[i]-st->ch[st->top]==1||ans[i]-st->ch[st->top]==2))
{
pop(st);
}
else
{
printf("NO\n");
if(IsEmpty(st)==0) //缺少左符号
{
printf("?-");
if(ans[i]=='b')
printf("*/\n");
else
printf("%c",ans[i]);
}
else //缺少右符号
{
if(st->ch[st->top]=='a')
printf("/*");
else
printf("%c",st->ch[st->top]);
printf("-?\n");
}
flag=0;
break;
}
}
}
if(flag)
{
if(IsEmpty(st)==0)
{
printf("YES");
}
else //缺少右符号
{
printf("NO\n");
if(st->ch[st->top]=='a')
printf("/*");
else
printf("%c",st->ch[st->top]);
printf("-?\n");
}
}
return 0;
}
stack CreateStack()
{
stack s;
s=(stack)malloc(sizeof(struct snode));
s->top=-1;
return s;
}
void push(stack s,char cht)
{
s->top++;
s->ch[s->top]=cht;
}
void pop(stack s)
{
s->top--;
}
int IsEmpty(stack s)
{
int flag=1;
if(s->top==-1)
{
flag=0;
}
return flag;
}
思路:
首先读入每行的字符串,提取出需要匹配的符号保存在ans数组中; 然后遍历ans数组中的符号。
如果是左符号,进栈;
如果是右符号,
-
若该符号与堆栈中栈顶符号相匹配(通过ASCLL码判别,如果右符号-左符号为1或者2,则匹配),匹配的符号出栈;
-
若堆栈为空,则将该符号输出(缺少左符号),跳出循环;
-
若该符号与栈顶符号不匹配,则将栈顶符号输出(缺少右符号),跳出循环。
处理完之后,如果栈为空,则完全匹配,输出YES;如果有剩余,则缺少右括号,输出栈顶符号。