【PTA】7-1 符号配对

题目

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

#define MAX_SIZE 100

char stack[MAX_SIZE];  // 用于存储括号的栈
int top = -1;          // 栈顶指针

// 入栈操作
void push(char c) {
    if (top < MAX_SIZE - 1) {
        stack[++top] = c;
    }
}

// 出栈操作
char pop() {
    if (top >= 0) {
        return stack[top--];
    }
    return '\0';  // 返回空字符表示栈为空
}

// 判断栈是否为空
int isEmpty() {
    return top == -1;
}

// 获取栈顶元素
char getTop() {
    if (top >= 0) {
        return stack[top];
    }
    return '\0';  // 返回空字符表示栈为空
}

int main() {
    char x[101], y[101] = ""; //x数组存放输入数据,y数组存放符号
    int flag = 1;

    // 读取输入直到遇到句点.
    while (fgets(x, 101, stdin)) {
        int i = 0;
        if (strcmp(x, ".\n") == 0)
            break;
        for (; x[i] != '\0'; i++) {
            if (x[i] == '[' || x[i] == ']' || x[i] == '{' || x[i] == '}' || x[i] == '(' || x[i] == ')') {
                strncat(y, &x[i], 1);  // 将括号加入符号序列 y
               // 单独处理 /* 和 */,用 < 和 > 表示 
            } else if (x[i] == '/' && x[i + 1] == '*') {
                strcat(y, "<");
                i++;
            } else if (x[i] == '*' && x[i + 1] == '/') {
                strcat(y, ">");
                i++;
            }
        }
    }

    int i = 0;
    // 循环遍历符号序列 y
    for (; y[i] != '\0'; i++) {
        char a = getTop();

        if (y[i] == '[' || y[i] == '{' || y[i] == '(' || y[i] == '<') {  // 左括号符号入栈
            push(y[i]);
            continue;
            // 遇到右括号,有两种不匹配的情况:栈为空(没有可匹配的左括号)或者和栈顶元素不匹配(不符合匹配规则)
        } else if (isEmpty()) {   //没有可匹配的左括号,只有这种情况是?在左边,表示缺少左符号
            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) {  // 匹配规则是左括号和右括号的 ASCII 码差值为 1 或 2
            printf("NO\n");
            if (a == '<')
                printf("/*-?\n");
            else
                printf("%c-?\n", a);
            pop();
            flag = 0;
            break;
        } else {  // 匹配,出栈
            pop();
        }
    }
	//如果flag==0,则右符号都有左符号与之匹配,但还有考虑可能还有未匹配的左括号
    if (flag == 1) {
        if (isEmpty()) {
            printf("YES\n");
        } else {
            char a = getTop();
            printf("NO\n");
            if (a == '<')
                printf("/*-?\n");
            else
                printf("%c-?\n", a);
        }
    }

    return 0;
}

ASCII Table

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值