第三章栈作业题2-栈及其应用-计算机17级 7-2 符号配对 (20 分)

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

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值