基于栈的中缀算术表达式求值

描述

输入一个中缀算术表达式,求解表达式的值。运算符包括+、-、*、/、(、)、=,参加运算的数为double类型且为正数。(要求:直接针对中缀算术表达式进行计算,不能转换为后缀或前缀表达式再进行计算,只考虑二元运算即可。)

输入

多组数据,每组数据一行,对应一个算术表达式,每个表达式均以“=”结尾。当表达式只有一个“=”时,输入结束。参加运算的数为double类型。

输出

对于每组数据输出一行,为表达式的运算结果。输出保留两位小数。

输入样例 1 

2+2=
20*(4.5-3)=
=

输出样例 1

4.00
30.00

#include <iostream>
#include <stdlib.h>
#include <cstring>
#include<iomanip>//该头文件为了后面的输出保留两位小数
 
#define MAXSIZE 100//初始分配的存储空间
#define OK 1
#define OVERFLOW -2
#define ERROR -1
 
using namespace std;
 

typedef struct {
    char* base;
    char* top;
    int stacksize;
} SqStackOPTR;
 //字符栈 

typedef struct {
    double* base;
    double* top;
    int stacksize;
} SqStackOPND;
 //数据栈 

int InitStack(SqStackOPTR& S) {
    S.base = new char[MAXSIZE];
    if (!S.base) exit(OVERFLOW);
    S.top = S.base;
    S.stacksize = MAXSIZE;
    return OK;
}
 

int InitStack(SqStackOPND& S) {
    S.base = new double[MAXSIZE];
    if (!S.base) exit(OVERFLOW);
    S.top = S.base;
    S.stacksize = MAXSIZE;
    return OK;
}
 

int Push(SqStackOPTR& S, char e) {
   	if(S.top-S.base==S.stacksize) return ERROR;
	*S.top++ = e; 
	return OK;
}
 

int  Push(SqStackOPND& S, double e) {
    if(S.top-S.base==S.stacksize) return ERROR;
	*S.top++ = e; 
	return OK;
}
 
//字符栈出栈
char Pop(SqStackOPTR& S) {
    char e;
    if (S.top == S.base) return ERROR;
    e = *--S.top;
    return e;
}
 
//数字栈出栈
double Pop(SqStackOPND& S) {
    double e;
    if (S.top == S.base) return ERROR;
    e = *--S.top;
    return e;
}
 

char GetTop(SqStackOPTR S) {
    char e;
    if (S.top == S.base) return ERROR;
    e = *(S.top - 1);
    return e;
}
 

double GetTop(SqStackOPND S) {
    double e;
    if (S.top == S.base) return ERROR;
    e = *(S.top - 1);
    return e;
}
 

int In(char ch) {
    int isNumber;
    switch (ch) {
    case '+':
    case '-':
    case '*':
    case '/':
    case '(':
    case ')':
    case '=': isNumber = 1; break;
    default:  isNumber = 0; break;
    }
    return isNumber;
}
 
//定义一个判定运算符栈的栈顶元素与读入的运算符之间优先关系的函数
char Precede(char top, char ch) {
    char sym;
    switch (top) {
    case '+':
    case '-':
        switch (ch) {
        case '+':
        case '-':
        case ')':
        case '=': sym = '>'; break;
        case '*':
        case '/':
        case '(': sym = '<'; break;
        } break;
 
    case '*':
    case '/':
        switch (ch) {
        case '+':
        case '-':
        case '*':
        case '/':
        case ')':
        case '=': sym = '>'; break;
        case '(': sym = '<'; break;
        }break;
    case '(':
        switch (ch) {
        case '+':
        case '-':
        case '*':
        case '/':
        case '(':sym = '<'; break;
        case ')': sym = '='; break;
        }break;
    case ')':
        switch (ch) {
        case '+':
        case '-':
        case '*':
        case '/':
        case ')':
        case '=':sym = '>'; break;
        }break;
    case '=':
        switch (ch) {
        case '+':
        case '-':
        case '*':
        case '/':
        case '(':sym = '<'; break;
        case '=':  sym = '='; break;
        } break;
    }
    return sym;
}

//char Precede(char top, char ch)另一种写法 
//{
//	if((top=='('&&ch==')')||(top=='='&&ch=='=') )return '=';
//	else
//	if(((top=='+'||top=='-'||top=='*'||top=='/'||top==')') && (ch=='+'||ch=='-'||ch==')'||ch=='='))||((top=='*'||top=='/'||top==')')&&(c=h='*'||ch=='/')))return '>';
//	else
//	if(((top=='('||top=='=')&&ch!=')'&&ch!='=')|| ((top=='+'||top=='-')&&(ch=='*'||ch=='/'))||top=='('||ch=='(') return '<';
//	else 
//	cout<<c1<<" "<<c2<<"没有输出"<<endl; 
//
//}
 

double Operate(double a, char top, double b) {
    double sum = 0;
    switch (top) {
    case '+': sum = a + b;  break;
    case '-':sum = a - b; break;
    case '*': sum = a * b; break;
    case '/':sum = a / b; break;
    }
    return sum;
}
 
double EvaluateExpression(char ch) {
    SqStackOPTR OPTR;
    SqStackOPND OPND;
    InitStack(OPTR);
    InitStack(OPND);
    Push(OPTR, '=');
    char chs[20];//定义一个字符数组,来实现数字转换为字符串
    memset(chs, '#', sizeof(char) * 20);//将字符数组的元素设置为‘#’ 即初始化chs数组 不然会报错
 
    while (ch != '=' || GetTop(OPTR) != '=') {//表达式没有扫描完毕或OPTR的栈顶元素不为“=”
        if (!In(ch)) {
        	
            //这里应该将字符串转换为数字
            for (int i = 0; i < strlen(chs); i++) {
                if (chs[i] == '#' && !In(ch)) {//如果数组的第i个元素不为‘#’或不为符号
                    chs[i] = ch;
                    cin >> ch;
                }
                else {
                    break;
                }
            }
            double d = atof(chs);//把字符串转换成浮点数 double
            Push(OPND, d);
            memset(chs, '#', sizeof(char) * 20);//将字符数组的元素设置为‘#’
        }
        else {
            switch (Precede(GetTop(OPTR), ch)) {
            case '<':
                Push(OPTR, ch); cin >> ch;
                break;
            case '>':
                char theta;
                double b;
                double a;
                theta = Pop(OPTR);
                b = Pop(OPND);
                a = Pop(OPND);
                double sum;
                sum = Operate(a, theta, b);
                Push(OPND, sum);
                break;
            case '=':
                Pop(OPTR);
                cin >> ch;
                break;
            }
        }
    }
    return GetTop(OPND);
}
 
int main() {
 
    while (1) {
        char ch;
        cin >> ch;
        if (ch == '=')break;
        double res = EvaluateExpression(ch);
        cout << fixed << setprecision(2) << res << endl;//输出保留两位小数
    }
    return 0;
}

  • 9
    点赞
  • 73
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Yvonnae

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值