表达式计算

这是一个使用C++编写的程序,用于计算包含加、减、乘、除和幂运算的数学表达式。程序处理了括号、多余括号和负数的情况,并且在除法中采用了向0取整的规则。它通过栈来处理运算符和操作数,遵循运算符的优先级进行计算。样例包括处理带有括号的复杂表达式以及含有多余符号的简单算术运算。
摘要由CSDN通过智能技术生成

题目要求:
给出一个表达式,其中运算符仅包含 +,-,*,/,^ 要求求出表达式的最终值。
数据可能会出现括号情况,还有可能出现多余括号情况
数据可能会出现负数情况,幂次不可能为负数,除法采用向 0 取整。
​注意:−9 和 +9 分别代表负数和正数的 9
个别样例:
样例1:((((7+9)^(1+3)) 答案:65536
样例2:51+89-56 – 78 答案:162
样例3:(-79+48+76-45+98) 答案:98

看似简单,细节却多到令人厌烦的表达式计算:
源码:

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

int calc(int a, int b, char op) {
    int ret;
    switch(op) {
        case '+': {
            ret = a + b;
        } break;
        case '-': {
            ret = a - b;
        } break;
        case '*': {
            ret = a * b;
        } break;
        case '/': {
            ret = a / b;
        } break;
        case '^': {
            ret = pow(a, b);
        } break;
    }
    return ret;
}

int operation(stack<int> &sta_num, stack<char> &sta_op) {
    int a = sta_num.top();
    sta_num.pop();
    int b = sta_num.top();
    sta_num.pop();
    //cout << b << sta_op.top() << a << endl;
    int ret = calc(b, a, sta_op.top()); //需要交换a,b顺序
    sta_num.push(ret);
    sta_op.pop();  //弹出用过的op
    return ret;
}

int precede(char op1, char op2) {
    if (op2 == '(') return 1;
    if (op1 == '^' && op2 != '^') return 1;
    if ((op1 == '*' || op1 == '/') && (op2 == '+' || op2 == '-')){
        return 1;
    } else {
        return 0;
    }
}

int main() {
    char buffers[1005];
    cin >> buffers;
    stack<int> numbers;
    stack<char> ops;
    int flag = 0;
    int num = 0;
    int n = strlen(buffers);
    int i = 0;
    while (i < n) {

        //cout << "ind :" << i + 1 << endl;
        if (isdigit(buffers[i])) {
            num = num * 10 + buffers[i] - '0';
            i++;
            //若后一个数字不为数字字符,则完整获取number,数的正负参考flag
            if (!isdigit(buffers[i])) {  
                flag == 1 && (num = 0 - num);
                numbers.push(num);
                num = 0, flag = 0;  //数字压栈,临时变量清0
            }
        } else if (buffers[i] == '('){
            ops.push(buffers[i]);
            i++;
        } else if(buffers[i] == ')') {
        	//计算()内的表达式
            while(!ops.empty() && ops.top() != '(') { 
                operation(numbers, ops);
            }
            ops.pop();
            i++;
        } else {
            if (buffers[i] == '-') {
            	//处理多余-号,符号取反
                if (i == 0 || (i > 0 && (!isdigit(buffers[i - 1]) && buffers[i - 1] != ')'))) {
                    flag ^= 1; 
                    i++;
                    continue;
                }
            } else if (buffers[i] == '+') {
                //处理多余加号,直接跳过
                if (i == 0 || (i > 0 && (!isdigit(buffers[i - 1]) && buffers[i - 1] != ')'))) {
                    i++;
                    continue;
                }
            }
            if (ops.empty() || precede(buffers[i], ops.top())) {
                ops.push(buffers[i]);
                i++;
            } else {
                operation(numbers, ops);
            }
        }
    }
    while (!ops.empty() && ops.top() != '(') {
        operation(numbers, ops);
    }
    cout << numbers.top() << endl;
    return 0;
}
一、问题描述 在控制台下实现一个对算术表达式求值的模拟程序。 二、基本要求 该演示程序具有如下基本功能: (1) 表达式输入,以字符序列的形式从终端输入一个语法正确的数值表达式(float型),且表达式中只含有+、-、*、/、( 、)6 种运算符,输入格式如下: <变量><运算符><变量>……<回车> 例如表达式: 100+(15/3)*2 输入格式为: 100+(15/3)*2<回车> 注意: 输入的表达式中间不含空格。 (2) 表达式结果的输出,输出形式为: <表达式> = <结果> 例如表达式: 100+(15/3)*2 输出形式为: 100+(15/3)*2 = 110 注意: 此处的输出结果为整个表达式的数值结果。 (3) 数据合法性检验 主要是针对原表达式中除数为 0 的情况。 三、界面效果 表达式求值模拟程序 功能菜单: ============== [1] 输入表达式并求值 [0] 退出 ============== 请输入你的选择 (0~1):1 请输入一个表达式 : 100+(15/3)*2 计算结果如下: 100+(15/3)*2 = 110 请输入你的选择 (0~1):0 四、测试数据 (1) 8 = (2) 1+2+3+4 = (3) 88-1*5 = (4) 1024/4*8 = (5) 1024/(4*8) = (6) (20+2)*(6/2) = (7) 3-3-3 = (8) 80/(9-9) = (9) (6+2*(3+6*(6+6)) = (10) (((6+6)*6+3)*2+6)*2 = 五、实现提示 (1) 设置运算符和操作数辅助分析算符优先关系; (2) 在读入字符序列时,完成运算符和操作数的处理,以及相应运算; (3) 在识别处运算数的同时,要将其字符序列形式转化成 float 型数据形式; (4) 输入的字符序列中,操作数不一定是一位数,可能是多位数,如 16+32 ; (5) 使用 Lab3-1 实现的的 ADT 基本操作完成本次作业 ; (6) 在程序中会用到两类:操作数和运算符,分别为 float 型数据和字符型数据, 思考在同一个程序中如何处理两类不同的数据类型? (7) 算符之间的优先关系参考课本 P53 页表 3.1 。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值