数据结构/PTA-符号配对/栈

请编写程序检查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

 

分析:

首先就是把串全部读进来,合成一个大串,只保留包含符号即可

读串时考虑使用函数getline,因为getline默认回车符停止读入,按Ctrl+Z或键入EOF回车即可退出循环,方便书写。

 

然后再对新生成的串处理:

如果读入的是左括号,直接压入栈顶。

如果读入的是右括号:

1.如果栈为空,那么缺少与之对应的左括号。

2.如果栈顶元素与之不匹配,那么缺少与栈顶元素相匹配的右括号。

   对于不匹配的判断:根据ASCII表,串中元素-栈顶元素!=1且!=2

 

 

3.处理完之后,如果栈为空,则表示完全匹配,如果有剩余,那么就是缺少右括号。因为是输出第一个缺少的,所以直接输出栈尾的元素就可以。

      判断情况可提前设立一个flag

参考https://www.cnblogs.com/sykline/p/9748825.html      https://www.cnblogs.com/ymd12103410/p/9514896.html


 

代码

#include<bits/stdc++.h>
using namespace std;
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
typedef char SElemType ;
typedef struct
{
    SElemType *base;
    SElemType *top;
    int stacksize;
} STACK;
int  Pop(STACK &S)         //出栈
{
    if(S.top==S.base)
        return 0;
    *S.top,S.top--;
    return 1;
}
int Push(STACK &S,char e)  //入栈
{
    if(S.top-S.base>=S.stacksize)
    {
        S.base = (SElemType*)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(SElemType));;

        if(!S.base)
        {
            return -1;
        }
        S.top=S.base+S.stacksize;
        S.stacksize+=STACKINCREMENT;
    }
    *S.top++=e;
    return 1;
}
int StackEmpty(STACK& S)   //判断是否栈空
{
    if(S.base == S.top)
        return 1;
    return -1;
}
int Gettop(STACK S,SElemType &e)  //返回栈顶元素
{
    if(S.top==S.base)
        return 0;
    e= *(S.top-1);
    return 1;
}
int InitStack(STACK &S)      //建立空栈
{
    S.base=(char *)malloc(STACK_INIT_SIZE*sizeof(char));
    if(!S.base)
        exit(-1);
    S.top=S.base;
    S.stacksize=STACK_INIT_SIZE;
    return 1;
}

int main()
{
    string x,y="";
    int flag=1;
    while(getline(cin,x))               //输入字符串
    {
        int i=0;

        if(x==".")
            break;
        for(; i<x.size(); i++)
        {
            if(x[i]=='['||x[i]==']'||x[i]=='{'||x[i]=='}'||x[i]=='('||x[i]==')')
                y+=x[i];
            else if(x[i]=='/'&&x[i+1]=='*')
            {
                y+="<";
                i++;
            }
            else if(x[i]=='*'&&x[i+1]=='/')   //注意:将*/视为>
            {
                y+=">";
                i++;
            }
        }
    }
    STACK S;
    InitStack(S);

    int i=0;
    for(; i<y.size(); i++)
    {
        char a;
        Gettop(S,a);
        if(y[i]=='['||y[i]=='{'||y[i]=='('||y[i]=='<') //以左包含的符号起始,入栈
        {
            Push(S,y[i]);
            continue;
        }
        else if(StackEmpty(S)==1)                      //以右包含的符号起始,直接报错
        {

            printf("NO\n");
            if(y[i]=='>')
                printf("?-*/\n");
            else
                printf("?-%c\n",y[i]);
            flag=0;
            break;
        }
        else if(y[i]-a!=1&&y[i]-a!=2)
        {

            printf("NO\n");
            if(a=='<')
                printf("/*-?\n");
            else
                printf("%c-?\n",a);
            Pop(S);
            flag=0;
            i--;
            break;
        }
        else
            Pop(S);

    }
    if(flag==1)
    {
        if(StackEmpty(S)==1)
            printf("YES\n");
        else
        {
            char a;
            Gettop(S,a);
            printf("NO\n");
            if(a=='<')
                printf("/*-?\n");
            else
                printf("%c-?\n",a);
        }
    }
}

 

posted @ 2020-09-29 19:47  EleclouD  阅读(1047)  评论(0编辑  收藏  举报