假设一个算术表达式中包含圆括号、方括号和花括号3种类型的括号,编写一个算法来判别,表达式中的括号是否配对,以字符“\0“作为算术表达式的结束符

发布于:2025-09-10 ⋅ 阅读:(23) ⋅ 点赞:(0)

思想:这道题是栈的应用类型,我们可以建立一个栈来保存'(','[','{',通过遍历字符串如果是三个左括号其中一个则入栈,当遇到')'']''}'则出栈配对,如果左右匹配,则遍历下一个元素,如果不匹配直接返回,如果遍历字符串结束,但栈中还有元素,则是左符号单身,如果已经空栈,但是又遍历到一个右括号,则是右括号单身

具体代码:

#include<stdio.h>
#include<stdbool.h>
#include<stdlib.h>
typedef struct LinkStack
{
    char data;
    struct LinkStack* next;
}LinkStack;
void InitStack(LinkStack** S)//初始化栈(不带头结点链表实现)
{
    (*S) = NULL;
    return;
}
bool Push(LinkStack** S,char ch)//入栈
{
    if (ch == '(' || ch == '[' || ch == '{')
    {
        LinkStack* p = (LinkStack*)malloc(sizeof(LinkStack));
        if (p == NULL)
            return false;
        //第一次入栈
        if ((*S) == NULL)
        {
            p->data = ch;
            p->next = NULL;
            (*S) = p;
        }
        //后续入栈
        else
        {
            p->data = ch;
            p->next = (*S);
            (*S) = p;
        }
    }
    return true;

}
bool Pop(LinkStack** S)//出栈并且带回元素
{
    if ((*S) == NULL)//空栈无法出栈
        return false;
    LinkStack* p = (*S);
    //*x = p->data;
    (*S) = p->next;
    free(p);
    return true;
}
LinkStack* GetTop(LinkStack* S)//返回栈顶指针
{
    if (S == NULL)//空栈
        return NULL;
    LinkStack* p = S;
    return p;
}
bool EmptyStack(LinkStack* S)//判断空栈
{
    if (S == NULL)
        return true;
    return false;
}
void JudgeStack(LinkStack **S,char arr[])//判断
{
    char* a = arr;
    while (*a != '\0')
    {
        if (*a == '(' || *a == '[' || *a == '{')//如果当时是三个括号其中一个则入栈
            Push(S, *a);
        else if (EmptyStack(*S) == false && *a == ')' && GetTop((*S))->data == '(')//如果是'('则出栈
            Pop(S);
        else if (EmptyStack(*S) == false && *a == ')' && GetTop((*S))->data != '(')//如果不是则直接退出
        {
            printf("配对失败\n");
            printf("%c %c\n",*a, GetTop((*S))->data);
            return;
        }
        else if (EmptyStack(*S) == false && *a == ']' && GetTop((*S))->data == '[')//如果是'['则出栈
            Pop(S);
        else if (EmptyStack(*S) == false && *a == ']' && GetTop((*S))->data != '[')
        {
            printf("配对失败\n");
            printf("%c %c\n", *a, GetTop((*S))->data);
            return;
        }
        else if (EmptyStack(*S) == false && *a == '}' && GetTop((*S))->data == '{')//如果是'{'则出栈
            Pop(S);
        else if (EmptyStack(*S) == false && *a == '}' && GetTop((*S))->data != '{')
        {
            printf("配对失败\n");
            printf("%c %c\n", *a, GetTop((*S))->data);
            return;
        }
        else if (EmptyStack(*S) == true && (*a == ')' || *a == ']' || *a == '}'))//如果栈为空,且字符串中还有元素
            printf("右括号单身\n");
        a++;//向后遍历字符串

    }
    if (EmptyStack(*S) == false)//如果字符串已遍历结束但栈里还有元素
        printf("左括号单身\n");
    else
        printf("配对成功\n");
    return;
}
int main()
{
    char arr[] = "[(3 + 2) * 5 + 3](]()";
    LinkStack* S;//指向栈的指针
    InitStack(&S);//初始化栈
    JudgeStack(&S , arr);
    return 0;
}

注:此代码中运用了大量的if-else语句,不是很美观(其实懒得改了),大家如果要引用可以自行优化代码


网站公告

今日签到

点亮在社区的每一天
去签到