1、完整word版)数据结构课程设计-表达式求值问题 实验 表达式求值问题 1.问题描述 表达式是数据运算的基本形式。人们的书写习惯是中缀式,如:11+22*(7-4)/3.中缀式的计算按运算符的优先级及括号优先的原则,相同级别从左到右进行计算。表达式还有后缀表达式(如:11 22 7 4 - * 3 / +)和前缀表达式(+ 11 / * 22 - 7 4 3)。后缀表达式 和前缀表达式中没有括号,给计算带来方便。如后缀表达式计算时按运算符出现的先后进行计算。本设计的主要任务是进行表达式形式的转换及不同形式的表达式计算。 2.数据结构设计 (1)顺序栈类定义:
2、首先应在类中定义成员函数,以此来完成顺序栈的相关操作,如下: class SqStack { private: T *base; //栈底指针 int top; //栈顶 int stacksize; //栈容量 public: SqStack(int m);
3、 //构建函数 ~SqStack(){delete [] base;top=0;stacksize=0;} //析构函数 void Push(T x); //入栈 T Pop(); //出栈 T GetTop(); //获取栈顶元素 int StackEmpty(); //测栈空 void Cle
4、arStack(); //清空栈
void StackTop(); //返回栈顶指针
void StackTranverse(); //显示栈中元素
};
(2)顺序栈类实现:对顺序栈进行初始化,初始化的首要操作就是创建一个空顺序栈。
Step1:申请一组连续的内存空间为顺序栈使用:
base=new T[m];
if(base==NULL)
{
cout<<"栈创建失败,退出!"< 5、op=-1;
(2)顺序栈入栈:入栈需要在栈顶插入一个新元素并相应的调整栈顶。
Step1:首先判断是否栈满,如果栈满,抛出“上溢”信息,无法入栈,否则转入Step2;
if(top==stacksize-1) throw "栈满,无法入栈";
Step2:栈顶指针增加1;
top++;
Step3:新元素插入栈顶位置;
base[top]=x;
(3)顺序栈出栈:出栈需要取出栈顶元素,并相应的调整栈顶指针。
Step1:首先判断是否栈空,如果栈空,抛出“下溢”信息,无法出栈,否则转入Step2;
if(top==-1) throw "栈空,不能出栈";
Step2:取 6、出栈顶元素,栈顶指针减1;
T x;
x=base[top--];
Step3:返回栈顶元素;
return x;
(4)顺序栈取栈顶元素:取栈顶元素是取出栈顶元素的值,但不改变栈。
Step1:首先判断是否栈空,如果栈空,抛出“下溢”信息,无法出栈,否则转入Step2;
if(top==-1) throw "栈空,栈顶无元素";
Step2:取出栈顶元素,返回栈顶元素;
return base[top];
(5) 判断栈空:判断是否栈空,返回
Step1:如果栈空,返回1,否则转Step2;
if(top==-1)
return 1;
Step2:否则返回0 7、
return 0;
(6) 清空栈:将栈清空。
top=-1
(7) 返回栈顶指针:
cout<<"栈顶top= "< 8、表达式中操作符优先级进行排序,优先级从高到低依次为(,),*,/,+,-,算法如下,利用选择语句比较:
char Precede(char t1,char t2)
{//运算符的优先级比较
char f;
switch(t2)
{
case '+':
case '-':if(t1=='('||t1=='=')
f='<';
else
f='>';
break;
case '*':
ca 9、se '/':if(t1=='*'||t1=='/'||t1==')')
f='>';
else
f='<';
break;
case '(':if(t1==')')
{
cout<<"ERROR1"< 10、 break;
case ')':switch(t1)
{
case '(':f='=';
break;
case '=':cout<<"ERROR2"< 11、itch(t1)
{
case '=':f='=';
break;
case '(':cout<<"ERROR2"< 12、In(char c)
{ // 判断c是否为运算符
switch(c)
{
case'+':
case'-':
case'*':
case'/':
case'(':
case')':
case'=':return 1;
default:return 0;
}
}
(3) 构造表达式的运算算法,利用选择语句将运算分类:
float Operate(float a,char theta,float b)
{//实施一次运算
float c;
13、switch(theta)
{
case'+':c=a+b;
break;
case'-':c=a-b;
break;
case'*':c=a*b;
break;
case'/':c=a/b;
}
return c;
}
(4) 要求一:中缀表达式求值
Step1:首先需要将运算符和运算数分开存放,这就需要分别创建栈:
SqStack 14、相关字符来存放由键盘输入的字符,并以“=”键结束
char theta;
float a,b,d;
char c,x; // 存放由键盘接收的字符
char z[6]; // 存放符点数字符串
int i;
OP.Push('=');
Step3:当输入为数字元素是,直接存入表达式栈就可以,而当输入是符号元素时,就需要判断优先级并进行存栈出栈操作,如果是非法字符,输出错误,并且不存入;
c=*exp++;
x=OP.GetTop();
while(c!='='||x!='=')
{
15、if(In(c)) // 是7种运算符之一
switch(Precede(x,c))
{
case'<':OP.Push(c); // 栈顶元素优先权低
c=*exp++;
break;
case'=':x=OP.Pop(); // 脱括号并接收下一字符
c=*exp++;
break;
case'>':theta=OP.Pop(); // 退栈并将运算结果入栈 16、
b=OD.Pop();
a=OD.Pop();
OD.Push(Operate(a,theta,b));
}
else if(c>='0'&&c<='9'||c=='.') // c是操作数
{
i=0;
do
{
z[i]=c;
i++;
c=*exp++;
}while(c>='0'&&c<='9'||c=='.');
17、
z[i]='\0';
d=atof(z); // 将字符串数组转为符点型存于d
OD.Push(d);
}
else // c是非法字符
{
cout<<"ERROR3"< 18、qStack 19、它比较:
2.2.1:A1 20、
break;
case'=':x=OP.Pop(); // 脱括号并接收下一字符
c=*exp++;
break;
case'>':postexp[i++]=OP.Pop(); // 运算符出栈输出
break;
}
}
postexp[i]='\0';
(4)中缀表达式转换成前缀表达式:
Step1:创建一个操作符栈;






