【 第1关:基于栈的中缀算术表达式求值】【编程题实训-栈】【头歌】【bjfu-240】

任务描述

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

编程要求

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

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

测试说明
平台会对你编写的代码进行测试:

测试输入:

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

预期输出:

4.00
30.00

来源
https://www.bjfuacm.com/

C++代码

240 head.h

#include <iostream>
#define MAXSIZE 100
#define OK 1
#define ERROR 0
#define OVERFLOW -2
using namespace std;


typedef struct
{//符号栈
	char* base;
	char* top;
	int stacksize;
}SqStack1;


int InitStack1(SqStack1& S)
{//符号栈初始化
	S.base=new char[MAXSIZE];
    if (!S.base) exit (OVERFLOW);
    S.top=S.base;
    S.stacksize=MAXSIZE;
	return OK;
}
int Push1(SqStack1& S, char e)
{//符号栈入栈
	if (S.top-S.base==MAXSIZE)
        return ERROR;
    *S.top++=e;//元素e入栈
	return OK;
}
int Pop1(SqStack1& S)
{//符号栈出栈
	char e;
    if (S.top==S.base) return ERROR;
    e=*--S.top;
	return OK;
}
char GetTop1(SqStack1 S)
{//符号栈取栈顶元素
	char e;
    if (S.top==S.base) return ERROR;
    e=*(S.top-1);
	return e;
}
typedef struct
{//数字栈
	double* base;
	double* top;
	int  stacksize;
}SqStack2;
int InitStack2(SqStack2& S)
{//数字栈初始化
    S.base=new double[MAXSIZE];
    if (!S.base) exit(OVERFLOW);
    S.top=S.base;
    S.stacksize=MAXSIZE;
	
	return OK;
}
int Push2(SqStack2& S, double e)
{//数字栈入栈
	if (S.top-S.base==MAXSIZE)//栈满
    return ERROR;
    *S.top++=e;//e入栈
	return OK;
}
int Pop2(SqStack2& S)
{//数字栈出栈
	    double e;
    if (S.top == S.base) return ERROR;
    e = *--S.top;
	return OK;
}
double GetTop2(SqStack2 S)
{//数字栈取栈顶元素
	double e;
    if (S.top == S.base) return ERROR;
    e = *(S.top - 1);
    return e;
}
double Calculate(double a, char op, double b)
{//算术表达式的求值		a在前,b在后
    switch(op)
    {
    case '+':return a+b;
    break;
    case '-':return (a-b);
    break;
    case '*':return(a*b);
    break;
    case '/':return(a/b);
    break;
    }
   
}
char Precede(char theta1, char theta2)
{//比较符号优先级
	if ((theta1 == '(' && theta2 == ')') || (theta1 == '=' && theta2 == '=')) {
		return '=';
	} else if (theta1 == '(' || theta1 == '=' || theta2 == '(' || (theta1
			== '+' || theta1 == '-') && (theta2 == '*' || theta2 == '/')) {
		return '<';
	} else
		return '>';
}

(主函数文件不可编辑)

#include "head.h"
int main()
{
	char s[100];
	while(cin>>s)
	{
		if(s[0]=='=') break;
		SqStack1 op;
		InitStack1(op);
		SqStack2 data;
		InitStack2(data);
		Push1(op,'=');
		//提前在符号栈中放入'=',便于以后比较符号优先级
		int i,x=0,e=0,flag=0;
		//x和e辅助存储double型数据
		//flag用于判断某个double类型数据是否处理完,1表示未完成,0表示完成
		for(i=0;s[i]!='\0';i++)
		{
			if('0'<=s[i]&&s[i]<='9')
			{
				flag=1;
				x=x*10+(s[i]-'0');//x存储去掉小数点的数据,如原数据1.23,最终得到的x为123
				if(e!=0) e=e*10;//小数点后有几位,e扩大为10的几倍
			}
			else if(s[i]=='.')
				e=1;
			else
			{
				if(flag!=0)
				{
					double number=x;
					if(e!=0) number=number/e;
					//如果其间有小数点出现,number缩小对应的倍数
					Push2(data,number);//将double类型数据入栈
					x=e=flag=0;//复原x、e、flag
				}
				while(1)
				{
					if(Precede(GetTop1(op),s[i])=='<')
					{//符号栈栈顶元素优先级低于当前符号,将当前符号入栈
						Push1(op,s[i]);
						break;
					}
					else if(Precede(GetTop1(op),s[i])=='>')
					{//符号栈栈顶元素优先级高于当前符号,出栈计算,所得结果重新入栈
						double b=GetTop2(data);
						Pop2(data);
						double a=GetTop2(data);
						Pop2(data);//将数字栈顶端的两个元素出栈
						char oper=GetTop1(op);
						Pop1(op);//将符号栈顶端的一个符号出栈
						Push2(data,Calculate(a,oper,b));//将运算结果压入数字栈
					}
					else
					{//其余情况时,将符号栈栈顶元素出栈
						Pop1(op);
						break;
					}
				}
			}
		}
		printf("%.2f\n",GetTop2(data));
	}
	return 0;
}

  • 11
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
是一种后进先出(LIFO)的数据结构,可以用来处理中缀算术表达式求值。具体的算法流程如下: 1. 定义两个,一个用来存放操作数,一个用来存放操作符。 2. 从左到右遍历中缀表达式的每个字符,对于每个字符执行以下操作: 1. 如果是数字,直接压入操作数。 2. 如果是左括号,直接压入操作符。 3. 如果是右括号,则一直从操作符中弹出操作符,并从操作数中弹出相应的操作数,直到遇到左括号为止。将弹出的操作数和操作符进行运算,将结果再压入操作数。 4. 如果是操作符,则首先比较它的优先级和操作符顶元素的优先级。如果它的优先级较高或者操作符为空,则直接压入操作符,否则从操作符中弹出操作符,并从操作数中弹出相应的操作数,将它们进行运算,将结果再压入操作数。然后将当前操作符压入操作符。 3. 重复执行步骤2,直到处理完所有的字符。 4. 当操作符不为空时,一直从操作符中弹出操作符,并从操作数中弹出相应的操作数,将它们进行运算,将结果再压入操作数。 5. 最后操作数中只剩下一个元素,就是表达式。 以下为Python代码实现: ``` python def infix_eval(expression): # 定义操作符优先级 priority = {'+': 1, '-': 1, '*': 2, '/': 2, '(': 0, ')': 0} # 定义操作数和操作符 operands = [] operators = [] # 开始遍历中缀表达式 for char in expression: if char.isdigit(): operands.append(int(char)) elif char == '(': operators.append(char) elif char == ')': while operators[-1] != '(': op = operators.pop() b = operands.pop() a = operands.pop() result = eval(str(a) + op + str(b)) operands.append(result) operators.pop() elif char in priority: while operators and priority[char] <= priority[operators[-1]]: op = operators.pop() b = operands.pop() a = operands.pop() result = eval(str(a) + op + str(b)) operands.append(result) operators.append(char) # 处理剩余的操作符 while operators: op = operators.pop() b = operands.pop() a = operands.pop() result = eval(str(a) + op + str(b)) operands.append(result) return operands[0] ``` 可以测试以下代码: ``` python expression = '3+4*5-(2+3*2)' result = infix_eval(expression) print(f'{expression} = {result}') ``` 输出结果: ``` 3+4*5-(2+3*2) = 13 ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

汤米尼克

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

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

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

打赏作者

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

抵扣说明:

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

余额充值