第四次作业的完善

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

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

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;

}

实现效果:

885782-20160418231226085-942333192.jpg

收获:

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

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

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

转载于:https://www.cnblogs.com/cjqcjq/p/5398786.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值