
数据结构 第四章 栈
发布日期:2021-05-07 18:20:29
浏览次数:16
分类:技术文章
本文共 3970 字,大约阅读时间需要 13 分钟。
Stack 模板类:
#include "Vector.h"templateclass Stack : public Vector { public: void push ( T const& e) {insert(size(), e);} T pop() {return remove(size() - 1);} T& top() {return (*this) [size() - 1];}};
栈结构的应用:
1. 逆序输出
例如:进制转换
void convert(Stack& S, __int64 n, int base){ static char digit[] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' }; while (n > 0){ S.push(digit[n % base]); n /= base; }}
2. 递归嵌套
例如:
括号匹配:
bool paren (const char exp[], int lo, int hi){ StackS; for ( int i = lo; i <= hi; i++) switch(exp[i]){ case '(': case '[':case '{': S.push(exp[i]); break; case ')': if ((S.empty())||('(' != S.pop())) return false; break; case ']': if ((S.empty())||('[' != S.pop())) return false; break; case '}': if ((S.empty())||('{' != S.pop())) return false; break; default : break; } return S.empty();}
3. 延迟缓冲
表达式求值:
运算符优先级表:
#define N_OPTR 9 //运算符总数typedef enum { ADD, SUB, MUL, DIV, POW, FAC, L_P, R_P, EOE } Operator; //运算符集合//加、减、乘、除、乘方、阶乘、左括号、右括号、起始符与终止符 const char pri[N_OPTR][N_OPTR] = { //运算符优先等级 [栈顶] [当前]/* |-------------------- 当 前 运 算 符 --------------------| *//* + - * / ^ ! ( ) \0 *//* -- + */ '>', '>', '<', '<', '<', '<', '<', '>', '>',/* | - */ '>', '>', '<', '<', '<', '<', '<', '>', '>',/* 栈 * */ '>', '>', '>', '>', '<', '<', '<', '>', '>',/* 顶 / */ '>', '>', '>', '>', '<', '<', '<', '>', '>',/* 运 ^ */ '>', '>', '>', '>', '>', '<', '<', '>', '>',/* 算 ! */ '>', '>', '>', '>', '>', '>', ' ', '>', '>',/* 符 ( */ '<', '<', '<', '<', '<', '<', '<', '=', ' ',/* | ) */ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',/* -- \0 */ '<', '<', '<', '<', '<', '<', '<', ' ', '='};
优先级判定:
void readNumber(char*& p, Stack& stk){ stk.push((float)(*p - '0')); while(isdigit(*(++p))) stk.push(stk.pop()*10+(*p - '0')); if ('.' != *p) return; float fraction = 1; while(isdigit(*(++p))) stk.push(stk.pop()+(*p -'0')*(fraction/=10));}Operator optr2rank (char op){ switch (op) { case '+': return ADD; break; case '-': return SUB; break; case '*' : return MUL; break; case '/': return DIV; break; case '^': return POW; break; case '!': return FAC; break; case '(': return L_P; break; case ')': return R_P; break; case '\0': return EOE; break; default: break; }}char orderBetween( char op1,char op2){ return pri[optr2rank(op1)][optr2rank(op2)];}
中缀表达式求值:
float evaluate( char* S, char* RPN){ Stackopnd; Stack optr; optr.push('\0'); while( !optr.empty()){ if(isdigit(*S)) readNumber(S, opnd); else switch(orderBetween(optr.top(), *S)){ case '<': optr.push(*S); S++; break; case '=': optr.pop(); S++; break; case '>': char op = optr.pop(); append(RPN, op); if ('!' == op) { float p0pnd = opnd.pop(); opnd.push( calcu(op, p0pnd)); }else { float p0pnd2 = opnd.pop(), p0pnd1 = opnd.pop(); opnd.push( calcu(p0pnd1, op, p0pnd2)); } break; default: exit(-1); } } return opnd.pop();}
void append(char*& rpn, char optr){ int n = strlen(rpn); rpn = (char*)realloc(rpn, sizeof(char)*(n+3)); sprintf(rpn+n, "%c", optr); rpn[n + 2] = '\0';}
栈混洗
逆波兰表达式:RPN
4. 栈式计算
发表评论
最新留言
第一次来,支持一个
[***.219.124.196]2025年03月21日 08时43分36秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
接口又是个啥?
2019-03-04
二叉树的基础练习题代码
2019-03-04
SpringMVC模板代码
2019-03-04
5.11 TEST1
2019-03-04
2020牛客NOIP赛前集训营-普及组(第四、五场)
2019-03-04
uni-app请求头中携带token
2019-03-04
常用的 Git 命令和小技巧(1)
2019-03-04
vue中接收后台的图片验证码并显示
2019-03-04
springboot入门(1)---整合MyBatis
2019-03-04
Vue入门学习笔记(1)
2019-03-04
前端入门经验——页面布局
2019-03-04
ECharts——双向柱状图
2019-03-04
Vue——引进bootstrap
2019-03-04
Vue——引进ivew
2019-03-04
趣谈win10常用快捷键
2019-03-04
趣谈文件扩展名和隐藏文件
2019-03-04
追梦App系列博客——第五次例会总结
2019-03-04
数学建模(NO.18灰色预测)
2019-03-04
数学建模更新12(数学线性规划模型1)
2019-03-04
数学建模更新12(多目标规划)
2019-03-04