• 关于Calculator的第四次作业


    一、魔法传送门:

    问题描述:点我点我点我!
    仓库地址:点我点我点我!

    二、网上资料:

    sstream的介绍及应用
    后缀表达式C++代码
    中缀转前缀及后缀方法
    C++计算器源代码

    三、实现过程:

    在看到题目之后,说实在的就是一脸懵逼,完全不知道从哪里下手,后来在泡泡老师(浩晖犇犇)的提醒下,了解到了中缀改后缀计算其值的方法,于是便有了以上的资料链接,看完之后,脑袋完全是懵逼的状态,但是缕清了思路之后,自己便尝试去按照介绍的方法去试着打出代码,打完之后,对于简单的式子比如(1+2、3+4等)中缀能变换成后缀,但是复杂的式子就不行了,后来在泡泡老师的指导下,debug之后才发现是括号优先级处理出了问题,废话不多说,上代码:
    这里只列Calculator.cpp的代码:

    /****************************************
    栈:sign用来存取运算符;
        opr用来存取操作数;    
        rpn用来存取后缀表达式; 
    	num用来存取整型数据;
    数组:mark:标记符号优先级; 
    函数:sstream用来操作字符串类型与整型字符型的转化;
    	  clear  用来清除多次使用的sstream对象;	 
    ****************************************/
    #include "calculation.h"
    #include <iostream>
    #include <sstream>
    #include <queue>
    #include <stack>
    
    using namespace std;
    
    Calculation::Calculation()
    {
    	error = false;
    }
    
    Calculation::~Calculation()
    {
    }
    
    //------------------------------------------------------
    	stack<string>sign; 
    	stack<string>opr;
    	stack<string>rpn;
    //------------------------------------------------------
    void Calculation::Getqueue(string input)
    {
    	
    	//初始化-------------------------------------- 
    	int mark[50];
    	mark['+'] = 1;
    	mark['-'] = 1;
    	mark['*'] = 2;
    	mark['/'] = 2;
    	mark[')'] = 3;
    	mark['('] = 4;	
    	Scan s1;
    	queue<string> tmp1 = s1.ToStringQueue(input);
    	//-------------------------------------------- 
    	//1.中缀转后缀---------------------------------
    	if (s1.IsError() == false)
    	{
    		if (tmp1.front() == "-")
    		{
    			opr.push("0");
    		} 
    		while ( tmp1.empty() == false )
    		{
    			//---1.处理操作数
    			if ( tmp1.front()[0] >= '0' && tmp1.front()[0] <= '9')
    			{
    				opr.push( tmp1.front() );
    				tmp1.pop();
    			}
    			//---2.处理运算符
    			else
    			{
    				if ( sign.empty() == true || sign.top() == "(")  
    				{
    					sign.push( tmp1.front() );
    					tmp1.pop();
    					continue;				
    				}
    				  
    				//运算符栈非空
    				//----1.判断括号的匹配 
    				if ( tmp1.front() == ")" )
    				{
    					while ( sign.top() != "(")
    					{
    						opr.push( sign.top() );
    						sign.pop();
    					}
    					tmp1.pop();
    					sign.pop(); 
    				}
    				//----2.判断优先级
    				else 
    				{
    					
    					for ( ; sign.empty() == false && sign.top()!= "("  
    									&& (mark[tmp1.front()[0]] <= mark[sign.top()[0]]); )
    					{
    						opr.push( sign.top() );
    						sign.pop();
    					}
    					sign.push( tmp1.front() );
    					tmp1.pop();
    				}
    			}
    		}
    		//----3.处理剩余的运算符 
    		while ( sign.empty() == false ) 
    		{
    			if (sign.top() == "(" || sign.top() == ")")
    			{ 
    				sign.pop();
    			}
    			else
    			{	
    				opr.push( sign.top() );
    				sign.pop();
    			}
    		}
    		
    		while (opr.empty() == false)
    		{
    			rpn.push( opr.top() );
    			opr.pop();
    		}
    	
    		//4.开始计算啦
    		//初始化--------------------- 
    		stringstream stream;
    		double n,a,b;
    		stack<double>num;
    		//---------------------------
    		while ( rpn.empty() == false)
    		{
    			if ( rpn.top()[0] >= '0' && rpn.top()[0] <='9')
    			{
    				stream << rpn.top();
    				stream >> n;
    				num.push(n);
    				stream.clear();
    				rpn.pop(); 
    			}
    			else
    			{
    				a = num.top();
    				num.pop();
    				b = num.top();
    				num.pop();
    				if (rpn.top() == "+")
    				{
    					num.push(b+a);
    					rpn.pop();
    				}
    				else if (rpn.top() == "-")
    				{
    					num.push(b-a);
    					rpn.pop();
    				}
    				else if (rpn.top() == "*")
    				{
    					num.push(a*b);
    					rpn.pop();  
    				}
    				else
    				{
    					//除数为0时的处理 
    					if ( a==0 )
    					{
    						error = true;
    						num.push(0);
    						rpn.pop(); 
    					}
    					else
    					{
    						num.push((double)b/a);
    						rpn.pop();
    					}
    				} 
    			}
    		}
    		
    		if ( error == true)
    		{ 
    			cout << "Error" << endl;
    		} 
    		else
    		{ 
    			cout << num.top() << endl; 
    		}
    	} 
    }
    

    1.测试结果:



    除数为0的处理

    2.一些方法:

    对于类似-24+35……开头为负数的式子,可以提前在存储操作数的栈中push(0);对于除数为0的处理也可以push(0)作为运算结果或者continue掉,在最后输出的时候判断是否出现判0的情况来决定是输出正确答案还是输出Error;

    四、总结与感受:

    针对于第四次作业,发觉自己在对问题处理上还不够细致,想法还不够简练,导致码出来的代码过于复杂,这里需要多多锻炼,debug的能力还待加强。学会了sstream的用法及对栈 (讲道理,有福利!<--栈的经典运用)有了初步的了解,对cmd命令也有了初步的了解点这里!,学无止境,希望自己在学习的道路上越走越远!

    你打开前面那扇门的时候,身后的退路就会消失,自始至终,你都只有一条路走——Distance
  • 相关阅读:
    HTML之元素分类(HTML基础知识)
    GreenPlum 与hadoop什么关系?(转)
    安装配置MySQL
    Linux下安装jdk步骤
    Linux ssh无密码登录
    左右无间切换走马灯angularJS指令
    CSS3制作立方体--有趣的应用
    hello,2017
    渐进增强与优雅降级
    图片上传预览(包含大小压缩)
  • 原文地址:https://www.cnblogs.com/distances/p/5351822.html
Copyright © 2020-2023  润新知