实验2 栈和队列的应用-算术表达式求值
算法与数据结构栈与队列实验报告

实验二 栈和队列实现四则运算一、实验目的及要求:1、掌握栈和队列的基本操作:建立、插入、删除、查找、合并2、掌握用栈和队列的储存3、熟悉C 语言上机编程环境4、掌握编译、调试程序的方法二、实验内容:采用栈进行表达式的求值,表达式求值是程序设计语言编译中的一个最基本问题。
它的实现是栈应用的又一个典型例子,本报告使用的是“算符优先法”求表达式的值。
要把一个表达式翻译成正确求值的一个机器指令序列,或者直接对表达式求值,首先要能够正确解释表达式。
若要正确翻译则首先要了解算术四则运算的规则。
即:(1)、先乘除,后加减; (2)、从左算到右; (3)、先括号内后括号外。
任何一个表达式都是由操作数、运算符和界限符组成的,我们称它们为单词。
一般地,操作数既可以是常数也可以是被说明为变量或常量的标识符;运算符可以分为算术运算符、关系运算符和逻辑运算符3类;基本界限符有左右括号和表达式结束符等。
为了叙述的简洁,我们仅讨论简单算术表达式的求值问题。
这种表达式只包含加、减、乘、除4种运算符。
我们把运算符和界限符统称为算符,它们构成的集合命名为OP 。
根据上述3条运算规则,在运算的每一步中,任意两个相继出现的算符1θ和2θ之间的优先级之多是以下3种关系之一:12θθ< 1θ的优先级低于2θ 12θθ= 1θ的优先级等于2θ 12θθ> 1θ的优先级高于2θ根据实际情况推导出如下的优先关系算符间的优先关系表有规则(3),+、-、*和/为1θ时优先性均低于“(”但高于“),”由规则(2),当12θθ=时,令12θθ>,“#”是表达式的结束符。
为了算法简洁,在表达式左右括号的最左边也虚设了一个“#”构成整个表达式的一对括号。
表中的“(”=“)”表示当左右括号相遇时,括号内的运算已经完成。
同理,“#”=“#”表示整个表达式求值完毕。
“)”与“(、“#”与“)”以及“(”与“#”之间无优先级,这是因为表达式中不允许它们相继出现,一旦遇到这种情况,则可以认为出现语法错误。
实验二栈和队列应用

数据结构
实验题目
9.简单背包问题 问题描述 设一个背包所允许的重量是M,假设有N件物品, 物品的重量分别是Wi,可以任意挑选物品将背包装满。 实验要求 设计程序实现将给定背包装满的可能解。 1)采用栈等数据结构。 2)应用穷举法回溯策略求解。 3)尝试采用递归和非递归算法求解。
数据结构
实验题目
7.八皇后问题 问题描述 设一个8×8的棋盘里放置8个皇后,要求在每行、 每列、没斜线只允许放置1个皇后。 实验要求 设计实现所有可能解的程序。 1)采用栈等数据结构。 2)应用穷举法回溯策略求解。 3)尝试采用递归和非递归算法求解。
数据结构
实验题目
8.马踏棋盘问题 问题描述 中国象棋中的“马”走子的规则是:马走日字形。 实验要求 设计实现求象棋盘中的某一点出发踏遍棋盘所有点 的程序。 1)采用栈等数据结构。 2)应用穷举法回溯策略求解。 3)尝试求解所有出发点的可能 解。
数据结构
实验题目
3.运动员混合双打组合 问题描述 设有M个男羽毛球运动员和N个女羽毛球运动员,现 进行男女混合双打组合K轮配对。男女运动员分别编号 排队在等候队列,按顺序依次从男女运动员中各出队1 人组合配对。本轮没成功配对者等待下一轮次配对。
数据结构
实验题目
3.运动员混合双打组合 实验要求 设计程序模拟完成运动员组合配对过程。 1)采用队列等数据结构。 2)输出每轮的配对信息。
数据结构实验
LOGO
数据结构
实验二
实验题目
栈和队列应用
1.算术表达式求值 问题描述 由输入的四则算术表达式字符串,动态生成算术表 达式所对应的后缀式,通过后缀式求值并输出。
数据结构 实验题目
1.算术表达式求值 实验要求 十进制整数四则运算计算器。
实验2 栈和队列的操作

实验二栈和队列的操作一、实验目的1.熟悉栈和队列的存储结构;2.熟悉栈和队列的相关操作;3.利用栈和队列求解一些常见问题。
二、实验内容1、表达式求值任何一个算术表达式都是由操作数(operand) 、运算符(operator) 和界限符(edlimiter) 组成的。
为了简化问题.这里假设算术表达式中的操作数为单个数字表示的变量:运算符有加“ + ”、减“—”、乘“ * ”、除“/”和括号,表达式以“#”结束。
运算法则是括号优先级最高,先乘除,后加减,同级运算自左至右。
程序设计时需设置两个工作栈。
一个称为运算符栈,用OP 表示,用于存放表达式中的运算符:另一个称为操作数栈,用S 表示,用于存放操作数或运算结果。
这两个栈的初始状态均为空。
计算机从左至右扫描表达式,凡遇操作数一律进S 栈;若遇运算符,则要把它的优先数和栈顶运算符的优先数进行比较:若前者大,则该运算符进OP 栈;否则,栈顶运算符退栈、并进行计算,运算对象为S 栈顶上的两个元素,且先退栈的元素在运算量的右侧,后退栈的在运算量的左侧。
试编写一程序,先输入一个表达式,再求表达式的值。
2、数制转换假设现要编制一个满足下列要求的程序:对于输入的任意一个非负十进制整数,打印输出与其等值的八进制数。
从计算过程可见,这八进制的各个数位产生的顺序是从低位到高位的,而打印输出的顺序,一般来说应从高位到低位,这恰好和计算过程相反。
因此,需要先保存在计算过程中得到的八进制数的各位,然后逆序输出,因为它是按“后进先出”的规律进行的,所以用栈最合适。
试编写一个程序,实现将十进制数转换成八进制数并输出。
三、主要任务1、完成算法设计和程序设计,并分析算法时间复杂度和空间复杂度;2、写出程序运行情况,写出输入数据及运行结果;3、撰写实验报告,写出算法设计小结和心得。
四、思考题1、为什么说栈是一种特殊线性表?它的操作与线性表有什么不同?2、对于数制转换算法,如果不用栈如何实现?。
实验二--栈的应用---算术表达式的计算

浙江大学城市学院实验报告课程名称数据结构与算法实验项目名称实验二栈的应用---算术表达式的计算实验成绩指导老师(签名)日期一.实验目的和要求1.进一步掌握栈的基本操作的实现。
2.掌握栈在算术表达式的计算方面的应用。
二. 实验内容1. 编写程序利用栈将中缀表达式转换成后缀表达式,即从键盘输入任一个中缀表达式(字符串形式),转换成后缀表达式后,将后缀表达式输出。
假设:中缀表达式包含圆括号( ) 及双目运算符+、-、*、/、^(乘方)。
要求:把栈的基本操作的实现函数存放在头文件stack1.h中(栈元素的类型为char),在主文件test6_2.cpp中包含将中缀表达式S1转换成后缀表达式S2的转换函数void Change( char *S1, char *S2 )及主函数,在主函数中进行输入输出及转换函数的调用。
2. 选做:编写利用栈对后缀表达式进行求值的函数double Compute(char *str),以计算从前述程序得到的后缀表达式的值。
要求:把栈的基本操作的实现函数存放在头文件stack2.h中(栈元素的类型为double),在主文件test6_2.cpp中添加后缀表达式求值函数,并在主函数中增加调用求值函数及输出结果值的语句。
3. 填写实验报告,实验报告文件取名为report2.doc。
4. 上传实验报告文件report2.doc与源程序文件stack1.h、stack2.h(若有)及test6_2.cpp到Ftp服务器上你自己的文件夹下。
二.函数的功能说明及算法思路(算法思路见源程序的注释部分)//栈的顺序存储结构定义struct Stack{ElemType *stack;int top;int MaxSize;};//初始化栈S为空void InitStack(Stack &S)//元素item进栈,即插入到栈顶void Push(Stack &S,ElemType item)//删除栈顶元素并返回ElemType Pop(Stack &S)//读取栈顶元素的值ElemType Peek(Stack &S)//判断S是否为空,若是则返回true,否则返回false bool EmptyStack(Stack &S)//清除栈S中的所有元素,释放动态存储空间void ClearStack(Stack &S)//将中缀算术表达式转换为后缀算术表达式void Change(char *S1,char *&S2)//返回运算符op所对应的优先级数值int Precedence(char op)//计算由str所指字符串的后缀表达式的值double Compute(char *str)四. 实验结果与分析五. 心得体会【附录----源程序】test6_2.cpp#include<iostream.h>#include<stdlib.h>#include<math.h>#include"stack1.h"#include"stack2.h"void main(){char x[30],y[30];double r;while(1){cout<<"请输入一个中缀算术表达式:";cin.getline(x,sizeof(x));Change(x,y);cout<<"对应的后缀算术表达式为:";cout<<y<<endl;r=Compute(y);cout<<"后缀算术表达式值为:"<<r<<endl<<endl;}}stack1.htypedef char ElemType1;struct Stack1{ElemType1 *stack;int top;int MaxSize;};void InitStack(Stack1 &S){S.MaxSize=10;S.stack=new ElemType1[S.MaxSize];if(!S.stack){cerr<<"动态储存分配失败"<<endl;exit(1);}S.top=-1;}void Push(Stack1 &S,ElemType1 item)if(S.top==S.MaxSize-1){int k=sizeof(ElemType1);S.stack=(ElemType1*)realloc(S.stack,2*S.MaxSize*k);S.MaxSize=2*S.MaxSize;}S.top++;S.stack[S.top]=item;}ElemType1 Pop(Stack1 &S){if(S.top==-1){cerr<<"Stack is empty! "<<endl;exit(1);}S.top--;return S.stack[S.top+1];}ElemType1 Peek(Stack1 &S){if(S.top==-1){cerr<<"Stack is empty! "<<endl;exit(1);}return S.stack[S.top];}bool EmptyStack(Stack1 &S){return S.top==-1;}void ClearStack(Stack1 &S){if(S.stack){delete []S.stack;S.stack=0;}S.top=-1;S.MaxSize=0;}//返回运算符op所对应的优先级数值int Precedence(char op){switch(op){case'+':case'-':return 1;case'*':case'/':return 2;case'^':return 3;case'(':case'@':default:return 0;}}//将中缀算术表达式转换为后缀算术表达式void Change(char *S1,char *S2){Stack1 R;InitStack(R);Push(R,'@');int i=0,j=0;char ch=S1[i];while(ch!='\0'){//对于空格字符不做任何处理,顺序读取下一个字符if(ch==' ')ch=S1[++i];//对于左括号,直接进栈else if(ch=='('){Push(R,ch);ch=S1[++i];}//对于右括号,使括号内的仍停留在栈中的运算符依次出栈并写入S2else if(ch==')'){while(Peek(R)!='(')S2[j++]=Pop(R);Pop(R);//删除栈顶的左括号ch=S1[++i];}//对于运算符,使暂存于栈顶且不低于ch优先级的运算符依次出栈并写入S2else if(ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='^'){char w=Peek(R);while(Precedence(w)>=Precedence(ch)){S2[j++]=w;Pop(R);w=Peek(R);}Push(R,ch);//把ch运算符写入栈中ch=S1[++i];}else{if((ch<'0'||ch>'9')&&ch!='.'){cout<<"中缀表达式表示错误!"<<endl;exit(1);}while((ch>='0'&&ch<='9')||ch=='.'){S2[j++]=ch;ch=S1[++i];}S2[j++]=' ';}}//把暂存在栈中的运算符依次退栈并写入到S2中ch=Pop(R);while(ch!='@'){if(ch=='('){cerr<<"expression error!"<<endl;exit(1);}else{S2[j++]=ch;ch=Pop(R);}}S2[j++]='\0';}stack2.htypedef double ElemType2;struct Stack2{ElemType2 *stack;int top;int MaxSize;};void InitStack(Stack2 &S){S.MaxSize=10;S.stack=new ElemType2[S.MaxSize];if(!S.stack){cerr<<"动态储存分配失败"<<endl;exit(1);}S.top=-1;}void Push(Stack2 &S,ElemType2 item){if(S.top==S.MaxSize-1){int k=sizeof(ElemType2);S.stack=(ElemType2*)realloc(S.stack,2*S.MaxSize*k);S.MaxSize=2*S.MaxSize;}S.top++;S.stack[S.top]=item;}ElemType2 Pop(Stack2 &S){if(S.top==-1){cerr<<"Stack is empty! "<<endl;exit(1);}S.top--;return S.stack[S.top+1];}ElemType2 Peek(Stack2 &S){if(S.top==-1){cerr<<"Stack is empty! "<<endl;exit(1);}return S.stack[S.top];}bool EmptyStack(Stack2 &S){return S.top==-1;}void ClearStack(Stack2 &S){if(S.stack){delete []S.stack;S.stack=0;}S.top=-1;S.MaxSize=0;}//计算由str所指字符串的后缀表达式的值double Compute(char *str){Stack2 S;InitStack(S);double x,y;int i=0;while(str[i]){if(str[i]==' '){i++;continue;}switch(str[i]){case '+':x=Pop(S)+Pop(S);i++;break;case'-':x=Pop(S);x=Pop(S)-x;i++;break;case'*':x=Pop(S)*Pop(S);i++;break;case'/':x=Pop(S);if(x!=0)x=Pop(S)/x;else{cerr<<"Divide by 0!"<<endl;exit(1);}i++;break;case'^':x=Pop(S);x=pow(Pop(S),x);i++;break;default:x=0;while(str[i]>=48&&str[i]<=57){x=x*10+str[i]-48;i++;}if(str[i]=='.'){i++;y=0;double j=10.0;while(str[i]>=48&&str[i]<=57){y=y+(str[i]-48)/j;i++;j*=10;}x+=y;}}Push(S,x);}if(EmptyStack(S)){cerr<<"expression error!"<<endl;exit(1);}x=Pop(S);if(EmptyStack(S))return x;else{cerr<<"expression error!"<<endl;exit(1);}ClearStack(S);}(注:可编辑下载,若有不当之处,请指正,谢谢!)。
实验二 栈和队列

实验二栈和队列本文档旨在介绍实验二的目的和背景,以及本实验的重要性。
实验二主要涉及栈和队列的相关概念和操作。
栈和队列是常用的数据结构,它们在计算机科学和软件开发中起着重要的作用。
栈是一种先进后出(Last In First Out,LIFO)的数据结构,类似于我们平常堆放书籍的行为。
队列是一种先进先出(First In First Out,FIFO)的数据结构,类似于排队等待的情景。
通过本实验,我们将研究如何使用栈和队列来解决各种问题。
掌握栈和队列的基本原理和操作,对于提高程序的效率和优化算法都具有重要意义。
同时,栈和队列的概念也是许多其他数据结构和算法的基础,理解栈和队列将有助于我们更深入地研究和应用其他数据结构和算法。
本实验将引导我们通过实际的编程练来加深对栈和队列的理解和应用。
我们将实现栈和队列的基本操作,例如入栈、出栈、入队、出队等,并通过一系列的例子和问题来巩固对这些概念的理解。
通过完成本实验,我们将掌握栈和队列的基本概念和操作,加深对其应用场景的理解和掌握,并培养解决问题的逻辑思维能力和编程实践能力。
让我们开始实验二的研究,进一步探索栈和队列的奥秘吧!本实验的目标是研究和理解栈和队列数据结构的基本概念和操作。
本实验主要涉及栈和队列的定义、基本操作及其应用。
栈的定义栈是一种具有后进先出(Last-In-First-Out,简称LIFO)特性的线性数据结构。
栈只允许在表尾(称为栈顶)进行插入和删除操作,且最后插入的元素最先删除。
栈的基本操作栈的基本操作包括:Push:将元素插入到栈顶。
Pop:删除栈顶的元素,并返回被删除的元素。
IsEmpty:判断栈是否为空。
Top:返回栈顶的元素,但不删除栈顶元素。
栈的应用栈在计算机科学中有广泛的应用,包括但不限于:函数调用(函数调用时的局部变量保存在栈中)。
表达式求值(后缀表达式计算等)。
浏览器的页面回退功能。
队列的定义队列是一种具有先进先出(First-In-First-Out,简称FIFO)特性的线性数据结构。
栈和队列的应用实验报告

栈和队列的应用实验报告栈和队列的应用实验报告引言:栈和队列是计算机科学中常用的数据结构,它们在各种算法和应用中都有广泛的应用。
本实验报告旨在探讨栈和队列的基本概念、特性以及它们在实际应用中的具体使用。
一、栈的基本概念和特性栈是一种特殊的数据结构,它遵循“先进后出”的原则。
栈有两个基本操作:压栈(push)和弹栈(pop)。
压栈将元素添加到栈的顶部,弹栈则将栈顶元素移除。
栈还具有一个重要的特性,即它的访问方式是受限的,只能访问栈顶元素。
在实际应用中,栈可以用于实现递归算法、表达式求值、括号匹配等。
例如,在递归算法中,当函数调用自身时,需要将当前状态保存到栈中,以便在递归结束后能够恢复到正确的状态。
另外,栈还可以用于实现浏览器的“后退”功能,每次浏览新页面时,将当前页面的URL压入栈中,当用户点击“后退”按钮时,再从栈中弹出最近访问的URL。
二、队列的基本概念和特性队列是另一种常见的数据结构,它遵循“先进先出”的原则。
队列有两个基本操作:入队(enqueue)和出队(dequeue)。
入队将元素添加到队列的尾部,出队则将队列头部的元素移除。
与栈不同的是,队列可以访问头部和尾部的元素。
在实际应用中,队列经常用于任务调度、消息传递等场景。
例如,在操作系统中,任务调度器使用队列来管理待执行的任务,每当一个任务执行完毕后,从队列中取出下一个任务进行执行。
另外,消息队列也是一种常见的应用,它用于在分布式系统中传递消息,保证消息的顺序性和可靠性。
三、栈和队列在实际应用中的具体使用1. 栈的应用栈在计算机科学中有广泛的应用。
其中一个典型的应用是表达式求值。
当计算机遇到一个复杂的表达式时,需要将其转化为逆波兰表达式,然后使用栈来进行求值。
栈的特性使得它非常适合处理这种情况,可以方便地保存运算符和操作数的顺序,并按照正确的顺序进行计算。
另一个常见的应用是括号匹配。
在编程语言中,括号是一种常见的语法结构,需要保证括号的匹配性。
数据结构实验2——栈和队列实验报告

数据结构实验报告实验名称:实验2——栈和队列1 实验目的通过选择下面五个题目之一进行实现,掌握如下内容:进一步掌握指针、模板类、异常处理的使用掌握栈的操作的实现方法掌握队列的操作的实现方法学习使用栈解决实际问题的能力学习使用队列解决实际问题的能力2 实验内容利用栈结构实现八皇后问题。
八皇后问题19世纪著名的数学家高斯于1850年提出的。
他的问题是:在8*8的棋盘上放置8个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列、同一斜线上。
请设计算法打印所有可能的摆放方法。
提示:1、可以使用递归或非递归两种方法实现2、实现一个关键算法:判断任意两个皇后是否在同一行、同一列和同一斜线上2. 程序分析主程序:#include<iostream>using namespace std;const int StackSize=8; //皇后的个数int num=0;template <class T>class SeqStack //定义顺序栈模板类{public:SeqStack(){top=-1;} //构造函数,初始化空栈void Push(T x); //入栈操作void Pop();//出栈操作void PlaceQueen(int row); //放置皇后bool Judgement();//判断是否符合条件void Print();//输出符合条件的皇后排列bool Empty(){if(top==-1) return true;else return false;}; //判断栈是否为空private:T data[StackSize]; //定义数组int top; //栈顶指针};template <class T>void SeqStack<T>::Push(T x) //入栈操作{if(top>=StackSize-1) throw"上溢";top++;//栈顶指针上移data[top]=x;}template <class T>void SeqStack<T>::Pop()//出栈操作{if(Empty()) throw"下溢";top--;//栈顶指针下移}template <class T>bool SeqStack<T>::Judgement()//判断该位置是否合适{for(int i=0;i<top;i++)if(data[top]==data[i]||(abs(data[top]-data[i]))==(top-i))//判断是否满足任意两个皇后不在同列同一斜线return false;return true;}template <class T>void SeqStack<T>::PlaceQueen(int row) //放置皇后{for (int i=0;i<StackSize;i++){Push(i); //入栈if (Judgement())//判断位置是否合适{if (row<StackSize-1)PlaceQueen(row+1); //如果合适满足条件则放置一个皇后,递归调用else{num++;//不满足条件则到下一行Print();//输出符合条件的皇后}}Pop();//出栈}}template <class T>void SeqStack<T>::Print()//输出皇后函数{cout<<"NO."<<num<<":"<<endl; for(int i=0;i<StackSize;i++){for(int j=0;j<data[i];j++){cout<<"□";}cout<<"■";for(int j=StackSize-1;j>data[i];j--){cout<<"□";}cout<<endl;}cout<<endl;}void main(){SeqStack<int> Queen;Queen.PlaceQueen(0);cout<<"总共有"<<num<<"种摆放方法。
实验二栈与队列操作实验题目

实验二栈与队列操作实验题目实验二栈与队列操作实验目的:(1)理解栈与队列的结构特征和运算特征,以便在实际问题背景下灵活运用。
(2)了解复杂问题的递归算法设计。
本次实验中,下列实验项目选做一。
1、顺序栈的基本操作[问题描述]设计算法,实现顺序栈的各种基本操作[基本要求](1)初始化栈s。
(2)从键盘输入10个字符以$结束,建立顺序栈。
(3)从键盘输入1个元素,执行入栈操作。
(4)将栈顶元素出栈。
(5)判断栈是否为空。
(6)输出从栈顶到栈底元素。
要求程序通过一个主菜单进行控制,在主菜单界面通过选择菜单项的序号来调用各功能函数。
2、链栈的基本操作[问题描述]设计算法,实现链栈的各种基本操作[基本要求](1)初始化栈s。
(2)从键盘输入10个字符以$结束,建立带头结点的链栈。
(3)从键盘输入1个元素,执行入栈操作。
(4)完成出栈操作。
(5)判断栈是否为空。
(6)输出从栈顶到栈底元素。
(7)输出链栈的长度。
要求程序通过一个主菜单进行控制,在主菜单界面通过选择菜单项的序号来调用各功能函数。
3、循环队列的基本操作[问题描述]设计算法,实现循环顺序队列的建立、入队、出队等操作。
[基本要求](1)从键盘输入10个字符以$结束,建立循环队列,并显示结果。
(2)从键盘输入1个元素,执行入队操作,并显示结果。
(3)将队头元素出队,并显示结果。
(4)要求程序通过一个主菜单进行控制,在主菜单界面通过选择菜单项的序号来调用各功能函数。
4、只用尾指针表示的循环链表队列的综合操作[问题描述]假设以带头结点的的循环链表表示队列,并且只设一个指针指向队尾元素的结点(注意不设头指针),试编写队列初始化、入队、出队函数。
[基本要求及提示](1)首先定义链表结点类型。
(2)编写带头结点的循环链表的初始化函数,只用尾指针表示。
(3)编写入队函数、出队函数。
(4)在主函数中编写菜单(1.初始化;2.入队;3.出队;4.退出),调用上述功能函数。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
1.实验题目
栈和队列的应用
2.实验内容
算术表达式求值
3.实验目的
掌握栈和队列的概念及工作原理,运用其原理完成实验题目中的内容。
4.实验要求
为了更好的掌握与理解课堂上老师所讲的概念与原理,实验前要认真预习所做的实验内容及编写源程序伪码(写在纸上及盘中均可)以便在实验课中完成老师所布置的实验内容。
5.概要设计原理
6.详细程序清单及注释说明
#include <stdio.h>
#include <iostream.h>
#include <stdlib.h>
#include <string.h>
#define NULL 0
#define OK 1
#define OVERFLOW -2
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 20
/* 定义字符类型栈*/
typedef struct
{
int stacksize;
char *base;
char *top;
}SqStack;
/* ----------------- 全局变量--------------- */
SqStack OPTR,OPND;// 定义运算符栈和操作数栈
char expr[255]; /* 存放表达式串*/
char *ptr=expr;
int InitStack(SqStack *s) //构造运算符栈
{
s->base=(char *)malloc(STACK_INIT_SIZE*sizeof(char));
if(!s->base) exit(OVERFLOW);
s->top=s->base;
s->stacksize=STACK_INIT_SIZE;
return OK;
}
char In(char ch) //判断字符是否是运算符,运算符即返回1
{
return(ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='('||ch==')'||ch=='#'); }
int Push(SqStack *s,char ch) //运算符栈插入ch为新的栈顶元素{
*s->top=ch;
s->top++;
return 0;
}
char Pop(SqStack *s) //删除运算符栈s的栈顶元素,用p返回其值{
char p;
s->top--;
p=*s->top;
return p;
}
char GetTop(SqStack s)//用p返回运算符栈s的栈顶元素
{
char p=*(s.top-1);
return p;
}
/* 判断运算符优先权,返回优先权高的*/
char Precede(char c1,char c2)
{
int i=0,j=0;
static char array[49]={
'>', '>', '<', '<', '<', '>', '>',
'>', '>', '<', '<', '<', '>', '>',
'>', '>', '>', '>', '<', '>', '>',
'>', '>', '>', '>', '<', '>', '>',
'<', '<', '<', '<', '<', '=', '!',
'>', '>', '>', '>', '!', '>', '>',
'<', '<', '<', '<', '<', '!', '='};
switch(c1)
{
/* i为下面array的横标*/
case '+' : i=0;break;
case '-' : i=1;break;
case '*' : i=2;break;
case '/' : i=3;break;
case '(' : i=4;break;
case ')' : i=5;break;
case '#' : i=6;break;
}
switch(c2)
{
/* j为下面array的纵标*/
case '+' : j=0;break;
case '-' : j=1;break;
case '*' : j=2;break;
case '/' : j=3;break;
case '(' : j=4;break;
case ')' : j=5;break;
case '#' : j=6;break;
}
return (array[7*i+j]); /* 返回运算符*/ }
/*操作函数*/
int Operate(int a,char op,int b)
{
switch(op)
{
case '+' : return (a+b);
case '-' : return (a-b);
case '*' : return (a*b);
case '/' : return (a/b);
}
return 0;
}
int num(int n)//返回操作数的长度
{
char p[10];
itoa(n,p,10);//把整型转换成字符串型
n=strlen(p);
return n;
}
int EvaluateExpression()//主要操作函数
{
char c,theta,x; int n,m;
int a,b;
c = *ptr++;
while(c!='#'||GetTop(OPTR)!='#')
{
if(!In(c))
{ if(!In(*(ptr-1))) ptr=ptr-1;
m=atoi(ptr);//取字符串前面的数字段
n=num(m);
Push(&OPND,m);
ptr=ptr+n;
c=*ptr++;
}
else
switch(Precede(GetTop(OPTR),c))
{
case'<':Push(&OPTR,c);c=*ptr++;break;
case'=':x=Pop(&OPTR);c=*ptr++;break;
case'>':
theta=Pop(&OPTR);
b=Pop(&OPND);
a=Pop(&OPND);
Push(&OPND,Operate(a,theta,b));break;
}
}
return GetTop(OPND);
}
int main( )
{
printf("请输入正确的表达式以'#'结尾:\n");
do{gets(expr);}while(!*expr);
InitStack(&OPTR); /* 初始化运算符栈*/
Push(&OPTR,'#'); /* 将#压入运算符栈*/
InitStack(&OPND); /* 初始化操作数栈*/
printf("表达式的运算结果为:%d\n",EvaluateExpression());
getchar();
return 0;
}
7.运行与测试及结果
8.实验中所遇的问题及解决方法。