栈解决------括号匹配问题和逆波兰表达式
2018-08-20 16:09
78 查看
所需知识
栈
字符串
一.括号匹配问题
❀思路分析
有如下四组字符串
如何检测左右括号顺序与个数是否匹配
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__
阅读更多
相关文章推荐
- 动态栈的实现,括号匹配问题,逆波兰表达式
- 数据结构中的栈,在解决很多问题都有用处,比如括号匹配,迷宫求解,表达式求值等等 java中有封装好的类,可以直接调用。
- 利用栈解决括号匹配和逆波兰表达式
- 【C++】括号匹配问题与逆波兰表达式
- 链栈的简单实现及括号匹配问题的链栈解决方法
- [C++]连续最长括号匹配问题解决策略二(学习)
- 括号匹配问题 中缀表达式转换为后缀表达式
- 用栈的链式存储结构来解决括号匹配问题
- 快速解决工作中遇到经典的括号匹配问题
- 栈的应用----括号匹配、逆波兰表达式【数据结构】
- python正则表达式中的括号匹配问题
- Java 用栈解决括号匹配问题
- 栈及栈的应用(括号匹配和逆波兰表达式)
- 《LeetBook》leetcode题解(20):Valid Parentheses[E]——栈解决括号匹配问题
- 数据结构(八) 用顺序栈解决括号匹配的问题
- 【面试题】用栈解决括号匹配问题
- python正则表达式中的括号匹配问题
- 栈的应用(括号匹配、逆波兰表达式)
- IOS 正则表达式匹配文本中URL位置并获取URL所在位置(解决连接中文问题)
- 用堆栈解决括号匹配问题(C语言)