中缀表达式 【习题描述】 d. 计算中缀表达式的值,例如:输入2*(3+5)+7/1-4,输出19 e. 中缀表达式变换为后缀表达式,例如:输入2*(3+5)+7/1-4,输出235+*71/+4-

中缀表达式
【习题描述】
d. 计算中缀表达式的值,例如:输入2*(3+5)+7/1-4,输出19

e. 中缀表达式变换为后缀表达式,例如:输入2*(3+5)+7/1-4,输出235+*71/+4-

用例:

假如输入为:2*(3+5)+7/1-4

则输出为:

输入一个中缀表达式:

表达式计算结果:

19

/**1.4-d,e 计算器:中缀表达式转换为后缀,并计算

	void infix_to_suffix();   //1.4-e  将中缀表达式转换为后缀表达
	void cal_suffix();        //1.4-d.	计算中缀表达式的值

**/
#include <cstdlib>
#include <iostream>
#include <string>

using namespace std;

template <class T>
class stack {
private:
    int top; //栈顶
    int maxtop; //最大的栈顶值
    T* st; //堆栈元素数组
public:
    stack(int maxstacksize = 10)
    {
        maxtop = maxstacksize - 1;
        st = new T[maxstacksize];
        top = -1;
    }
    ~stack()
    {
        delete[] st;
    }
    bool isfull()
    {
        return top == maxtop;
    }
    bool isempty()
    {
        return top == -1;
    }
    bool add(const T& x)
    {
        if (isfull()) {
            cout << "no memory" << endl;
            return false;
        }
        top++;
        st[top] = x;
        return true;
    }
    T del()
    {
        if (isempty()) {
            cerr << "no element" << endl;
        }
        T x;
        x = st[top];
        top--;
        return x;
    }
    T returntop()
    {
        return st[top];
    }
    void clear()
    {
        top = -1;
    }
    void output()
    {
        if (isempty()) {
            cout << "栈是空的" << endl;
        } else {
            for (int i = 0; i <= top; i++) {
                cout << st[i] << '\t';
            }
            cout << endl;
        }
    }
};

class Calculator {
public:
    string infix; //中缀表达式
    string postfix; //后缀表达式
    stack<double> poststack; //后缀栈
    Calculator(string str);
    ~Calculator()
    {
        poststack.clear();
    }
    void infix_to_suffix(); //1.4-e  将中缀表达式转换为后缀表达
    int inStack(char ch); //栈内优先级
    int outStack(char ch); //栈外优先级数
    void cal_suffix(); //1.4-d.	计算中缀表达式的值
    void print();
    bool Get_operands(double& left, double& right);
    bool isNumber(char ch);
    double returnnum(char* c, int n); //返回字符对应的数
    float toNum(char num_ch); //数值型字符转换成数字
    void cal(char ch); //根据操作符 去栈中去取两个元素计算
};
Calculator::Calculator(string str)
{
    infix = str;
}

string format(string str) {
    for (int i = 0; i < str.length(); i++)
        if (str[i] == '-')
            if (i == 0)
                str.insert(0, 1, '0');
            else if (str[i - 1] == '(')
                str.insert(i, 1, '0');
    return str;
}
/*
TODO:1.4-e  将中缀表达式转换为后缀表达,假如中缀表达式为1+(2-3)*4+4/2,
则转换后为:1&2&3&-4&*+4&2&/+ [为了区分数字与数字,用&符号将数字进行隔开,当然也可自行选择其他方式来表达]
 */
void Calculator::infix_to_suffix()
{
    int r=infix.length();
    for (int i = 0; i < infix.length(); ++i) {
        if (infix[i]=='('||infix[i]==')')
            r--;
        if (isNumber(infix[i]))
            r++;
    }
    postfix.resize(r);
    int a=0;
    for (int i = 0; i < infix.length(); ++i) {
        if (isNumber(infix[i])){
            postfix[a++]=infix[i];
        } else{
            if (a)
                if (isNumber(postfix[a-1]))
                    postfix[a++]=' ';
            if (poststack.isempty())
                poststack.add(infix[i]);
            else{
                if (inStack(poststack.returntop())<outStack(infix[i])){
                    poststack.add(infix[i]);
                } else if (inStack(poststack.returntop())>outStack(infix[i])){
                    while (inStack(poststack.returntop())>outStack(infix[i])){
                        postfix[a++]=poststack.returntop();
                        poststack.del();
                    }
                    if (inStack(poststack.returntop())==outStack(infix[i])){
                        poststack.del();
                    } else
                        poststack.add(infix[i]);
                } else{
                    poststack.del();
                }
            }
        }
    }
    if (a)
        if (isNumber(postfix[a-1]))
            postfix[a++]=' ';
    while (!poststack.isempty()){
        postfix[a++]=poststack.returntop();
        poststack.del();
    }
}

/*
TODO: 1.4-d.计算中缀表达式的值,比如:假如中缀表达式为1+(2-3)*4+4/2,则根据四则混合运算优先级计算,它的结果为-1.
如果输入的中缀表达式非法,则打印cout << "重新输入 并检查表达式的合法性" << endl;,然后exit(1)结束执行。
*/
void Calculator::cal_suffix()
{
    infix_to_suffix(); //将中缀表达式转换为后缀表达式
    for (int i = 0; i < postfix.length(); ++i) {
        if (isNumber(postfix[i])){
            int cnt=0,a=0;
            char*c=new char;
            while (isNumber(postfix[i])){
                cnt++;
                c[a++]=postfix[i++];
            }
            poststack.add(returnnum(c,cnt));
        } else{
            cal(postfix[i]);
        }
    }
}

bool Calculator::Get_operands(double& left, double& right)
{
    if (poststack.isempty()) {
        cout << "缺少右操作数" << endl;
        return false;
    }
    right = poststack.del(); //取右操作数
    if (poststack.isempty()) {
        cout << "缺少左操作数" << endl;
        return false;
    }
    left = poststack.del(); //取出左操作数
    return true; //返回true
}
double Calculator::returnnum(char* c, int n) //返回字符对应的数,n表示个十百千位
{
    int l = n;
    double num = 0;
    double m = 1;
    for (int i = l - 1; i >= 0; i--) {
        num += toNum(c[i]) * m;
        m *= 10;
    }
    return num;
}

int Calculator::inStack(char c)
{
    switch (c) {
        case '#':
            return 0;
            break;
        case '(':
            return 1;
            break;
        case '*':
        case '/':
        case '%':
            return 5;
            break;
        case '+':
        case '-':
            return 3;
            break;
        case ')':
            return 6;
            break;
    }
}
//返回操作符的栈外优先级
int Calculator::outStack(char c)
{
    switch (c) {
        case '#':
            return 0;
            break;
        case '(':
            return 6;
            break;
        case '*':
        case '/':
        case '%':
            return 4;
            break;
        case '+':
        case '-':
            return 2;
            break;
        case ')':
            return 1;
            break;
    }
}
//判断是否为操作数
bool Calculator::isNumber(char ch)
{
    if (48 <= ch && ch <= 57)
        return true;
    else
        return false;
}

//数值型字符转换为数字
float Calculator::toNum(char num_ch)
{
    switch (num_ch) {
        case '0':
            return 0;
            break;
        case '1':
            return 1;
            break;
        case '2':
            return 2;
            break;
        case '3':
            return 3;
            break;
        case '4':
            return 4;
            break;
        case '5':
            return 5;
            break;
        case '6':
            return 6;
            break;
        case '7':
            return 7;
            break;
        case '8':
            return 8;
            break;
        case '9':
            return 9;
            break;
    }
}
//根据操作符 去栈中去取两个元素计算
void Calculator::cal(char cp)
{
    double left, right, value;
    if (Get_operands(left, right)) {
        switch (cp) {
            case '+': {
                value = left + right;
                poststack.add(value); //相加后结果压栈
                break;
            }
            case '-': {
                value = left - right;
                poststack.add(value); //相减 压栈
                break;
            }
            case '*': {
                value = left * right;
                poststack.add(value); //相乘 压栈
                break;
            }
            case '/':
                if (right == 0) {
                    cout << "/ 操作符 右操作数为0" << endl;
                    exit(1);
                } else {
                    value = left / right;
                    poststack.add(value); //相除 压栈
                }
                break;
        }
    }
}
//保留并输出最后结果
void Calculator::print()
{
    cout << "表达式计算结果:" << endl;
    cout << poststack.returntop() << endl;
}
int main()
{
    string str;
    cout << "输入一个中缀表达式:" << endl;
    cin >> str;
    str = format(str);
    Calculator calculator(str);
    calculator.cal_suffix();
    calculator.print(); //显示结果
    return 0;
}


  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值