<数据结构>栈-表达式求值
2013-06-04 22:11
369 查看
#include <cstdio> #include <malloc.h> #include <cstring> #define MAXSIZE 101 //运算符栈 struct OpStack { char data[MAXSIZE]; int top; //栈顶元素下一个元素的下标 }; //初始化运算符栈 OpStack *Init_Op() { OpStack *sOp; sOp = (OpStack *)malloc(sizeof(OpStack)); sOp->top = 0; return sOp; } //入运算符栈 int Push_Op(OpStack *sOp, char ch) { if (sOp->top == MAXSIZE) { return 0; } else { sOp->data[sOp->top] = ch; sOp->top++; return 1; } } //出运算符栈 int Pop_Op(OpStack *sOp, char *ch) { if (sOp->top == 0) { return 0; } else { *ch = sOp->data[sOp->top-1]; sOp->top--; return 1; } } //获取运算符栈栈顶元素 char GetTop_Op(OpStack *sOp) { return sOp->data[sOp->top-1]; } //判断运算符栈是否为空 int IsEmpty_Op(OpStack *sOp) { return sOp->top == 0; } //操作数栈 struct NumStack { float data[MAXSIZE]; int top; //栈顶元素下一个元素的下标 }; //初始化操作数栈 NumStack *Init_Num() { NumStack *sNum; sNum = (NumStack *)malloc(sizeof(NumStack)); sNum->top = 0; return sNum; } //入操作数栈 int Push_Num(NumStack *sNum, float num) { if (sNum->top == MAXSIZE) { return 0; } else { sNum->data[sNum->top] = num; sNum->top++; return 1; } } //出操作数栈 int Pop_Num(NumStack *sNum, float *num) { if (sNum->top == 0) { return 0; } else { *num = sNum->data[sNum->top-1]; sNum->top--; return 1; } } //获取操作数栈栈顶元素 float GetTop_Num(NumStack *sNum) { return sNum->data[sNum->top-1]; } //判断操作数栈是否为空 int IsEmpty_Num(NumStack *sNum) { return sNum->top == 0; } //判断运算符的优先级 int priority(char ch) { if (ch=='=' || ch=='(') { return 0; //使左括号和等号的优先级最低 } else if (ch=='+' || ch=='-') { return 1; } else if (ch=='*' || ch=='/') { return 2; } } //计算结果 float result(float x, float y, char ch) { if (ch == '+') { return y+x; } else if (ch == '-') { return y-x; } else if (ch == '*') { return y*x; } else if (ch == '/') { return y/x; } } //中缀表达式转换为后缀表达式 void toPostfix(char inf[], char post[]) { //post为存放后缀表达式的字符数组 int index = 0; //用于动态的表示post数组的下标 bool isNum = false; //用于判断之前是否出现过数字 OpStack *sOp; //定义运算符栈 sOp = Init_Op(); //初始化运算符栈 char ch;//接收出栈的左括号 //循环遍历中缀表达式 for (int i=0; i<strlen(inf); i++) { //判断是否为数字或者小数点 if (inf[i]>='0' && inf[i]<='9' || inf[i]=='.') { isNum = true; //将布尔值置为真 post[index++] = inf[i]; //直接将数字加入到post数组中 } else { //如果输入空格,结束本次循环 if (inf[i] == ' ') { continue ; } //判断之前是否出现了数字 if (isNum) { post[index++] = '#'; isNum = false; //将布尔值置为假 } //判断是否结束 if (inf[i] == '=') { break; } //判断是否为'('或者栈空 if (inf[i]=='(' || IsEmpty_Op(sOp)) { //将其入栈 Push_Op(sOp, inf[i]); } else if (inf[i]==')') { //循环到左括号 while (GetTop_Op(sOp) != '(') { //依次出栈,并加入到post数组中 Pop_Op(sOp, &post[index++]); } Pop_Op(sOp, &ch);//将左括号出栈 } else if (!IsEmpty_Op(sOp) && priority(inf[i])<=priority(GetTop_Op(sOp))) { //栈不为空,且此运算符的优先级低于或等于栈顶元素优先级 while (!IsEmpty_Op(sOp) && priority(inf[i])<=priority(GetTop_Op(sOp))) { //出栈加post Pop_Op(sOp, &post[index++]); } //循环完毕,把此运算符压入栈中 Push_Op(sOp, inf[i]); } else { //直接把此运算符压入栈中 Push_Op(sOp, inf[i]); } } } //遍历完成 //将栈顶运算符出栈,加入到post中 Pop_Op(sOp, &post[index++]); //字符串末尾加上'\0' post[index] = '\0'; return ; } //计算后缀表达式 float caPostfix(char post[]) { NumStack *sNum; //定义一个操作数栈 sNum = Init_Num();//初始化操作数栈 float res; //存放结果 bool isPoint;//判断是否有小数点 float pos;//10的倍数 float temp1; //存放操作数1 float temp2;//存放操作数2 for (int i=0; i<strlen(post); i++) { res = 0; isPoint = false; pos = 10; //判断是否为数字 if (post[i]>='0' && post[i]<='9') { //数字没结束前 for (; post[i]!='#'; i++) { if (post[i]=='.') { isPoint = true; i++; } //如果没有小数点,整数部分 if (!isPoint) { res = res*10+post[i]-'0'; } else { res += (post[i]-'0')/pos; pos *= 10; } } //把结果入栈 Push_Num(sNum, res); } else { Pop_Num(sNum, &temp1);//出栈第一个操作数 Pop_Num(sNum, &temp2);//出栈第二个操作数 Push_Num(sNum, result(temp1, temp2, post[i]));//结果入栈 } } return GetTop_Num(sNum); } int main() { printf("|-----------表达式求解----------|\n"); printf("|1.该程序支持浮点数运算 |\n"); printf("|2.该程序支持空格输入 |\n"); printf("|3.该程序支持多重小括号运算 |\n"); printf("|注:此程序使用的是后缀表达式计算|\n"); printf("|-------------------------------|\n"); char inf[MAXSIZE];//定义一个存放中缀表达式的字符数组 printf("请输入你需要计算的中值表达式(eg:(2*(2*(3+1))+1=,注意末尾有一个=号.):\n"); gets(inf);//输入中缀表达式字符数组 char post[MAXSIZE]; toPostfix(inf, post); printf("Postfix:%s\n", post); float res; res = caPostfix(post); printf("Result:%s%.2f\n", inf, res); return 0; }
相关文章推荐
- 数据结构Java实现——①栈-->栈的应用三、算术表达式求值
- 数据结构 栈的应用-- 表达式求值
- 数据结构-表达式求值
- nyoj 35 表达式求值<模拟+栈>
- MATLAB符号表达式->函数->求值
- 数据结构 【实验5 表达式求值】
- nyoj.35 表达式求值【数据结构】 2015/03/11
- <<精通正在表达式>> 书评
- 数据结构中的栈,在解决很多问题都有用处,比如括号匹配,迷宫求解,表达式求值等等 java中有封装好的类,可以直接调用。
- 数据结构---表达式求值
- nyoj305表达式求值(数据结构---栈)
- <数据结构-队列>
- 数据结构(19)栈典型问题之C++实现表达式求值
- 数据结构 学习笔记(三):线性结构:堆栈,队列,表达式求值,多项式加法运算
- 数据结构:栈的典型应用之二:四则运算表达式求值(C++)
- <数据结构>线性表.顺序存储结构
- <数据结构 课程设计> 文件目录结构显示(Java 版)
- < 笔记 > Java SE - 10 Java SE 正则表达式
- <深入理解JavaScript>学习笔记(4)_立即调用的函数表达式
- 数据结构--栈的应用(表达式求值 nyoj 35)