Stack and Queue of Data Structure Exercises: Bracket Matching Problem (C language implementation)

     This is just one of the example questions. After reading my analysis of this question, you will definitely be able to grasp the problem of bracket matching. Please indicate the link of this article when reprinting!

content

1. Problem description

2. Problem Analysis 

3. Code Implementation

(1), define the structure

(2), initialize the stack

(3), push stack function

(4), determine whether the stack is empty

(5), pop-up function

(6), get the top element of the stack

(7), the main function

(8) Operation results

 4. Complete code


1. Problem description

Description

 Given a string of characters, no more than 50 characters, which may include brackets, numbers, letters, punctuation, spaces, your task is to check whether ( ) , [ ], { } in this string of characters match.

Input

 There are multiple sets of input data, which are processed until the end of the file.

Output

 Output "yes" if it matches, output "no" if it doesn't

Sample

Input

sin(20+10)
{[}]

Output

yes
no

2. Problem Analysis 

       This is a question that took me three days to solve. It can only be said that I am too stupid and think too complicated a simple problem. Then let's analyze what we need to do in the bracket matching problem and what we need to pay attention to.

(1) First of all, to see the problem of bracket matching, we need a stack, which is used to store the left brackets '(', '{', '[' in arithmetic expressions.

(2) When storing the left bracket, we need to judge whether the stack is full. As long as the stack is not full, we can push it directly into the stack.

(3) When we encounter the closing bracket, we need to see if there are elements in the current stack. If the stack is empty, then we don't have to judge and end the program directly. The brackets do not match; if the stack is empty If there is an element, then we take out the top element of the stack and match it with the closing parenthesis we currently encounter. If they are a pair, then we pop the opening parenthesis in the current stack, continue to scan the arithmetic expression, and loop Execute steps (2) and (3); if it is not a pair, then we don't have to continue, and end the program directly, the parentheses do not match.

(4), we need to know that the parentheses appear in pairs, there are left parentheses but no right parentheses, and there are right parentheses but no left parentheses. This is not acceptable. It should be noted that when we judge whether the parentheses match, we cannot use the equality of the parenthesis at the top of the stack and the current closing parenthesis as a judgment condition. Because the left and right parentheses are definitely not equal. We can only judge which kind of parenthesis the current right parenthesis is, and then we manually define its corresponding left parenthesis, and use the left parenthesis we defined and the stack top parenthesis to judge whether they are equal.

(5) For this question, we only stop scanning when we encounter '\0'. The reason is '\0', because after the array is stored, the system will automatically add '\0 to the end. ' is used to mark the end of the array storage here. Otherwise keep scanning for parentheses in arithmetic expressions.

(6) After scanning the arithmetic expression, we need to check whether there are still elements in the current stack. If there are no elements, the parentheses match. If there are still elements in the stack, it means they do not match. Because we execute the pop operation when we encounter matching brackets, if all of them match, the elements in the final stack should be all stacked.

3. Code Implementation

(1), define the structure

       According to our understanding of the stack, we need to define a structure first, which has an array for storing elements and a stack top marker bit top. Because the stack is LIFO. We only need a stack top marker bit to perform operations such as pushing and popping the stack into the stack. If you are not familiar enough with the stack, please read the knowledge about the stack first and then read on.

#include <stdio.h>
#include <stdlib.h>
#define Maxsize 100   //数组大小
typedef struct ST
{
    char data[Maxsize]; //存储栈中的元素
    int  top;           //栈顶标记位
}Stack;                 //用Stack来表示这个结构体

(2), initialize the stack

       Because the subscript of the array starts from 0, we didn't store the element at the beginning, so we can let top==-1. When storing an element, let top+1, and then store the element at the position it marks.

void Init(Stack *L)
{
    L->top=-1;
}

(3), push stack function

void Push(Stack *L,char x)
{
    if(L->top>=Maxsize)     //当我们栈满的时候就不能存储元素了
    {
        return;
    }
    L->top++;               //让top先加一
    L->data[L->top]=x;       //在top标记的位置存储当前的元素x
}

(4), determine whether the stack is empty

int Empty(Stack L)
{
    if(L.top==-1)
    {
        return 1;//为空返回1
    }
    return 0;    //不为空返回0
}

(5), pop-up function

        When popping the stack, you only need to judge whether the stack is empty. If it is not empty, then let the top of the stack mark the bit top-1.

void Pop(Stack *L)
{
    if(L->top==-1)
    {
        return;
    }
    L->top--;
}

(6), get the top element of the stack

       When we encounter the closing bracket, we need to get the element at the top of the stack to determine whether the element at the top of the stack matches the current closing bracket.

char Get(Stack L)
{
    return L.data[L.top];
}

(7), the main function

         The functions we defined above are very simple, mainly to see how we call the above functions in the main function, and under what circumstances can we use the above functions.

int main()
{
    Stack L;                                       //定义一个栈
    char s[100];                                   //定义一个字符数组用来存储我们输入的算术表达式
    while(gets(s))                                  //用来获得我们输入的各个字符,包括空格
    {
        Init(&L);                                  //我们先初始化栈L
        int flag=1;                                //这个变量用来标记括号是否匹配成功
        for(int i=0;s[i]!='\0';i++)                //循环遍历我们输入的算术表达式中的括号
        {          
            if(s[i]=='('||s[i]=='['||s[i]=='{')    //如果是左括号我们就看能不能让它入栈
            {
                if(L.top<Maxsize)                  //栈没满我们就让左括号进栈,调用Push函数
                {
                    char x=s[i];
                    //进栈
                    Push(&L,x);
                }

            }
            else if(s[i]==')')                      //如果栈是这个右括号,就判断栈是否为空
            {
                if(Empty(L))                        //栈为空,我们就标记flag=0,结束循环,括号不匹配
                {
                    flag=0;
                    break;
                }
                else                                 //栈不空,我们就获取栈顶元素,调用Get函数
                {
                    if(Get(L)=='(')                  //括号匹配了,调用Pop函数,将左括号出栈
                    {
                        Pop(&L);
                    }
                    else                              //括号不匹配,那我们标记flag=0,结束循环,括号不匹配
                    {
                        flag=0;
                        break;
                    }
                }
            }
            else if(s[i]=='}')                           //接下来的两个else  if和上面的思想一致。
            {

                if(Empty(L))
                {
                    flag=0;
                    break;
                }
                else   //问题就出在这一句上
                {
                    if(Get(L)=='{')
                    {
                        Pop(&L);
                    }
                    else
                    {
                        flag=0;
                        break;
                    }
                }
            }
            else if(s[i]==']')
            {

                if(Empty(L))
                {
                    flag=0;
                    break;
                }
                else
                {
                    if(Get(L)=='[')
                    {
                        Pop(&L);
                    }
                    else
                    {
                        flag=0;
                        break;
                    }
                }
            }
        }
        if(!Empty(L))                                   //遍历完算术表达式之后,判断栈是否为空,如果不为空,标记flag=0;
        {
            flag=0;
        }
        if(flag==1&&Empty(L))                  //只有flag=1并且栈是空的,我们才能说我们输入的括号是完全匹配的
        {
            printf("yes\n");
        }
        else                       
        {
            printf("no\n");
        }
    }
    return 0;
}

(8) Operation results

 4. Complete code


#include <stdio.h>
#include <stdlib.h>
#define Maxsize 100
typedef struct ST
{
    char data[Maxsize];
    int  top;
}Stack;
void Init(Stack *L)
{
    L->top=-1;
}
void Push(Stack *L,char x)
{
    if(L->top>=Maxsize)
    {
        return;
    }
    L->top++;
    L->data[L->top]=x;
}
int Empty(Stack L)
{
    if(L.top==-1)
    {
        return 1;//为空返回1
    }
    return 0;    //不为空返回0
}
void Print(Stack L)
{
    for(int i=L.top;i>-1;i--)
    {
        printf("%c   ",L.data[i]);
    }
}
void Pop(Stack *L)
{
    if(L->top==-1)
    {
        return;
    }
    L->top--;
}
char Get(Stack L)
{
    return L.data[L.top];
}
int main()
{
    Stack L;
    char s[100];
    while(gets(s))
    {
        Init(&L);
        int flag=1;
        //printf("%s",s);
        for(int i=0;s[i]!='\0';i++)
        {
            if(s[i]=='('||s[i]=='['||s[i]=='{')
            {
                if(L.top<Maxsize)
                {
                    char x=s[i];
                    Push(&L,x);
                }

            }
            else if(s[i]==')')
            {

                if(Empty(L))
                {
                    flag=0;
                    break;
                }
                else  
                {
                    if(Get(L)=='(')
                    {
                        Pop(&L);
                    }
                    else
                    {
                        flag=0;
                        break;
                    }
                }
            }
            else if(s[i]=='}')
            {

                if(Empty(L))
                {
                    flag=0;
                    break;
                }
                else   
                {
                    if(Get(L)=='{')
                    {
                        Pop(&L);
                    }
                    else
                    {
                        flag=0;
                        break;
                    }
                }
            }
            else if(s[i]==']')
            {
                if(Empty(L))
                {
                    flag=0;
                    break;
                }
                else   
                {
                    if(Get(L)=='[')
                    {
                        Pop(&L);
                    }
                    else
                    {
                        flag=0;
                        break;
                    }
                }
            }
        }
        if(!Empty(L))
        {
            flag=0;
        }
        if(flag==1&&Empty(L))
        {
            printf("yes\n");
        }
        else
        {
            printf("no\n");
        }
    }
    return 0;
}

Summary: The bracket matching problem is a classic. It perfectly examines our understanding of the stack. Familiarity with the operation of the stack is basic. Only by combining it with specific problems and applying it can we really master it. Theory is linked to practice, and practice is the only criterion for testing truth. Keep going.

Guess you like

Origin blog.csdn.net/BaoITcore/article/details/121442060