【PTA数据结构 | C语言版】符号配对

本专栏持续输出数据结构题目集,欢迎订阅。

文章目录

题目

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

代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.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

typedef char SElemType;
typedef int Status;

typedef struct {
    SElemType *base;
    SElemType *top;
    int stacksize;
} Stack;

Status InitStack(Stack *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(Stack *S, SElemType e) {
    if (S->top - S->base >= S->stacksize) {
        SElemType *newBase = (SElemType *)realloc(S->base, sizeof(SElemType) * (S->stacksize + STACKINCREMENT));
        if (!newBase)
            exit(OVERFLOW);
        S->base = newBase;
        S->top = S->base + S->stacksize;
        S->stacksize += STACKINCREMENT;
    }
    *S->top++ = e;
    return OK;
}

Status Pop(Stack *S) {
    if (S->top == S->base)
        return ERROR;
    S->top--;
    return OK;
}

Status GetTop(Stack *S, SElemType *e) {
    if (S->base == S->top)
        return ERROR;
    *e = *(S->top - 1);
    return OK;
}

const int maxn = 1000 + 5;
char s[maxn];

bool Find(Stack *S, char ch) {
    char tmp[maxn];
    memset(tmp, '\0', sizeof(tmp));
    int num = 0;
    Stack tempStack = *S;  // 复制栈状态用于查找
    
    while (tempStack.top != tempStack.base) {
        SElemType e2;
        if (GetTop(&tempStack, &e2) == ERROR)
            break;
        if (e2 == ch) {
            // 找到匹配字符,更新原栈
            while (num > 0) {
                Push(S, tmp[--num]);
            }
            Pop(S);  // 弹出匹配的字符
            return true;
        } else {
            tmp[num++] = e2;
            Pop(&tempStack);
        }
    }
    
    // 未找到匹配字符,恢复原栈
    while (num > 0) {
        Push(S, tmp[--num]);
    }
    return false;
}

void judge(char ch) {
    if (ch == '(')
        printf("(-?\n");
    else if (ch == '[')
        printf("[-?\n");
    else if (ch == '{')
        printf("{-?\n");
    else if (ch == '<')
        printf("/*-?\n");
}

int main() {
    Stack Sta;
    InitStack(&Sta);
    int flag = 1;
    
    while (fgets(s, maxn, stdin) != NULL) {
        // 移除换行符
        size_t len = strlen(s);
        if (len > 0 && s[len-1] == '\n')
            s[len-1] = '\0';
            
        if (s[0] == '.') break;
        
        for (int i = 0; i < strlen(s); i++) {
            if (s[i] == '(' || s[i] == '[' || s[i] == '{')
                Push(&Sta, s[i]);
            else if (s[i] == '/' && s[i+1] == '*' && i+1 < strlen(s)) {
                i++;
                Push(&Sta, '<');
            } else if (s[i] == ')') {
                if (Sta.top != Sta.base) {
                    SElemType e;
                    GetTop(&Sta, &e);
                    if (e == '(')
                        Pop(&Sta);
                    else if (flag) {
                        printf("NO\n");
                        flag = 0;
                        judge(e);
                    }
                } else if (flag) {
                    flag = 0;
                    printf("NO\n");
                    printf("?-)\n");
                }
            } else if (s[i] == ']') {
                if (Sta.top != Sta.base) {
                    SElemType e;
                    GetTop(&Sta, &e);
                    if (e == '[')
                        Pop(&Sta);
                    else if (flag) {
                        printf("NO\n");
                        flag = 0;
                        judge(e);
                    }
                } else if (flag) {
                    flag = 0;
                    printf("NO\n");
                    printf("?-]\n");
                }
            } else if (s[i] == '}') {
                if (Sta.top != Sta.base) {
                    SElemType e;
                    GetTop(&Sta, &e);
                    if (e == '{')
                        Pop(&Sta);
                    else if (flag) {
                        printf("NO\n");
                        flag = 0;
                        judge(e);
                    }
                } else if (flag) {
                    flag = 0;
                    printf("NO\n");
                    printf("?-}\n");
                }
            } else if (s[i] == '*' && s[i+1] == '/' && i+1 < strlen(s)) {
                i++;
                if (Sta.top != Sta.base) {
                    SElemType e;
                    GetTop(&Sta, &e);
                    if (e == '<')
                        Pop(&Sta);
                    else if (flag) {
                        printf("NO\n");
                        flag = 0;
                        judge(e);
                    }
                } else if (flag) {
                    flag = 0;
                    printf("NO\n");
                    printf("?-*/\n");
                }
            }
        }
    }
    
    if (flag) {
        if (Sta.base == Sta.top)
            printf("YES\n");
        else {
            SElemType e;
            GetTop(&Sta, &e);
            printf("NO\n");
            judge(e);
        }
    }
   
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

秋说

感谢打赏

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值