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;
}
}
}
}
}