浙大版《数据结构(第2版)》题目集-习题3.8 符号配对 (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
?-]

参考代码:

#include
#include
#include

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数组中的符号。
如果是左符号,进栈;
如果是右符号,

  1. 若该符号与堆栈中栈顶符号相匹配(通过ASCLL码判别,如果右符号-左符号为1或者2,则匹配),匹配的符号出栈;

  2. 若堆栈为空,则将该符号输出(缺少左符号),跳出循环;

  3. 若该符号与栈顶符号不匹配,则将栈顶符号输出(缺少右符号),跳出循环。

处理完之后,如果栈为空,则完全匹配,输出YES;如果有剩余,则缺少右括号,输出栈顶符号。

你可能感兴趣的:(浙大版《数据结构(第2版)》题目集-习题3.8 符号配对 (20分))