计算器:中缀转后缀与后缀的计算

分别写了中缀转后缀,用后缀进行计算的两个源文件,后来想着干脆把它们连起来做个计算器吧。两个栈的声明完全可以合成一个类模板,不过既然复制粘贴很方便,就没去修改。而且这样一个是数组栈,而另一个是链表栈,也挺好的。
写中缀转换栈的函数时遇到了些问题,主要是在左括号的处理上。不妨写几个中缀表达式做测试,这样可以更好地理解原理。
简单来说,两个模块可以归成以下的思路。(参考了洛谷的题解)
在这里插入图片描述

#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;
} 



  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值