分别写了中缀转后缀,用后缀进行计算的两个源文件,后来想着干脆把它们连起来做个计算器吧。两个栈的声明完全可以合成一个类模板,不过既然复制粘贴很方便,就没去修改。而且这样一个是数组栈,而另一个是链表栈,也挺好的。
写中缀转换栈的函数时遇到了些问题,主要是在左括号的处理上。不妨写几个中缀表达式做测试,这样可以更好地理解原理。
简单来说,两个模块可以归成以下的思路。(参考了洛谷的题解)
#include<iostream>
#include<string>
#define MAX_N 10000
using namespace std;
class node{
public:
int data;
node *next;
};
//中缀转换栈
class Stack1{
public:
Stack1(){
top=-1;
ope= new char[MAX_N];
}
~Stack1(){
delete ope;
}
void Push(int data){
top= top+1;
ope[top]= data;
}
char Pop(){
int temp= top;
top= top-1;
return ope[temp];
}
char Top(){
return ope[top];
}
bool isEmpty(){
return top==-1;
}
private:
int top;
char *ope;
};
//后缀计算栈
class Stack2{
public:
Stack2(){
top= NULL;
}
~Stack2(){
while(top!=NULL){
node *ptr= top;
top= top->next;
delete ptr;
}
}
void Push(int data){
node *ptr= new node;
ptr->next= top;
ptr->data= data;
top= ptr;
}
int Pop(){
if(isEmpty()){
cout <<"Error Pop:STACK EMPTY" << endl;
return -1;
}
else{
int tempdata= top->data;
node *ptr= top;
top= top->next;
delete ptr;
return tempdata;
}
}
int Top(){
if(isEmpty()){
cout <<"Error Top:STACK EMPTY" << endl;
return -1;
}
else
return top->data;
}
bool isEmpty(){
return top== NULL;
}
private:
node *top;
};
//优先级判断函数
int judge(char temp){
if(temp=='+'||temp=='-'){
return 1;
}
if(temp=='*'||temp=='/'){
return 2;
}
if(temp=='(') return 0;
}
//中缀转后缀函数
string midfixToPostfix(string midfix){
string postfix;
Stack1 stk;
char curr;
for(int i=0; i<midfix.length(); i++){
curr= midfix[i];
//数字直接输出
if(curr>='0'&&curr<='9'){
postfix= postfix+ curr;
}
//左括号直接入栈
if(curr=='(') {
stk.Push('(');
}
//右括号弹出元素至左括号
if(curr==')'){
while(stk.Top()!='('){
postfix= postfix+ stk.Pop();
}
stk.Pop();
}
//其他符号比较栈顶优先级
if((curr<'0'||curr>'9')&&curr!='(' &&curr!=')'){
while(!stk.isEmpty()&&judge(curr)<=judge(stk.Top())){
postfix= postfix+ stk.Pop();
}
stk.Push(curr);
}
}
while(!stk.isEmpty()){
postfix= postfix+ stk.Pop();
}
return postfix;
}
//后缀计算函数
int calPostfix(string postfix){
Stack2 sta;
int i=0;
while(i<postfix.length()){
char curr=postfix[i];
if(curr>='0'&& curr<='9'){
sta.Push(curr-'0');
}
if(curr<'0'||curr>'9'){
int result= 0;
int numA= sta.Pop();
int numB= sta.Pop();
switch(curr){
case '+':
result= numA+numB;
break;
case '-':
result= numB-numA;
break;
case '*':
result= numA*numB;
break;
case '/':
result= numB/numA;
break;
default:
break;
}
sta.Push(result);
}
i=i+1;
}
return sta.Top();
}
//函数接口
int calculate(string midfix){
string postfix;
int result;
postfix= midfixToPostfix(midfix);
result= calPostfix(postfix);
return result;
}
string input;
int main(){
cin >> input;
//cout << midfixToPostfix(input)<< endl;
cout << calculate(input)<< endl;
return 0;
}