算法:中缀表达式转后缀表达式(想看全部代码直接翻到底部)
众所周知,在编程里面,直接用中缀表达式求值是不方便的,so咱们将中缀转化为后缀再求值。
平时咱们使用的表达式为中缀表达式:
如:a+b*(c-d);
运算符本身具有优先级,存在括号优先级,编程时考虑的情况多样,代码也不简洁。
So咱们推出一个后缀表达式:
如上面表达式转换成后缀abcd-*+;
只存在操作符和运算符。
中缀转后缀方法(采用栈来实现):
咱们会发现,数字如果是两位的话,与运算符不太好隔离。这就有二种解决办法:
1.直接定义一个结构体栈,里面含数组和字符数组,咱们可间字符数组里将表示数字的字符定义成‘0’字符以便判断。
如19+2+5;它的字符数组可以为0+0+0。
2.就是直接定义两个数组,一个是存数字一个是存字符。
string a;
queue<int> s2;
cin>>a;
int t[50]= {0};
char ch[50];
int c=a.length();
int i=0,j=0,k=0;
for(i=0;i<c;i++)
{
ch[i]='0';
}
//分为两个数组
for(i=0; i<c; i++)
{
if(a[i]>='0'&&a[i]<='9')
{
t[j]=t[j]*10+(a[i]-'0');
if(a[i+1]<'0'||a[i+1]>'9')
{
j++;
}
}
else
{
ch[j]=a[i];
j++;
}
}
分隔解决了,然后是中缀转后缀(按照上述图片步骤)
stack<int> s;//临时存符号栈
int i,j,f;
int m,n;//比较优先级
int n1=a.length();
for(i=0; i<n1; i++)
{
if(ch[i]=='0')
{
s2.push(i);
}
else if(ch[i]!='0'&&s.empty()==1&&ch[i]!='(')
{
s.push(i);
}
else if(ch[i]=='(')
{
s.push(i);
//适用()里只有一个算术符号
while(ch[i]!=')')
{
i++;
if(ch[i]=='0')
{
s2.push(i);
}
else if(ch[i]!='0')
{
s.push(i);
}
}
s.pop();//')'出栈
int f=s.top();//临时顶部符号下标
while(ch[f]!='(')
{
s2.push(f);
s.pop();
f=s.top();
}
s.pop();
}
else if(s.empty()==0&&ch[i]!='0')
{
f=s.top();
m=getpriority(ch[f]);
n=getpriority(ch[i]);
while(m>=n&&s.empty()!=1)//注意s栈要不为空
{
s2.push(f);
s.pop();
//栈不为空的时候取顶
if(s.empty()!=1)
{
f=s.top();
m=getpriority(ch[f]);
}
}
s.push(i);
}
}
while(s.empty()==0)
{
f=s.top();
s2.push(f);
s.pop();
}
后缀求值:
1.将已经完成的后缀表达式队列出列一个,进入新栈。
2.依次出列进栈,遇到运算符,栈顶的两位出栈运算,运算顺序:第二位出栈+运算符+第一位出栈。运算结果入栈。
3.直到队列为空,栈里只有一个元素,取栈顶输出结果。
代码:
stack<int> s;//后缀表达式在此栈里计算
int index=s2.front();
int sm,i,j;
s.push(t[index]);
//栈中一个元素入另一个栈,一进一删
s2.pop();
while(s.empty()!=1)
{
index=s2.front();
s2.pop();
if(ch[index]=='0')
{
s.push(t[index]);
}
else
{
if(ch[index]=='+')
{
i=s.top();
s.pop();
j=s.top();
s.pop();
sm=i+j;
s.push(sm);
}
else if(ch[index]=='-')
{
i=s.top();
s.pop();
j=s.top();
s.pop();
sm=j-i;
s.push(sm);
}
else if(ch[index]=='/')
{
i=s.top();
s.pop();
j=s.top();
s.pop();
sm=j/i;
s.push(sm);
}
else if(ch[index]=='*')
{
i=s.top();
s.pop();
j=s.top();
s.pop();
sm=j*i;
s.push(sm);
}
}
if(s2.empty()==1)
{
cout<<s.top()<<endl;
s.pop();
}
}`
全部代码:
#include <iostream>
#include<stack>
#include<queue>
using namespace std;
int getpriority(char v)
{
switch(v)
{
case'+':
case'-':
return 1;
case'*':
case'/':
return 2;
default:
return 0;
}
}
/*中缀转后缀*/
void inturnafter(string a,int t[],char ch[],queue<int> &s2)
{
stack<int> s;//临时存符号栈
int i,j,f;
int m,n;//比较优先级
int n1=a.length();
for(i=0; i<n1; i++)
{
if(ch[i]=='0')
{
s2.push(i);
}
else if(ch[i]!='0'&&s.empty()==1&&ch[i]!='(')
{
s.push(i);
}
else if(ch[i]=='(')
{
s.push(i);
//适用()里只有一个算术符号
while(ch[i]!=')')
{
i++;
if(ch[i]=='0')
{
s2.push(i);
}
else if(ch[i]!='0')
{
s.push(i);
}
}
s.pop();//')'出栈
int f=s.top();//临时顶部符号下标
while(ch[f]!='(')
{
s2.push(f);
s.pop();
f=s.top();
}
s.pop();
}
else if(s.empty()==0&&ch[i]!='0')
{
f=s.top();
m=getpriority(ch[f]);
n=getpriority(ch[i]);
while(m>=n&&s.empty()!=1)//注意s栈要不为空
{
s2.push(f);
s.pop();
//栈不为空的时候取顶
if(s.empty()!=1)
{
f=s.top();
m=getpriority(ch[f]);
}
}
s.push(i);
}
}
while(s.empty()==0)
{
f=s.top();
s2.push(f);
s.pop();
}
}
/*后缀计算*/
void getvalue(queue<int> s2,int t[],char ch[])
{
stack<int> s;//后缀表达式在此栈里计算
int index=s2.front();
int sm,i,j;
s.push(t[index]);
//栈中一个元素入另一个栈,一进一删
s2.pop();
while(s.empty()!=1)
{
index=s2.front();
s2.pop();
if(ch[index]=='0')
{
s.push(t[index]);
}
else
{
if(ch[index]=='+')
{
i=s.top();
s.pop();
j=s.top();
s.pop();
sm=i+j;
s.push(sm);
}
else if(ch[index]=='-')
{
i=s.top();
s.pop();
j=s.top();
s.pop();
sm=j-i;
s.push(sm);
}
else if(ch[index]=='/')
{
i=s.top();
s.pop();
j=s.top();
s.pop();
sm=j/i;
s.push(sm);
}
else if(ch[index]=='*')
{
i=s.top();
s.pop();
j=s.top();
s.pop();
sm=j*i;
s.push(sm);
}
}
if(s2.empty()==1)
{
cout<<s.top()<<endl;
s.pop();
}
}
}
int main()
{
string a;
queue<int> s2;
cin>>a;
int t[50]= {0};
char ch[50];
int c=a.length();
int i=0,j=0,k=0;
for(i=0;i<c;i++)
{
ch[i]='0';
}
//分为两个数组
for(i=0; i<c; i++)
{
if(a[i]>='0'&&a[i]<='9')
{
t[j]=t[j]*10+(a[i]-'0');
if(a[i+1]<'0'||a[i+1]>'9')
{
j++;
}
}
else
{
ch[j]=a[i];
j++;
}
}
inturnafter(a,t,ch,s2);
getvalue(s2,t,ch);
return 0;
}