一个四则运算表达式该如何求值,比如
(2+1)*(2+3)+2*6
这里只考虑+-*/()的形式
先把四则运算符(中缀表达式)转换成后缀表达式,再利用栈对后缀表达式进行处理;
关键是如何将中缀表达式转换成后缀表达式,规则如下:
(1)如果当前字符是数字,直接输出到后缀表达式
(2)如果是‘(’,压栈
(3)如果是‘)’,将栈中从‘(’到栈顶的元素全部退栈,并输出到后缀表达式,栈中的‘(’退栈即可不需要输出到后缀表达式
(4)如果当前元素的优先级小于栈顶元素的优先级,本着优先级越大距离数字越近的原则,将栈顶元素依次退栈,输出到后缀表达式,直到当前元素的优先级大于等于栈顶元素的优先级
(4)其他情况,直接入栈
当所有字符处理完毕后,依次将栈内元素退栈到后缀表达式中
代码如下:
#include<iostream>
#include <stack>
using namespace std;
int priority(char c);
bool calculate(char *pStr,int &nRes);
void convert(const char *pStrSrc,char *pStrObj);
int main()
{
char *pStr="(2+1)*(2+3)+2*6";
char pStrObj[30];
memset(pStrObj,0,30);
convert(pStr,pStrObj);
int nRes;
if(calculate(pStrObj,nRes))
{
cout<<nRes<<endl;
}
getchar();
return 0;
}
void convert(const char *pStrSrc,char *pStrObj)
{
if (pStrSrc==NULL||pStrObj==NULL)
{
return;
}
int nLen=strlen(pStrSrc);
int objIndex=0;
stack<char> StackTemp;
for (int i=0;i<nLen;i++)
{
if (pStrSrc[i]<='9'&&pStrSrc[i]>='0')
{
pStrObj[objIndex++]=pStrSrc[i];
}
else if (StackTemp.empty())
{
StackTemp.push(pStrSrc[i]);
}
else if (pStrSrc[i]=='(')
{
StackTemp.push(pStrSrc[i]);
}
else if (pStrSrc[i]==')')
{
while(!StackTemp.empty()&&StackTemp.top()!='(')
{
char cTemp=StackTemp.top();
StackTemp.pop();
pStrObj[objIndex++]=cTemp;
}
if (!StackTemp.empty())
{
StackTemp.pop();
}
}//优先级越高,离数据越近
else if (priority(pStrSrc[i])<priority(StackTemp.top()))
{
while(!StackTemp.empty()&&priority(StackTemp.top())>priority(pStrSrc[i]))
{
pStrObj[objIndex++]=StackTemp.top();
StackTemp.pop();
}
StackTemp.push(pStrSrc[i]);
}
else
{
StackTemp.push(pStrSrc[i]);
}
}
while(!StackTemp.empty())
{
pStrObj[objIndex++]=StackTemp.top();
StackTemp.pop();
}
for (int i=0;i<objIndex;i++)
{
cout<<pStrObj[i];
}
cout<<endl;
}
bool calculate(char *pStr,int &nRes)
{
int nLen=strlen(pStr);
if (pStr==NULL||nLen==0)
{
return false;
}
stack<char> ss;
ss.push(pStr[0]);
for (int i=1;i<nLen;i++)
{
if (pStr[i]<='9'&&pStr[i]>='0')
{
ss.push(pStr[i]);
}
else
{
if (pStr[i]=='+')
{
int nTemp2=ss.top()-'0';
ss.pop();
int nTemp1=ss.top()-'0';
ss.pop();
ss.push(nTemp1+nTemp2+'0');
}
else if (pStr[i]=='-')
{
int nTemp2=ss.top()-'0';
ss.pop();
int nTemp1=ss.top()-'0';
ss.pop();
ss.push(nTemp1-nTemp2+'0');
}
else if (pStr[i]=='*')
{
int nTemp2=ss.top()-'0';
ss.pop();
int nTemp1=ss.top()-'0';
ss.pop();
ss.push(nTemp1*nTemp2+'0');
}
else if (pStr[i]=='/')
{
int nTemp2=ss.top()-'0';
ss.pop();
if (nTemp2==0)
{
return false;
}
int nTemp1=ss.top()-'0';
ss.pop();
ss.push(nTemp1/nTemp2+'0');
}
}
}
nRes=ss.top()-'0';
return true;
}
int priority(char c)
{
if (c=='+')
{
return 0;
}
else if(c=='-')
{
return 0;
}
else if (c=='*')
{
return 1;
}
else if(c=='/')
{
return 1;
}
else
return -1;
}