C++数据结构 栈实现中缀表达式求值

一、问题描述

算符优先法:根据运算符优先关系来实现对表达式进行编译执行,为简单起见只讨论四则运算
优先级表格如下:
在这里插入图片描述

二、算法描述

  1. 设置两个栈,操作数栈opnd和操作符栈optr
  2. 在optr栈底加入一个“=”
  3. 在输入流中读入一个字符ch,循环执行 ,直到求出表达式的值
  4. 取出optr的栈顶optrTop,当optrTop和ch同时=“=”,整个表达式求值完毕,opnd栈顶元素为表达式值
  5. 若ch不是操作符,将字符放回输入流,读操作数operand,加入opnd栈,读入下一字符ch
  6. 若ch是操作符,则比较ch和optrTop的优先级:
    optrTop<ch ch入optr栈,读入下一字符ch
    optrTop>ch 从opnd栈中弹出两个数,弹出optrTop,执行运算后结果放入opnd栈中
    optrTop为”)”且ch=“(” 弹出optrTop,读入下一字符ch
    optrTop e ch 出现错误,停止执行

三、参考代码

  • 定义栈类
class AStack                                         //栈模板
{
protected:
	int count;
	int maxsize;
	T* elems;
	void init(int size);
	bool full() const;
public:
	    AStack(int size = 2000);                     //定义栈大小
	    virtual ~AStack();                           //析构函数
		bool Empty() const;                          //判断是否空栈
	    void Clear();                                //清空栈
		void push(const T &a) ;                         //入栈
		void pop(T& b);                                 //出栈
		void top(T& e) const;                           //取栈顶元素
		 
};
  • 执行运算的类
 class Caculator {
 private:
	 static bool IsOperator(char ch);                                            //判断是否操作符
	 static char JudgePriority(char thetal, char theta2);                        //判断操作符优先级
	 static double Operate(double left, char theta, double right);               //执行计算操作
	 static void GetTwoOpra(AStack<double>& opnd, double& left, double& right);  //从栈中弹出两个操作数
	 static void JudgeEnter(char ch);
 public:
	 Caculator() { };                                //构造函数
	 virtual ~Caculator() {};                        //析构函数
	 static void Run();                              //实际运行函数

 };
  • 实际运行主函数
void Caculator::Run() {
	 AStack<double> opnd;                            //构建操作数栈
	 AStack<char> optr;                              //构建操作符栈
	 optr.push('=');                                 //操作符栈底先放入一个等号
	 char ch;
	 char OptrTop;                                   //操作符栈的栈顶元素
	 double Operand;                                 //操作数
	 char theta;                                     //操作符

	 ch = cin.get();
	 while ((optr.top(OptrTop), OptrTop!='=') || ch!='=')             
	 {
		 if (ch == ' ') { ch = cin.get(); continue; }
		 if (!IsOperator(ch))                        //不是操作数就入操作数栈,继续往后读
		 {
		 	 temp1 = 0;
			 cin.putback(ch);
			 cin >> Operand;
			 opnd.push(Operand);
			 ch = cin.get();
			 if (ch == ' ') { ch = cin.get(); continue; }
			 JudgeEnter(ch);
		 }
		 else 
	 {
		 if ((temp1 == 1 && ch == '+') || (temp1 == 1 && ch == '-')) {           //如果左括号旁边是正号或负号,往栈里压一个0,temp1重新为0    
			 opnd.push(0);
		 temp1 = 0; }   
		  else temp1 = 0;                            
			 switch (JudgePriority(OptrTop, ch))
			 {                                       //是操作符就判断该操作符与操作符栈顶的操作符的优先级
			 case'<':                                //优先级低,就进栈,继续往后读
				 optr.push(ch);
				 ch = cin.get();
				 JudgeEnter(ch);
				 break;
			 case '=':                               //操作符优先级相等,从操作符栈中弹出,继续往后读
				 optr.pop(OptrTop);
				 ch = cin.get();
				 JudgeEnter(ch);
				 break;
			 case'>':                                //优先级高,从操作数栈中弹出两个操作数进行运算,结果放入操作数栈中
				 double left, right;
				 GetTwoOpra(opnd, left, right);
				 optr.pop(theta);
				 opnd.push(Operate(left, theta, right));
				 break;
			 case'e':                                //读取的不是规范的操作符,错误提示
				 cout << "操作符匹配错" << endl;
				 	system("pause");
				 exit(1);

			 }
		 
		 }
	 }
	 opnd.top(Operand);                              //读操作数栈的栈顶元素,输出计算结果
	 cout << "表达式值为:" << Operand << endl;
 }

四、总结
总的来说,实现并不难,关键是操作符优先级的比较和表达式各种情况的考虑,对熟悉栈的搭建和应用很有帮助,应尽量独立完成。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值