栈解决------括号匹配问题和逆波兰表达式

所需知识


字符串

一.括号匹配问题

❀思路分析

有如下四组字符串
如何检测左右括号顺序与个数是否匹配

    char a[] = "(())abc{[(])}";
    char b[] = "(()))abc{[]}";
    char c[] = "(()()abc{[]}";
    char d[] = "(())abc{[]()}";

1、解决:

(1)、当读到一个左括号的字符,包括‘(’,‘{’,‘[’时,将这个字符入栈,当检测到右括号字符时,包括‘)’,‘}’,’]’时,检测栈顶元素是否为与之匹配的左括号,若是,证明这一对括号匹配,将这个左括号出栈继续检测,检测到其他字符,如字母数字,直接跳过,不做任何处理。
(2)、左右括号不匹配:如果检测到右括号时,取栈顶元素中的左括号,发现不是与之对应的左括号,说明不匹配。
(3)、右括号比左括号多:如果检测到右括号时,取栈顶元素中的左括号,发现栈已空,说明右括号多余左括号。
(4)、左括号比右括号多:当所有字符都已经读完,发现栈内仍有左括号,说明左括号比右括号多。
(5)、匹配成功:当中间无其他情况发生,且读完字符后,栈为空,说明匹配成功。

2、具体实现

#include <stdio.h>
//括号匹配
#define MAX 20
typedef char DataType;
typedef struct Stack
{
    DataType arr[MAX];
    int top;

}Stack;
//初始化栈
void InitStack(Stack * s)
{
    s->top = 0;
}
//取栈顶元素
DataType StackTop(Stack * s)
{
    if (s->top == 0)
    {
        return '*';
    }
    return s->arr[s->top - 1];
}
//清空栈
void Empty(Stack * s)
{
    s->top = 0;
}
//入栈
void PushStack(Stack * s, DataType c)
{
    if (s->top == MAX)
    {
        printf("栈已满,无法再入\n");
        return;
    }
    s->arr[s->top] = c;
    s->top++;
}
//判断栈是否空,空返回1
int  EmptyStack(Stack *s)
{
    if (s->top == 0)
        return 1;
    return 0;
}
//出栈
void PopStack(Stack * s)
{
    if (s->top == 0)
    {
        printf("已空,无法再出栈\n");
        return;
    }
    s->top--;
}
void The(char arr[],Stack * s)
{
    int  i = 0;
    for ( i = 0; arr[i]!=0;i++)
    {
        if (arr[i] == '(')
        {
            PushStack(s, arr[i]);   
            continue;
        }
        if (arr[i] == '{')
        {
            PushStack(s, arr[i]);
            continue;
        }
        if (arr[i] == '[')
        {
            PushStack(s, arr[i]);
            continue;
        }
        if (arr[i] == ')')
        {

            if (StackTop(s) == '(')
            {
                PopStack(s);
            }
            else if (StackTop(s) == '*')
            {
                printf("右括号比左括号多\n");
                return;
            }
            else
            {
                printf("左右括号不匹配\n");
                return;
            }
        }
        if (arr[i] == ']')
        {
            if (StackTop(s) == '[')
            {
                PopStack(s);
            }
            else if (StackTop(s) == '*')
            {
                printf("右括号比左括号多\n");
                return;
            }
            else
            {
                printf("左右括号不匹配\n");
                return;
            }
        }
        if (arr[i] == '}')
        {
            if (StackTop(s) == '{')
            {
                PopStack(s);
            }
            else if (StackTop(s) == '*')
            {
                printf("右括号比左括号多\n");
                return;
            }
            else
            {
                printf("左右括号不匹配\n");
                return;
            }
        }
    }
    if (EmptyStack(s)&&arr[i]==0)
    {
        printf("匹配成功\n");
    }
    else
    {
        printf("左括号比右括号多\n");
    }

}
int main()
{
    //

    char a[] = "(())abc{[(])}";
    char b[] = "(()))abc{[]}";
    char c[] = "(()()abc{[]}";
    char d[] = "(())abc{[]()}";
    Stack s;
    InitStack(&s);
    The(a,&s);
    Empty(&s);
    The(b, &s);
    Empty(&s);
    The(c, &s);
    Empty(&s);
    The(d, &s); 
    system("pause");
    return 0;
}

《栈解决------括号匹配问题和逆波兰表达式》

二、逆波兰表达式

❀思路分析

《栈解决------括号匹配问题和逆波兰表达式》

以12*(3+4)-6+8/2 —–> 12 3 4 + *6 – 8 2/ +为例

(1)、读到数字时,将数字压栈

(2)、读到+,-,*,/的操作符时,取出栈顶的前两位数字,进行运算操作后,将其结果压栈

具体实现

#ifndef __REVERSE_ORDER_EXPRESSION_H__
//逆波兰表达式
//12*(3+4)-6+8/2 -----> 12 3 4 + *6 - 8 2/ +
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#define MAXSIZE 15
typedef enum Operation
{
    ADD,
    SUB,
    MUL,
    DIV,
    DATA
}Way;
typedef int DataType;
typedef struct Cell
{
    Way way;
    DataType data;
}Cell;
//进行逆波兰填栈操作
//创建栈
typedef struct Stack
{
    DataType data[MAXSIZE];
    int top;
}Stack;
//栈的初始化
void InitStack(Stack * s)
{
    s->top = 0;
}
//入栈
void PushStack(Stack * s, DataType d)
{
    assert(s);
    if (s->top == MAXSIZE)
    {
        printf("栈已满,无法入\n");
        return;
    }
    s->data[s->top] = d;
    s->top++;

}
//取栈顶元素,并出栈
DataType TopStack(Stack *s)
{
    assert(s);
    if (s->top == 0)
    {
        printf("无元素,无法取栈顶\n");
        return ;
    }
    s->top--;
    return s->data[s->top];
}
DataType order(Cell arr[],int size,Stack *s)
{
    int i = 0;
    int a = 0, b = 0;
    for (i = 0; i<size;i++)
    {
        a = 0;
        b = 0;
        switch(arr[i].way)
        {
        case ADD:
        {
                    a = TopStack(s);
                    b = TopStack(s);
                    PushStack(s, b + a);
                    break; 
        }
        case SUB:
        {
                    a = TopStack(s);
                    b = TopStack(s);
                    PushStack(s, b - a);
                    break; 
        }
        case MUL:
        {
                    a = TopStack(s);
                    b = TopStack(s);
                    PushStack(s, b * a);
                    break; 
        }
        case DIV:
        {
                    a = TopStack(s);
                    b = TopStack(s);
                    PushStack(s, b / a);
                    break;
        }
        case DATA:
        {
                     PushStack(s, arr[i].data );
                    break;
        }
        default:
        {
                   printf("给定值错误,请重新给定\n");
                    break;
        }
        }
    }
    return TopStack(s);
}
int main()
{
    //12*(3+4)-6+8/2 -----> 12 3 4 + *6 - 8 2/ +
    //给定数列操作12 3 4 + *6 - 8 2/ +
    Stack s;
    Cell arr[] = { { DATA, 12 }, { DATA, 3 }, { DATA, 4 },
    { ADD, 0 }, { MUL, 0 }, { DATA, 6 }, { SUB, 0 }, {DATA,8}, {DATA,2}, {DIV,0}, {ADD,0} };
    int size = sizeof(arr) / sizeof(arr[0]);
    InitStack(&s);
    printf("该表达式12*(3+4)-6+8/2 -----> 12 3 4 + *6 - 8 2/ +的值为%d \n", order(arr, size, &s));
    system("pause");
    return 0;
}

#endif //__REVERSE_H__

《栈解决------括号匹配问题和逆波兰表达式》

    原文作者:括号匹配问题
    原文地址: https://blog.csdn.net/qq_24990383/article/details/81865209
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞