1、将以字符串形式输入的中缀表达式转换成后缀表达式
- 初始化一个空栈用于存储操作符
对于中缀表达式从左向右遍历,每得到一个字符,进行判断
a、如果是数字,则直接加入到后缀表达式中,同时判断下一个
字符是也是数字,如果是,也加入到后缀表达式中,如此循
环判断,将连续的数字字符一并识别存储。b、如果是左括号,则把左括号入操作符栈。
c、如果是右括号,则从操作符栈中把符号出栈加入后缀表达
式中,直到遇到左括号停止并将左括号出栈。d、如果是操作符,首先判断操作符栈是否为空,如果为空,直接
入栈,如果为左操作符,也直接入栈。如果非空,将该操作符
与操作符栈的栈顶元素进行优先级比较,若当前操作符优先级
大于栈顶优先级,那么当前操作符入栈,否则,栈顶操作符
出栈加入到后缀表达式中(此处当前操作符不需要入栈),重复
d步骤,直到当前操作符入栈(也就是说要保证栈顶操作符优
先级最高)。- 当中缀表达式搜索完毕后,检查操作符栈是否为空,如果非空,
那么将其中的操作符添加到后缀表达式中。
(同时注意,在转换的时候,每添加一个数字串、操作符到后缀表达式中的时候,在前面先添加一个空格,使得连续存储的数字不会连在一起,方便后面的后缀表达式计算)
2、计算后缀表达式
- 定义一个存储操作数的操作数栈。
- 从左向右遍历后缀表达式
a、如果是空格,则跳过
b、如果是数字,将其转换为整型,循环判断下一个字符是否为
数字,转换成相应的多位整型数字形式,并将该整型数如操
作数栈。
c、如果是操作符,则从操作数栈中把栈顶的两个操作数出栈,
判断操作符类型,并进行相应计算,然后将计算得到的结果
重新入栈。 - 最后将操作数栈中的栈顶元素作为最终结果输出。
#include <iostream>
#include <Stack>
#include <string>
#include <cctype>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <cstring>
using namespace std;
string inTopostExp(string exp); //
int prior(char c); //judge the priority of the operator
int computepostExp(string postExp);
int Auxcal(int a,int b,char ch);
int main()
{
string inexp,posexp;
for(;;)
{
cout<<"input a infix expression:(input exit to quit)";
getline(cin,inexp);
if(inexp=="exit")
break;
posexp=inTopostExp(inexp);
cout<<"the reference postfix expression is:"<<posexp<<endl;
cout<<"the compute result is:"<<computepostExp(posexp)<<endl;
}
return 1;
}
int Auxcal(int a,int b,char ch)
{
switch(ch)
{
case'+':return a+b;
case'-':return a-b;
case'*':return a*b;
case'/':return a/b;
}
}
int computepostExp(string postExp)
{
char curch;
int num1,num2;
stack<int> numStack;
for(int i=0;i<postExp.length();i++)
{
curch=postExp[i];
if(postExp[i]==32)
{
continue;
}
else if(postExp[i]<'9'&&postExp[i]>'0')
{
int tmpnum=int(postExp[i])-'0';
while(postExp[i+1]<'9'&& postExp[i+1]>'0')
{
tmpnum=tmpnum*10+int(postExp[i+1])-'0';
i++;
}
numStack.push(tmpnum);
}
else
{
num2=numStack.top();
numStack.pop();
num1=numStack.top();
numStack.pop();
numStack.push(Auxcal(num1,num2,curch));
}
}
return numStack.top();
}
int prior(char c)
{
switch(c)
{
case'+':case'-':return 1;
case'*':case'/':case'%':return 2;
}
}
string inTopostExp(string exp)
{
string postExp;
char curtoken,toptoken;
stack<char> opStack;
for(int i=0;i<exp.length();i++)
{
curtoken=exp[i];
if(isalnum(curtoken))
{
postExp.append(1,' ');
postExp.append(1,curtoken);
for(;isalnum(exp[i+1]);i++)
{
postExp.append(1,exp[i+1]);
}
continue;
}
else
{
switch(curtoken)
{
case '(':
opStack.push(curtoken);
break;
case')':
while(opStack.top()!='(')
{
toptoken=opStack.top();
postExp.append(1,toptoken);
opStack.pop();
}
opStack.pop();
break;
case'+':case'-':case'*':case'/':case'%':
for(;;)
{
if(opStack.empty())
{
opStack.push(curtoken);
break;
}
else if(opStack.top()=='(')
{
opStack.push(curtoken);
break;
}
else if(prior(opStack.top())<prior(curtoken))
{
opStack.push(curtoken);
break;
}
else
//若栈顶符号优先级大于当前符号优先级,则该符号出栈,但此时当前符号不入栈,因为还需继续判断下一个优先级,也就是说这一步只是将操作符栈栈顶的符号出栈进入后缀表达式中。
{
toptoken=opStack.top();
postExp.append(1,' ');
postExp.append(1,toptoken);
opStack.pop();
}
}
break;
}
}
}
//最后一个字符如果是数字,那么栈内还有没出栈的符号
while(!opStack.empty())
{
toptoken=opStack.top();
postExp.append(1,' ');
postExp.append(1,toptoken);
opStack.pop();
}
return postExp;
}