诸如1+2*(3-4)+5的简单表达式
运算符在操作数之间,称为中缀表达式,中缀表达式具有不同的优先级,求值过程无法从左到右进行。
可把中缀表达式转换为后缀表达式计算。
算法如下:
1.设置一个运算符栈,从左到右对每个字符进行处理。
2.遇到左括号 ' '(直接入栈
3.遇到数字,原样输出。
4.遇到运算符,如果栈顶元素的优先级低,则入栈,否则出栈,直到栈顶元素优先级低,入栈。
5.遇到右括号")",运算符出栈,直到出栈运算符为左括号,表示一对括号匹配。
6.重复以上步骤,直到表达式结束,将栈中元素全部出栈。
1+2*(3-4)+5 ======> 1@2@3@4-*+5+ 数字之间用@字符隔开
char*& toPosfix(char* str)//函数功能 中缀转后缀
{ //1+2*(3-4)+5
//1@2@3@4-*+5+
stack<char> sc;
int i=0;
int j=0;
char* pos = new char [2*strlen(str)];
while(str[i]!='\0')
{
if(str[i]>='0'&&str[i]<='9')
pos[j++]=str[i++];
switch(str[i])
{
case '+':
case '-':if(sc.size()==0||sc.top()=='(')
{
sc.push(str[i++]);
pos[j++]='@';
break;
}
while(sc.size()!=0&&sc.top()!='(')
{
pos[j++]=sc.top();
sc.pop();
}
sc.push(str[i++]);
break;
case '*':
case '/':if(sc.size()==0||sc.top()=='('||sc.top()=='+'||sc.top()=='-')
{
sc.push(str[i++]);
pos[j++]='@';break;
}
while((sc.size()!=0)&&(sc.top()=='*'||sc.top()=='/'))//注意短路效应
{ //sc.size()==0,sc.top()错误
pos[j++]=sc.top();
sc.pop();
}
sc.push(str[i++]);
break;
case '(':sc.push(str[i++]);break;
case ')':while(sc.top()!='(')
{
pos[j++]=sc.top();
sc.pop();
}
sc.pop();i++;break;
default: break;
}
}
while(sc.size()!=0)
{
pos[j++]=sc.top();
sc.pop();
}
pos[j]='\0';
return pos;
}
后缀表达式求值
算法如下:
从左到右对后缀表达式进行处理,每次处理一个字符。
遇到数字,转为整数,入栈
遇到运算符,出栈两个值进行运算,运算结果继续入栈。
重复以上步骤。
int value(char* p)
{
int i=0;
int res=0;
int flag=0;
stack<int> si;
while(p[i]!='\0')
{
while(p[i]>='0'&&p[i]<='9')
{
res=res*10+p[i]-'0';
i++;
flag=1;
}
if(p[i]=='@')
{
si.push(res);
res=0;
i++;
flag=0;
}
else
{
if(flag==1)
{
si.push(res);
}
switch(p[i++])
{
case '+':res=si.top();si.pop();res=si.top()+res;si.pop();si.push(res);res=0;flag=0;break;
case '-':res=si.top();si.pop();res=si.top()-res;si.pop();si.push(res);res=0;flag=0;break;
case '*':res=si.top();si.pop();res=si.top()*res;si.pop();si.push(res);res=0;flag=0;break;
case '/':res=si.top();si.pop();res=si.top()/res;si.pop();si.push(res);res=0;flag=0;break;
default: break;
}
}
}
return si.top();
}