中缀表达式转后缀表达式的算法规则:
先将这个用C/C++实现一下:
#include
#include
#include
#define MaxSize 100
#define ElemType char
typedef struct{
ElemType data[MaxSize];
int top;
}SqStack;
//顺序栈的初始化:
void InitStack(SqStack &S)
{
memset(S.data,'\0',MaxSize);
S.top=-1;
}
//获取栈顶元素(不是出栈操作!!)
bool GetTop(SqStack &S,ElemType &x)
{
if(S.top==-1)return false;
x=S.data[S.top];
return true;
}
//入栈操作:
bool Push(SqStack &S,ElemType x)
{
if(S.top==(MaxSize-1))return false;
S.data[++S.top]=x;
return true;
}
//出栈操作:
bool Pop(SqStack &S,ElemType &x)
{
if(S.top==-1)return false;
x=S.data[S.top--];
return true;
}
//用于判断运算符优先级的高低,优先级高于或等于就返回true,否则为false
bool Priority(char a,char b)
{
if((a=='+'||a=='-')&&(b=='+'||b=='-'||b=='*'||b=='/'))
{
return true;
}
else if((a=='*'||a=='/')&&(b=='*'||b=='/'))
{
return true;
}
return false;
}
//将中缀表达式转化为后缀表达式:
void ChangeToRPN(ElemType str[],int length,ElemType* &str1) //RPN指逆波兰式,也就是后缀表达式
{
int j=0;
str1=(char*)malloc(sizeof(char)*MaxSize); //str1是字符数组,用于存放处理后的后缀表达式
memset(str1,' ',MaxSize);
ElemType topElem;
SqStack S; //定义一个栈
InitStack(S); //初始化栈
for(int i=0;i<length;i++)
{
if(str[i]>='0'&&str[i]<='9') //遇到操作数
{
while(1)
{
str1[j]=str[i];
if(str[i+1]>='0'&&str[i+1]<='9'){
j=j+1;
i++;
}
else{
j=j+2;
break;
}
}
}
else if(str[i]!=')') //遇到运算符或左括号
{
if(str[i]=='(')
{
if(!Push(S,str[i]))printf("Your input is too long!!\n");
continue;
}
else while(GetTop(S,topElem)&&topElem!='('&&Priority(str[i],topElem))
{ //Priority是用于判断运算符优先级的自定义函数
Pop(S,topElem);
str1[j]=topElem;
j=j+2;
}
Push(S,str[i]);
}
else{ //遇到右括号
while(GetTop(S,topElem))
{
Pop(S,topElem);
if(topElem=='(')break;
str1[j]=topElem;
j=j+2;
}
}
}
//将栈中剩下的运算符弹出
while(Pop(S,topElem)){
str1[j]=topElem;
j=j+2;
}
return;
}
int main()
{
char str[50];
char *str1;
memset(str,'\0',50);
printf("\n请输入要转化的中缀表达式:\n");
scanf("%s",str);
ChangeToRPN(str,strlen(str),str1);
printf("\n输出结果:\n");
printf("%s\n",str1);
free(str1);
return 0;
}
接着就是让计算机实现中缀表达式的计算:
在算法思想上,该算法结合了中缀转后缀和后缀表达式求值两:个算法的思想,参考我自己之前的笔记:利用栈实现表达式求值(理论分析)
总的算法思想:
我的代码实现:
//这个算法针对只含有正整数数的表达式计算
#include
#include
#include
#define MaxSize 100
//用于存放运算符的栈的数据类型定义及基本操作:
//数据类型定义
#define ElemType1 char
typedef struct{
ElemType1 data[MaxSize];
int top;
}SqStack1;
//运算符栈的初始化操作:
void InitStack_1(SqStack1 &S)
{
memset(S.data,'\0',MaxSize);
S.top=-1;
}
//取运算符栈的栈顶元素:
bool GetTop_1(SqStack1 &S,ElemType1 &x)
{
if(S.top==-1)return false;
x=S.data[S.top];
return true;
}
//运算符栈入栈操作:
bool Push_1(SqStack1 &S,ElemType1 x)
{
if(S.top==(MaxSize-1))return false;
S.data[++S.top]=x;
return true;
}
//运算符栈出栈操作:
bool Pop_1(SqStack1 &S,ElemType1 &x)
{
if(S.top==-1)return false;
x=S.data[S.top--];
return true;
}
//用于存放操作数的栈的数据类型定义及基本类型操作
//数据类型定义
#define ElemType2 float
typedef struct{
ElemType2 data[MaxSize];
int top;
}SqStack2;
//操作数栈的初始化操作:
void InitStack_2(SqStack2 &S)
{
S.top=-1;
}
//取操作数栈的栈顶元素:
bool GetTop_2(SqStack2 &S,ElemType2 &x)
{
if(S.top==-1)return false;
x=S.data[S.top];
return true;
}
//操作数栈入栈操作:
bool Push_2(SqStack2 &S,ElemType2 x)
{
if(S.top==(MaxSize-1))return false;
S.data[++S.top]=x;
return true;
}
//操作数栈出栈操作:
bool Pop_2(SqStack2 &S,ElemType2 &x)
{
if(S.top==-1)return false;
x=S.data[S.top--];
return true;
}
//用于判断运算符优先级的高低,优先级高于或等于就返回true,否则为false
bool Priority(char a,char b)
{
if((a=='+'||a=='-')&&(b=='+'||b=='-'||b=='*'||b=='/'))
{
return true;
}
else if((a=='*'||a=='/')&&(b=='*'||b=='/'))
{
return true;
}
return false;
}
//用于两个操作数之间的计算
ElemType2 CalculateTwo(ElemType2 n1,ElemType2 n2,ElemType1 t)
{ //n1是右操作数,n2是左操作数
if(t=='+')return n1+n2;
if(t=='-')return n2-n1;
if(t=='/')return n2/n1;
if(t=='*')return n2*n1;
}
//计算中缀表达式的算法:
void Calculate(ElemType1 str[],ElemType2 &e)
{
SqStack1 S1;//S1是运算符栈
SqStack2 S2;//S2是操作数栈
InitStack_1(S1);//初始化S1
InitStack_2(S2);//初始化S2
float n=0;
ElemType2 n1,n2;
ElemType1 t;
for(unsigned int i=0;i<strlen(str);i++)
{
if(str[i]>='0'&&str[i]<='9')
{
while(1){ //这个循环的存在是因为操作数的位数是不确定的
n*=10;
n+=(str[i]-'0');
if(str[i+1]>='0'&&str[i+1]<='9')i++;
else break;
}
Push_2(S2,n);
n=0;
}
else if(str[i]!=')')
{
while(GetTop_1(S1,t)&&t!='('&&Priority(str[i],t))
{
Pop_1(S1,t);
Pop_2(S2,n1); //n1是右操作数
Pop_2(S2,n2); //n2是左操作数
Push_2(S2,CalculateTwo(n1,n2,t));
}
Push_1(S1,str[i]);
}
else
{
while(Pop_1(S1,t))
{
if(t=='(')break;
Pop_2(S2,n1); //n1是右操作数
Pop_2(S2,n2); //n2是左操作数
Push_2(S2,CalculateTwo(n1,n2,t));
}
}
}
while(Pop_1(S1,t)&&Pop_2(S2,n1)&&Pop_2(S2,n2))
{
Push_2(S2,CalculateTwo(n1,n2,t));
}
Pop_2(S2,e);
}
int main()
{
ElemType1 str[MaxSize];
ElemType2 e;
memset(str,'\0',MaxSize);
printf("\n请输入要计算的表达式:\n");
scanf("%s",str);
printf("\n计算并输出结果:\n");
Calculate(str,e);
printf("%f\n",e);
return 0;
}
其中放操作数的栈和放运算符的栈用了两种数据类型定义。