目录
中缀表达式求值
算法思想:把数字和操作符分别放在栈中,遇到操作符时,与栈顶操作符的优先级比较,如果优先级比栈顶的低就进行运算。
#include<stack>
#include<stdlib.h>
#include<iostream>
#include<ctype.h>
#include<string.h>
using namespace std;
int pre(char c)//优先级判断
{
if(c=='=') return 0;
else if(c=='+'||c=='-')
return 1;
else if(c=='*'||c=='/')
return 2;
else return 0;
}
void calculate(stack<double> &num,stack<char> &op)//运算
{
double b=num.top();
num.pop();
double a=num.top();
num.pop();
switch(op.top())
{
case '+':
num.push(a+b);
break;
case '-':
num.push(a-b);
break;
case '*':
num.push(a*b);
break;
case '/':
if(b==0)throw"错误:除数为0";
else
{
num.push(a/b);
break;
}
}
op.pop();
}
int main()
{
try
{
stack<double> num;//存储数字
stack<char> op;//存储操作符
string s;
cin>>s;//读取整个字符串
for(int i=0; s[i]!='\0'; i++)
{
if(isdigit(s[i]))//判断是否为数字
{
double temp=atof(&s[i]);//转化为浮点数
num.push(temp);//入栈
while(isdigit(s[i])||s[i]=='.')//寻找下一个操作符
i++;
i--;//由于有外层循环,往前挪一位
}
else if(s[i]=='+'||s[i]=='-'||s[i]=='*'||s[i]=='/'||s[i]=='('||s[i]==')'||s[i]=='=')//字符是操作符
{
if(s[i]=='(')
op.push(s[i]);
else if(s[i]==')')
{
while(op.top()!='(')//计算括号内的式子
calculate(num,op);
op.pop();//左括号出栈
}
else if(op.empty()||pre(s[i])>pre(op.top()))//优先级大于栈顶,或栈为空时,直接进栈
op.push(s[i]);
else if(!op.empty()&&pre(s[i])<=pre(op.top()))//是优先级不大于栈顶的操作符,且栈不空,先进行运算操作
{
while(!op.empty()&&pre(s[i])<=pre(op.top()))
calculate(num,op);
op.push(s[i]);//将优先级大于它的操作做完再让它进栈
}
}
else throw"错误:输入不符合规范";
}
printf("%.2lf\n",num.top());//输出结果
num.pop();
op.pop();//清空栈
}
catch(const char *mess)
{
cout<<mess<<endl ;
}
return 0;
}
输入: 0.6*(10.6-1.9/2)+5.6=
输出:11.39
中缀表达式转化为二叉树
采用中缀表达式求值的算法思想,只是操作数栈中用存储指向结点的指针来代替存储操作数。采用中缀表达式求值的算法思想,只是操作数栈中用存储指向结点的指针来代替存储操作数。
此处为了方便操作,用字母代替数字,并默认表达式无错误
#include<stack>
#include<stdlib.h>
#include<iostream>
#include<string.h>
using namespace std;
class treenode
{
public:
treenode *left;
treenode *right;
string data;
};
class tree
{
public:
treenode *root; //根节点
tree(treenode *x); //以一个节点为根节点构造书
~tree() {}; //析构函数
void print(); //输出树
void preorder(const treenode *treeroot); //先序遍历
void inorder(const treenode *treeroot); //中序遍历
};
tree::tree(treenode *x)
{
root=x;
}
void tree::preorder(const treenode *treeroot) //先序遍历
{
if(treeroot!=NULL&&!treeroot->data.empty())
{
cout<<treeroot->data<<' ';
preorder(treeroot->left);
preorder(treeroot->right);
}
}
void tree::inorder(const treenode *treeroot) //中序遍历
{
if(treeroot!=NULL)
{
inorder(treeroot->left);
cout<<treeroot->data<<' ';
inorder(treeroot->right);
}
}
void tree::print() //输出树
{
cout<<"先序:";
preorder(root);
cout<<endl<<"中序:";
inorder(root);
}
int pre(char c)//优先级判断
{
if(c=='=') return 0;
else if(c=='+'||c=='-')
return 1;
else if(c=='*'||c=='/')
return 2;
else return 0;
}
void calculate(stack<treenode*> &num,stack<char> &op)//运算
{
treenode * b=new treenode; //创建新节点,且储存字母1
b = num.top();
num.pop();
treenode * a=new treenode; //创建新节点,且储存字母2
a=num.top();
num.pop();
treenode *cur=new treenode; //创建新节点,且储存操作符
cur->left=a;
cur->right=b;
cur->data=op.top();
num.push(cur); //新的子树压入栈中
op.pop();
}
int main()
{
stack<treenode*> num;//存储节点
stack<char> op;//存储操作符
char s;
while((s=getchar())!='\n')
{
if(s>='a'&&s<='z')//判断是否为字母
{
treenode *p=new treenode;
p->data=s;
p->left=NULL;
p->right=NULL;
num.push(p);//入栈
}
else if(s=='+'||s=='-'||s=='*'||s=='/'||s=='('||s==')'||s=='=')//字符是操作符
{
if(s=='(')
op.push(s);
else if(s==')')
{
while(op.top()!='(')//计算括号内的式子,生成新的子树
calculate(num,op);
op.pop();//左括号出栈
}
else if(op.empty()||pre(s)>pre(op.top()))//优先级大于栈顶,或栈为空时,直接进栈
op.push(s);
else if(!op.empty()&&pre(s)<=pre(op.top()))//是优先级不大于栈顶的操作符,且栈不空,先进行运算操作,生成新的子树
{
while(!op.empty()&&pre(s)<=pre(op.top()))
calculate(num,op);
op.push(s);//将优先级大于它的操作做完再让它进栈
}
}
}
tree x(num.top()); //以当前节点为根节点产生二叉树
x.print(); //显示二叉树
op.pop();//清空栈
return 0;
}
输入:a*(b+c)-d/e=
输出:先序:- * a + b c / d e
中序:a * b + c - d / e