表达式的转换:
1.中缀表达式转前缀表达式或者后缀表达式
- 1.1 中缀转后缀
利用两个栈即可从中缀符号串转换得到后缀符号串
- 1.2 中缀转前缀
中缀先转后缀,然后构造表达式树,得到表达式树根节点后,前序、后序遍历即可得到前缀,后缀表达式
2.后缀表达式转中缀表达式或者前缀表达式
最简单,直接构造表达式二叉树,得到表达式树根节点,然后中序遍历和前序遍历即可
3.前缀表达式转中缀表达式或者后缀表达式
最简单,直接构造表达式二叉树,得到表达式树根节点,然后中序遍历和后序遍历即可
准备工作:
- 定义表达式树结点类型
typedef struct BTNode{...}BTNode
- 1.中缀表达式转前缀表达式或者后缀表达式
stack<char> k1,k2//初始化一个操作数栈,一个操作符栈
- 2.后缀表达式转中缀表达式或者前缀表达式
stack<char> k3//初始化一个操作数栈
- 3.前缀表达式转中缀表达式或者后缀表达式
stack<char> k4//初始化一个操作数栈
接口声明:
- 1.中缀表达式转前缀表达式或者后缀表达式
int priority(char x)//返回运算符优先级大小,返回格式是int数字
string intopost(string in)//中缀转后缀
- 2.后缀表达式转中缀表达式或者前缀表达式
BTNode *posttree(string post)//后缀生成二叉树
- 3.前缀表达式转中缀表达式或者后缀表达式
BTNode *pretree(string post)//前缀生成二叉树
- 4.遍历函数
void preorder(BTNode *head);
void inorder(BTNode *head);
void postorder(BTNode *head);
算法核心:
- 1.中缀表达式转后缀
从左到右扫描
- 操作符在以下情况时入操作符栈
- 操作符栈为空
- 栈顶为(
- 优先级大于栈顶
- 优先级小于栈顶时,把运算符栈顶元素弹到操作数栈直到能入栈为止
- 若遇到(,直接入操作符栈
- 若遇到),把(与)内的所有元素都弹到操作数栈中,(与)舍去
- 若遇到操作数,直接进入操作数栈中
最后把操作符内元素全部压入操作数栈
- 操作数栈内元素全部出栈后逆序输出
2.后缀表达式生成表达式树
从左到右扫描,遇到操作数进入操作数栈,
遇到操作符,操作数栈先后弹出两个操作数n1,n2
n2连到操作符结点的左子树,n1连到操作符结点的右子树,操作符再进栈
最后操作数栈中只有一个操作符,弹出即可得到根节点
3.前缀表达式生成表达式树
从右到左扫描,遇到操作数进入操作数栈,
遇到操作符,操作数栈先后弹出两个操作数n1,n2
n1连到操作符结点的左子树,n2连到操作符结点的右子树,操作符再进栈
最后操作数栈中只有一个操作符,弹出即可得到根节点
#include
表达式的计算:
- 中缀表达式:先构造表达式树,然后后序遍历生成后缀表达式,再计算
- 前缀表达式:直接运算
- 后缀表达式:直接运算
运算整体思路和前缀表达式构造表达式树,后缀表达式构造表达式树一样的
- 后缀表达式运算
从左到右扫描,遇到操作数进入操作数栈,
遇到操作符,操作数栈先后弹出两个操作数n1,n2
n2 Op n1 得到结果再进栈
最后操作数栈中只有一个结果,弹出即可得到表达式的值
- 前缀表达式运算
从右到左扫描,遇到操作数进入操作数栈,
遇到操作符,操作数栈先后弹出两个操作数n1,n2
n1 Op n2 得到结果再进栈
最后操作数栈中只有一个结果,弹出即可得到表达式的值
接口声明:
- 1.操作数栈
stack<double> k;
- 2.运算函数
double op(double a,double b,char op);
- 3.后缀表达式运算
double postcalculate(string post);
- 4.前缀表达式运算
double precalculate(string post);
stack<double> k;
double op(double a,double b,char op);
double postcalculate(string post);
double precalculate(string pre);
double op(double a,double b,char op)
{
double result;
switch(op)
{
case '*':result=(a*b);break;
case '/':result=(a/b);break;
case '+':result=(a+b);break;
case '-':result=(a-b);break;
};
return result;
}
//表达式内的数字只能为0-9的整形
double postcalculate(string post)
{
int i;
double n1,n2;
double n3,num;
for(i=0;i<post.length();i++)
{
if(post[i]=='*'||post[i]=='/'||post[i]=='+'||post[i]=='-')
{
n1=k.top();
k.pop();
n2=k.top();
k.pop();
n3=op(n2,n1,post[i]);
k.push(n3);
}
else
{
num=post[i]-'0';
k.push(num);
}
}
n3=k.top();
k.pop();
return n3;
}
//表达式内的数字只能为0-9的整形
double precalculate(string pre)
{
int i;
double n1,n2;
double n3,num;
for(i=pre.length()-1;i>=0;i--)
{
if(pre[i]=='*'||pre[i]=='/'||pre[i]=='+'||pre[i]=='-')
{
n1=k.top();
k.pop();
n2=k.top();
k.pop();
n3=op(n1,n2,pre[i]);
k.push(n3);
}
else
{
num=pre[i]-'0';
k.push(num);
}
}
n3=k.top();
k.pop();
return n3;
}
int main()
{
string pre="+/236";
cout<<precalculate(pre)<<endl;
return 0;
}