算术表达式求值 - 栈的应用
2017-05-16 17:00
351 查看
注:实验用书为 数据结构 C语言版 第2版,人民邮电出版社出版。
实验题目:学生管理系统的设计与实现
实验环境:Visual C++ 6.0或其他C++环境
一、实验目的
1、掌握栈的定义及实现;
2、掌握利用栈求解算术表达式的方法。
二、实验内容
通过修改完善教材中的算法3.4,利用栈来实现算术表达式求值的算法。对算法3.4中调用的几个函数要给出其实现过程:
1、函数In(c):判断c是否为运算符;
2、函数Precede(t1,t2):判断运算符t1和t2的优先级;
3、函数Operate(a,theta,b):对a和b进行二元运算theta。
4、程序运行时,输入合法的算术表达式(中间值及最终结果要在0~9之间,可以包括加减乘除和括号),便可输出相应的计算结果。如下图所示。
三、实验吐槽
此代码有很多缺陷,比如只能整数运算。而且单个运算最多到127。即数字运行结果最好在100以内。但可以实现10*10#等运算,这是因为算法的存储环境是char,最大256,而‘0’这个ASCII值又是48,对运算有所限制,但突破了之前的只能一位数字运算。
四、代码
代码主文件(calculator.cpp):
代码头文件(stack.h):
另外提供一种我第一次实践的方法,这里的算数表达式只能计算1位数值。
五、流程图
实验题目:学生管理系统的设计与实现
实验环境:Visual C++ 6.0或其他C++环境
一、实验目的
1、掌握栈的定义及实现;
2、掌握利用栈求解算术表达式的方法。
二、实验内容
通过修改完善教材中的算法3.4,利用栈来实现算术表达式求值的算法。对算法3.4中调用的几个函数要给出其实现过程:
1、函数In(c):判断c是否为运算符;
2、函数Precede(t1,t2):判断运算符t1和t2的优先级;
3、函数Operate(a,theta,b):对a和b进行二元运算theta。
4、程序运行时,输入合法的算术表达式(中间值及最终结果要在0~9之间,可以包括加减乘除和括号),便可输出相应的计算结果。如下图所示。
三、实验吐槽
此代码有很多缺陷,比如只能整数运算。而且单个运算最多到127。即数字运行结果最好在100以内。但可以实现10*10#等运算,这是因为算法的存储环境是char,最大256,而‘0’这个ASCII值又是48,对运算有所限制,但突破了之前的只能一位数字运算。
四、代码
代码主文件(calculator.cpp):
#include<iostream> #include "stack.h" #include<stdio.h> using namespace std; bool In(char e)//判断读入字符是否为运算符 { if(e=='+'||e=='-'||e=='*'||e=='/'||e=='('||e==')'||e=='#') return true;//是 else return false;//不是 } char Precede(char a,char b)//比较运算符的优先级 {//对照数据集书78页的表,a为纵轴值,b为横轴值 char f; if(a=='+'||a=='-') { if(b=='+'||b=='-'||b==')'||b=='#') f='>'; else if(b=='*'||b=='/'||b=='(') f='<'; } else if(a=='*'||a=='/') { if(b=='+'||b=='-'||b=='*'||b=='/'||b==')'||b=='#') f='>'; else if(b=='(') f='<'; } else if(a=='(') { if(b=='+'||b=='-'||b=='*'||b=='/'||b=='(') f='<'; else if(b==')') f='='; } else if(a==')') { if(b=='+'||b=='-'||b=='*'||b=='/'||b==')'||b=='#') f='>'; } else if(a=='#') { if(b=='+'||b=='-'||b=='*'||b=='/'||b=='(') f='<'; else if(b=='#') f='='; } return f; } int Operate(int i,char theta,int j)//计算a(theta)b结果 { int result; switch(theta) { case '+': result = i + j; break; case '-': result = i - j; break; case '*': result = i * j; break; case '/': result = i / j; break; } return result; } int read_C(int *n){ char c; *n=0; while((c=getchar())==' '); //跳过一个或多个空格 if(In(c)){//通过函数判断如果字符不是数字,那么只能是运算符 *n=c; return 1; } do{//能执行到该条语句,说明字符是数字,此处用循环获得连续的数字 *n=*n*10+(c-'0'); //把连续的数字字符转换成相对应的整数 c=getchar(); }while(!In(c)); //如果下一个字符是数字,进入下一轮循环 ungetc(c,stdin);//新读入的字符不是数字,可能是运算符,为了不影响下次读入,把该字符放回到输入缓冲区 return 0; } int EvaluateExpression() { SqStack OPND,OPTR; int flag; int ch;//把读入的字符转换为整数型,即ASCII表值 char a,b,theta,x;//ch为当前读入字符,theta为运算符,x仅仅只是变量寄存弹出值,对计算表达式无影响。 InitStack(OPND);//初始化OPND栈,寄存操作数和运算结果 InitStack(OPTR);//初始化OPTR栈,寄存运算符 Push(OPTR,'#'); flag=read_C(&ch); while(ch!='#'||GetTop(OPTR)!='#') { if(flag==0)//如果是运算符,直接压栈读入新字符 { Push(OPND,ch); flag=read_C(&ch); } else { switch(Precede(GetTop(OPTR),ch)) {//优先级选择 case '<': Push(OPTR,ch); flag=read_C(&ch); break; case '>': Pop(OPTR,theta); Pop(OPND,b); Pop(OPND,a); Push(OPND,Operate(a,theta,b)); break; case '=': Pop(OPTR,x); flag=read_C(&ch); break; } } } return GetTop(OPND); } int main() { cout<<"请输入算术表达式,并以#结束."<<endl; cout<<EvaluateExpression()<<endl; return 0; }
代码头文件(stack.h):
#ifndef STACK_H_INCLUDED #define STACK_H_INCLUDED #endif // STACK_H_INCLUDED #define MAXSIZE 100 #include<stdlib.h> using namespace std; typedef char SElemType; typedef struct { char *base; char *top; int stacksize; }SqStack; void InitStack(SqStack &S) { S.base=new char [MAXSIZE]; if(!S.base) exit(0); S.top=S.base; S.stacksize=MAXSIZE; } bool Push(SqStack &S,char e) { if(S.top-S.base==S.stacksize) return false; *S.top++=e; return true; } bool Pop(SqStack &S,char &e) { if(S.top==S.base) return false; e=*--S.top; //cout<<"pop="<<*S.top; return true; } char GetTop(SqStack S) { if(S.top!=S.base) return *(S.top-1); }
另外提供一种我第一次实践的方法,这里的算数表达式只能计算1位数值。
#include<iostream> #include "stack.h" #include<stdio.h> using namespace std; bool In(char e)//判断读入字符是否为运算符 { if(e=='+'||e=='-'||e=='*'||e=='/'||e=='('||e==')'||e=='#') return true;//是 else return false;//不是 } char Precede(char a,char b)//比较运算符的优先级 {//对照数据集书78页的表,a为纵轴值,b为横轴值 char f; if(a=='+'||a=='-') { if(b=='+'||b=='-'||b==')'||b=='#') f='>'; else if(b=='*'||b=='/'||b=='(') f='<'; } else if(a=='*'||a=='/') { if(b=='+'||b=='-'||b=='*'||b=='/'||b==')'||b=='#') f='>'; else if(b=='(') f='<'; } else if(a=='(') { if(b=='+'||b=='-'||b=='*'||b=='/'||b=='(') f='<'; else if(b==')') f='='; } else if(a==')') { if(b=='+'||b=='-'||b=='*'||b=='/'||b==')'||b=='#') f='>'; } else if(a=='#') { if(b=='+'||b=='-'||b=='*'||b=='/'||b=='(') f='<'; else if(b=='#') f='='; } return f; } char Operate(char a,char theta,char b)//计算a(theta)b结果 { char c; a=a-'0';//把char类型数据转换为数值型数据,方便运算。· b=b-'0'; if(theta=='+') c=a+b+'0'; else if(theta=='-') c=a-b+'0'; else if(theta=='*') c=a*b+'0'; else if(theta=='/') c=a/b+'0'; return c; } int EvaluateExpression() { SqStack OPND,OPTR; char ch,a,b,theta,x;//ch为当前读入字符,theta为运算符,x仅仅只是变量寄存弹出值,对计算表达式无影响。 InitStack(OPND);//初始化OPND栈,寄存操作数和运算结果 InitStack(OPTR);//初始化OPTR栈,寄存运算符 Push(OPTR,'#'); ch=getchar(); while(ch!='#'||GetTop(OPTR)!='#') { if(!In(ch)) { Push(OPND,ch); cin>>ch;//相当于ch=getchar(); } else { switch(Precede(GetTop(OPTR),ch)) { case '<': Push(OPTR,ch); cin>>ch; break; case '>': Pop(OPTR,theta); Pop(OPND,b); Pop(OPND,a); Push(OPND,Operate(a,theta,b)); break; case '=': Pop(OPTR,x); cin>>ch; break; } } } return GetTop(OPND)-'0'; } int main() { cout<<"请输入算术表达式,并以#结束."<<endl; cout<<EvaluateExpression()<<endl; return 0; }
五、流程图
相关文章推荐
- 数据结构之应用 "栈(Stack)" 实现: 解析算术表达式及计算求值 (C#/Java)
- 栈的应用--算术表达式的求值(中缀转后缀然后计算后缀表达式的值)
- 数据结构之应用 "栈(Stack)" 实现: 解析算术表达式及计算求值 (C#/Java) (转载)
- 数据结构习作之应用 "栈(Stack)" 实现: 解析算术表达式及计算求值 (C#/Java) (技术含量少许)
- 数据结构之应用 "栈(Stack)" 实现: 解析算术表达式及计算求值 (C#/Java)
- 栈应用1:算术表达式求值
- 通过算术表达式求值说明栈的应用
- 栈的应用之算术表达式求值
- 数据结构之应用 "栈(Stack)" 实现: 解析算术表达式及计算求值 (C#/Java)
- 栈的应用 算术表达式求值 学习笔记
- 数据结构Java实现——①栈-->栈的应用三、算术表达式求值
- 实验一 线性表及其应用 算术表达式求值
- 数据结构之应用 "栈(Stack)" 实现: 解析算术表达式及计算求值 (C#/Java)
- 表达式求值(栈的应用)(C++)
- 算术表达式求值
- 栈和队列-算术表达式的求值
- 算术表达式求值
- 经典算法-算术表达式求值
- 堆栈的应用(2) 中缀算术表达式到后缀(逆波兰记法reverse polish notation)的转换及其计算 C++实现
- 算术表达式求值:“算符优先级法”、“后缀表达式法”