中缀转后缀
1.维护一个符号栈
2.对于数字,直接加入结果ans
3.对于左括号,直到遇到右括号,把括号中间的数字全部添加到结果ans
4.大于栈顶元素则push,小于则pop。(大进小出)
5.弹出栈中其他符号
由于没有对数字相连进行处理,只能处理单个数组的情况
int pr(char o)//传入操作符,返回优先级
{
int pri[10]={0,0,1,1,2,2,3};//priority
char op[10]={'#','(','+','-','*','/','^'};
for(int i=0;i<6;i++)
if(op[i]==o)return pri[i];
}
string infix_to_postfix(string in)//中缀转后缀
{
string ans="";
stack<char>s;
s.push('#');//作栈底使用
for(int i=0;i<in.length();i++){//处理表达式
if(in[i]>='0'&&in[i]<='9')ans+=in[i];//处理数字
else if(in[i]=='(')s.push(in[i]);//处理括号
else if(in[i]==')'){
while(s.top()!='(')ans+=s.top(),s.pop();
s.pop();//左括号
}
else{//处理操作符
if(pr(in[i])>pr(s.top()))s.push(in[i]);
else{
while(pr(in[i])<=pr(s.top()))ans+=s.top(),s.pop();
s.push(in[i]);
}
}
}
while(s.top()!='#')ans+=s.top(),s.pop();
return ans;
}
测试样例:
8-(3+2*6)/5+4
输出结果:
8326*+5/-4+
后缀表达式求值
由于没有对数字相连进行处理,只能处理单个数组的情况
遇到符号,则把栈顶元素和次栈顶元素拿出去运算即可。由于进栈导致顺序倒置,所以是
运算规则 : 次栈顶元素 操作符 栈顶元素
int calc(int num_a,char o,int num_b)
{
switch(o){
case '+':return num_a+num_b;
case '-':return num_a-num_b;
case '*':return num_a*num_b;
case '/':return num_a/num_b;
case '^':return pow(num_a,numb_b);
}
}
int calc_postfix(string in)
{
stack<int>s;
for(int i=0;i<in.length();i++){
if(in[i]>='0'&&in[i]<='9')s.push(in[i]-'0');
else {
int b = s.top();s.pop();
int a = s.top();s.pop();
s.push(calc(a,in[i],b));
}
}
return s.top();
}
单位数的中缀求值
把前面两个步骤合并起来
#include<bits/stdc++.h>
using namespace std;
string str;
int pr(char o)//传入操作符,返回优先级
{
int pri[10]={0,1,1,2,2,3};//priority
char op[10]={'#','+','-','*','/'};
for(int i=0;i<6;i++)
if(op[i]==o)return pri[i];
}
string infix_to_postfix(string in)//中缀转后缀
{
string ans="";
stack<char>s;
s.push('#');//作栈底使用
for(int i=0;i<in.length();i++){//处理表达式
if(in[i]>='0'&&in[i]<='9')ans+=in[i];//处理数字
else if(in[i]=='(')s.push(in[i]);//处理括号
else if(in[i]==')'){
while(s.top()!='(')ans+=s.top(),s.pop();
s.pop();//左括号
}
else{//处理操作符
if(pr(in[i])>pr(s.top()))s.push(in[i]);
else{
while(pr(in[i])<=pr(s.top()))ans+=s.top(),s.pop();
s.push(in[i]);
}
}
}
while(s.top()!='#')ans+=s.top(),s.pop();
return ans;
}
int calc(int num_a,char o,int num_b)
{
switch(o){
case '+':return num_a+num_b;
case '-':return num_a-num_b;
case '*':return num_a*num_b;
case '/':return num_a/num_b;
}
}
int calc_postfix(string in)
{
stack<int>s;
for(int i=0;i<in.length();i++){
if(in[i]>='0'&&in[i]<='9')s.push(in[i]-'0');
else {
int b = s.top();s.pop();
int a = s.top();s.pop();
s.push(calc(a,in[i],b));
}
}
return s.top();
}
int main()
{
cin>>str;
cout<<calc_postfix(infix_to_postfix(str))<<endl;
return 0;
}
表达式中多位数处理
思路:对读入的中缀表达式进行预处理,将数字分开。计算时以@作为分割符来读取数。
#include<bits/stdc++.h>
using namespace std;
string str;
int pr(char o)//传入操作符,返回优先级
{
int pri[10]={0,0,1,1,2,2,3};//priority
char op[10]={'#','(','+','-','*','/','^'};
for(int i=0;i<6;i++)
if(op[i]==o)return pri[i];
}
int is_op(char o)//判断是否为符号
{
if(o>='0'&&o<='9')return 0;
return 1;
}
string exp_deal(string in)//对表达式进行处理,防止数字相连,这里以@分隔
{
string deal="";
for(int i=0;i<in.length();i++){
deal+=in[i];
if(in[i]>='0'&&in[i]<='9'&&is_op(in[i+1]))deal+='@';
}
return deal;
}
string infix_to_postfix(string in)//中缀转后缀
{
in=exp_deal(in);//对多位数字进行处理
string ans="";
stack<char>s;
s.push('#');//作栈底使用
for(int i=0;i<in.length();i++){//处理表达式
if(in[i]>='0'&&in[i]<='9'||in[i]=='@')ans+=in[i];//处理数字
else if(in[i]=='(')s.push(in[i]);//处理括号
else if(in[i]==')'){
while(s.top()!='(')ans+=s.top(),s.pop();
s.pop();//左括号
}
else{//处理操作符
if(pr(in[i])>pr(s.top()))s.push(in[i]);
else{
while(pr(in[i])<=pr(s.top()))ans+=s.top(),s.pop();
s.push(in[i]);
}
}
}
while(s.top()!='#')ans+=s.top(),s.pop();
return ans;
}
int calc(int num_a,char o,int num_b)
{
switch(o){
case '+':return num_a+num_b;
case '-':return num_a-num_b;
case '*':return num_a*num_b;
case '/':return num_a/num_b;
case '^':return (int)pow(num_a,num_b);
}
}
int calc_postfix(string in)
{
stack<int>s;
int num=0;
for(int i=0;i<in.length();i++){
if(in[i]>='0'&&in[i]<='9')
num = num*10+(in[i]-'0');
else if(in[i]=='@')
s.push(num),num=0;
else {
int b = s.top();s.pop();
int a = s.top();s.pop();
s.push(calc(a,in[i],b));
}
}
return s.top();
}
int main()
{
cin>>str;
cout<<calc_postfix(infix_to_postfix(str))<<endl;
return 0;
}
版权声明:本文为weixin_43615816原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。