1. 程式人生 > >第三章棧作業題2-棧及其應用-計算機17級 7-2 符號配對 (20 分)

第三章棧作業題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);
        }
    }
}