基本的思路是将中缀表达式转换为后缀表达式,消除括号,然后计算。后缀表达式又称逆波兰表达式。主要通过栈来实现。
中缀表达式转换为后缀表达式:
1.从左到右逐个扫描中缀表达式中的各项,遇到结束符“#” 转6,否则继续。这里选择想中追表达式中添加一个#或自行判断是否到字符串的末尾。
2.遇到操作数直接输出。
3.若遇到右括号 ,则连续出栈输出,直到遇到左括号为止。左括号出栈但不输出,遇到右括号也不输出。
4.若是其他操作符,则和栈顶操作符比较优先级,若小于等于栈顶操作符优先级,则连续出栈输出,直到大于栈顶操作符的优先级结束,操作符进栈。
5。
6.输出栈中剩余操作符,“#”除外。
这里我们将输入的一个表达式字符串转换为后缀,且输入表达式是正确无误的。
#include "Calculator.h"
int calculator::getPriorityInStack(char oper){
if(oper == '#')return 0;
else if(oper == '(')return 1;
else if(oper == '*' || oper == '/')return 5;
else if(oper == '+' || oper == '-')return 3;
else if(oper == ')')return 7;
return -1;
}
int calculator::getPriorityOutStack(char oper){
if(oper == '#')return 0;
else if(oper == '(')return 7;
else if(oper == '*' || oper == '/')return 4;
else if(oper == '+' || oper == '-')return 2;
else if(oper == ')')return 1;
return -1;
}
string calculator::changeToSuffix(string Prefix){
int isp,icp,i = -1 ;
string output = "";;
operstack.push('#');
while(++i < Prefix.length()){
isp = getPriorityOutStack( Prefix[i]) ;
if(isp == -1){
output+=Prefix[i];
output+=',';
}
else{
icp = getPriorityInStack( operstack.top() );
while(isp <= icp){
output += operstack.top();
operstack.pop();
icp = getPriorityInStack( operstack.top() );
output+=',';
}
operstack.push(Prefix[i]);
}
}
while (!operstack.empty())
{
output+= operstack.top();
operstack.pop();
output+=',';
}
return output.substr(0,output.length()-3);
}
使用 逗号,将数字分开。
c++中没有split函数,之后对改好的后缀表达式的运算就只能一个个遍历了。
后缀表达式的计算:
扫描表达式,遇到操作数进栈,遇到操作符,出栈两个操作数,然后使用操作符进行计算,先出栈的放在操作符的右边,获得结果进栈,知道遇到结束符。
int calculator::getResultBySuffix(string Suffix){
int i = 0;
string buff;
int a,b;
while( i < Suffix.length()){
if(Suffix[i] == ',')
i++;
buff = "";
while(Suffix[i] >='0' && Suffix[i]<='9'&& i <Suffix.length())
buff += Suffix[i++];
if(buff != ""){
numstack.push(atoi(buff.c_str()));
}else{
a = numstack.top();
numstack.pop();
b = numstack.top();
numstack.pop();
if(Suffix[i] == '+')
numstack.push(b+a);
else if(Suffix[i] == '-')
numstack.push(b-a);
else if(Suffix[i] == '*')
numstack.push(b*a);
else if(Suffix[i] == '/')
numstack.push(b/a);
i++;
}
}
i = numstack.top();
numstack.pop();
return i;
}
int calculator::getResult(string Prefix){
return getResultBySuffix(changeToSuffix(Prefix));
}
完成计算。