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

该程序实现了对中缀算术表达式的直接计算,不通过转换为后缀或前缀表达式。使用两个栈分别存储数字和运算符,遵循运算符优先级规则处理表达式,遇到数字入数字栈,遇到运算符则比较优先级进行计算。程序遍历输入的字符串,处理数字和括号,最终输出保留两位小数的结果。
摘要由CSDN通过智能技术生成

描述

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

输入

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

输出

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

demo

#include<iostream>
#include <stack>
#include <string.h>
#include <stdlib.h>  //atof库函数
using namespace std;

//判断优先级
int pre(char c){
	if (c == '=')
		return 0;
	else if (c == '+' || c == '-')
		return 1;
	else if (c == '*' || c == '/ ')
		return 2;
	else 
		return 0;
}

//计算
void Calculate(stack <double> &num, stack <char> &op) {
	double b = num.top();  //右操作数
	num.pop();
	double a= num.top();   //左操作数
	num.pop();
	char x = op.top();     //操作符

	if (x == '+')
		num.push(a + b);
	else if (x == '-')
		num.push(a - b);
	else if (x == '*')
		num.push(a*b);
	else if (x == '/ ')
		num.push(a / b);

	    op.pop();   //弹出操作符
}

int main() {
	stack <double> num;
	stack <char> op;
	 char s[1000];    //待输入的字符串
	while (scanf("%s",s)!=EOF) {
		if (!strcmp(s, "=") )  break;     //退出循环的条件

		for (int i = 0; s[i] != '\0'; i++){  //字符串结束的标志: != '\0' ***
			
             //①若遍历到的是数字
			if (s[i]>='0' && s[i]<='9') {    
				double temp = atof(s + i);  //转化为double【s是数组始址 i是数字字符起始下标】
				num.push(temp);
				while ((s[i] >= '0' && s[i] <= '9') || s[i] == '.')
				{
					i++;  //寻找数字的组成部分
				}
				i--; //回到遍历的数字de末尾				
			}

			//②若遍历到的是字符
			else
			{
				if (s[i] == '(') //【左括号】直接入栈
					op.push(s[i]);
				else if(s[i]==')')//遇到【右括号】从op栈往外弹,直到弹出一个左括号
				{
					while (op.top()!='(') 
					{
						Calculate(num, op); //计算式子
					}
					    op.pop();//左括号出栈
				}
				else if (op.empty()||pre(s[i]) > pre(op.top())) { //来了一个【高优先级的运算符】
					op.push(s[i]);
				}
				else if (!op.empty() && pre(s[i]) <= pre(op.top())) { //来了一个【低优先级的运算符】
					while (!op.empty()&&pre(op.top())>=pre(s[i]))
					{
						Calculate(num, op);
					}
					 op.push(s[i]);//当比它优先级高的都出队操作后,将新操作符入队
				}
			}
		}
		printf("%.2lf\n", num.top());//结果
		num.pop(); 
		op.pop();
	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值