C++实现四则运算

表达式计算思路:

       1)准备两个栈,一个数据栈,一个运算符栈。

          反复读取表达式:(2、3、4)

      2)如果是数,入数栈。

      3)如果是左括号,入运算符栈。如果是右括号,反复从运算符栈顶取运算符合从数据栈中取两个数据进行计算,并把运算结果入数据栈,直到遇到栈顶或左括号为止。

    4)如果是运算符,先跟栈顶的运算符比,只要不高于栈顶优先级,就取出栈顶的运算符和数据栈中的两个数据进行计算,把结果入数据栈,直到高于栈顶运算符优先级或者遇到左括号或者运算符栈空为止。

    5)处理栈中的运算符:取出栈顶的运算符和数据栈的两个数据进行运算,并把结果入数据栈,直到运算符栈空为止。

    6)这时数据栈中的数据就是计数结果。

#include<iostream>
#include<stack>
#include<string>
#include<cstring>
using namespace std;

class Exp
{
    stack<char> ops; //运算符栈
    stack<double> ds;  //数据栈
    double v,lh,rh;  //结果、左运算符、右运算符
    char op;   //操作符
    public:
        double calinput() //读取计数表达式直到结束
        {
            do
            {
                readdata();  //读取数据
                skipspace();  //跳过空白字符
            }while(readop());  //读取运算符

            calremain();
            return v;
        }

        void readdata()  //读取数据可能遇到'('
        {
            while(!(cin >> v))  //读取失败因该是‘(’
            {
                cin.clear();
                cin >> op;    //读取‘(’
                if(op != '(')
                {
                    throw string("在该出现数值得地方遇到了") + op;
                }
                ops.push(op);
            }
            ds.push(v);
        }

        void skipspace()  
        {
            while(cin.peek() == ' ' || cin.peek() == '\t')
            {
                cin.ignore();
            }
        }

        bool readop()  //读取运算符可能遇到‘)’或者‘\n’
        {
            while((op=cin.get()) == ')')
            {
                while(ops.top() != '(')  //栈中的‘(’
                {
                    rh = ds.top(); ds.pop(); //从栈中取右操作数
                    lh = ds.top(); ds.pop(); //从栈中取左操作数
                    ds.push(cal(lh,ops.top(),rh)); //计算结果入栈
                    ops.pop();
                }
                ops.pop();  //丢弃栈中的‘(’
            }

            if(op == '\n') return false;
            if(strchr("+-*/",op) == NULL)
            {
                throw string("无效运算符")+op;
            }

            while(!ops.empty() && ops.top() != '(' && prior(op,ops.top()))
            {
                rh = ds.top(); ds.pop(); //从栈中取右操作数
                lh = ds.top(); ds.pop(); //从栈中取左操作数
                ds.push(cal(lh,ops.top(),rh)); //计算结果入栈
                ops.pop();
            }
            ops.push(op);  //预算符入栈
            return true;
        }

        void calremain()
        {
            while(!ops.empty())
            {
                rh = ds.top(); ds.pop(); //从栈中取右操作数
                lh = ds.top(); ds.pop(); //从栈中取左操作数
                ds.push(cal(lh,ops.top(),rh)); //计算结果入栈
                ops.pop();
            }
            if(ds.size()!= 1) 
            {
                throw string("无效表达式");
            }
            v = ds.top();
            ds.pop();
        }

        double cal(double lh, char op, double rh)
        {
            return op == '+' ? lh + rh :
                   op == '-' ? lh - rh :
                   op == '*' ? lh * rh : lh/rh;
                    
        }

        bool prior(char op1, char op2)  // op1的优先级是否高于op2
        {
            return op1 != '+' && op1 != '-' && op2 != '*' && op2 != '/';
        }
};

int main ()
{
    Exp e;
    try
    {
        cout << e.calinput() <<endl;
    }
    catch(const string& e)
    {
        cout << e <<endl;
    }
    
    
}

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值