zoukankan      html  css  js  c++  java
  • 第四次作业的完善

    ——下定决心开始行动后,你会发现问题并非有想象中的那么难,问题照样有理可寻。过程中也曾迷茫,甚至想放弃,但既然开始了总不能半途而废吧。

    ——时间挤一挤真的还是会有的。

    github链接
    接下来的是我的解题思路:

    1.因为我们输入的式子是中缀表达式,但对计算机来说中缀表达式却是很复杂的,因此计算表达式的值时,通常需要先将中缀表达式转换为前缀或后缀表达式,然后再进行求值。
    因此我先将中缀表达式转变为前缀表达式。(过程中我参考了以下博客 参考博客 )。
    (期间我在转换的前缀表达式的过程中,忘记了将括号剔除,导致了程序无法正常运行。。。在这上花了好多时间。)

    2.转化成前缀表达式之后就可以开始计算了:
    从右到左遍历表达式的每个数字和符号,遇到是数字就进栈,遇到的是符号,就将栈顶的两个数字出栈,进行运算,运算结果进栈,一直到最终获得结果。

    3.其中让我最懵的就是对负数的判断处理,这也是我考虑了最久的问题,后来在同学的帮助下终于攻克了该难关。

    如下是主要代码:

    int Calculation::level(string c) //判断运算符号优先级 
    {
    int q;
    if(c=="+" || c=="-")
    {
    	q=1;
    }
    if(c=="*" || c=="/")
    {
    	q=2;
    }
    
    return (q);
    }
    
    bool Calculation::isOperator(string s) //判断是否是四则运算符号 
    {
    if (s=="+" || s=="-" ||s== "*" ||s=="/")
    	return true;
    else
    	return false;
    }
    
    
    
    double Calculation::output(queue<string> strs)
    {    
    stack<string> ch;  // 放队列strs的逆表达式
    stack<string> s1; //运算符栈
    stack<string> s2; //储存中间元素的栈
    stack<string> ch1;//放前缀表达式的逆式子
    stack<double> out; //放运算结果的栈
    string temp;
    
    
    while(!strs.empty()) // 将scan中返回的队列按逆序的方式压入栈ch中 
    {
    	ch.push(strs.front()) ;
    	strs.pop();
    
    }
    
    while(!ch.empty())
    {
    	temp=ch.top();
    
    	ch.pop();
    
    	if(isOperator(temp))
    	{
    
    		ex:;
    
    		if(s1.empty())
    		{
    			s1.push(temp);
    		}
            else if (s1.top() == ")")
            {
                s1.push(temp);
    		}   
    
    
    		else if(level(temp)>=level(s1.top()))
    		{
    
    			s1.push(temp);
    
    		}
    
    		else
    		{
    			s2.push(s1.top());
    			s1.pop();
    
    			goto ex;
    		}
    	}
    
    	else if(temp=="(")
    	{
    		while(s1.top()!=")")
    		{
    			s2.push(s1.top());
    			s1.pop();
    		}
    
            s1.pop();
    	}
    
    	else if(temp==")")
    	{
    		s1.push(temp);
    	}
    
    	else
    	{
    		s2.push(temp) ;
    	}
    
    
    }
    
    
    while(!s1.empty()) //栈s1不为空则把s1中剩下的所有元素压入栈s2中 
    {
    	s2.push(s1.top());
    	s1.pop();
    }
    
    
    	// 此时已得到前缀表达式 
    
    while(!s2.empty()) //将前缀表达式的逆序逐个压入栈ch1中 
    {
    	ch1.push((s2.top())) ;
    	s2.pop();
    }
    
      
    
    while(!ch1.empty()) //开始计算
    {
    	double x,y,z;
    	string symble;   
    	symble=ch1.top(); //将栈顶元素赋给字符串
    	ch1.pop();
    
    
    
     	if(symble =="+")
    	{
    		x=out.top();
    		out.pop();
    		y=out.top();
    		out.pop();
    		z=x+y;
    		out.push(z);
    	}
    	else if(symble == "-")
    	{
    		x=out.top();
    		out.pop();
    		y=out.top();
    		out.pop();
    		z=x-y;
    		out.push(z);
    
    	}
    	else if(symble == "*")
    	{
    		x=out.top();
    		out.pop();
    		y=out.top();
    		out.pop();
    		z=x*y;
    		out.push(z);
    	}
    	else if(symble == "/")
    	{
    		x=out.top();
    		out.pop();
    		y=out.top();
    		out.pop();
    		z=x/y;
    		out.push(z);
    	}
    
    	else // 将字符串中的数字转成double型 
    	{
    		stringstream stream;
    		double number;
    		stream<<symble;
    		stream>>number;
    		out.push(number);
    		stream.clear();
    	}
    }
    
    double num=0;
    num=out.top();
    out.pop();
    return num;
    
    }
    

    实现效果:

    收获:

    1.cmd命令行对于我来说也是陌生的,因此参考资料(参考资料 ),通过查看资料自己对于命令行有了基础的了解。

    2.这次的作业也让我对stack栈有所了解,能够比较熟练应用该数据结构。

    3.运用sstream将字符串中的数字转为double型。(可参考资料 )

  • 相关阅读:
    git
    switch切换
    js object 常用方法总结
    pod install速度慢的终极解决方案
    MacBook Pro 初体验
    LINQ以及LINQ to Object 和LINQ to Entities
    WebService/WCF/WebAPI 之间的区别
    owin
    回车和刷新以及Ctr+F5的区别
    ASP.NET Core 启动流程图
  • 原文地址:https://www.cnblogs.com/cjqcjq/p/5398786.html
Copyright © 2011-2022 走看看