BJFU 244基于栈的后缀算术表达式求值(要特别注意输入问题!!因为空格的输入卡了好久)

该程序使用栈结构处理后缀表达式,读取用户输入的后缀表达式,按照运算符进行相应的加、减、乘、除运算,最终输出表达式的计算结果。程序通过遇到字符就进行运算的方式来处理表达式,并在遇到=时结束输入。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在这里插入图片描述
!!后缀表达式的基本思想:只要遇见了字符,就取出栈的两个数据进行运算

## 描述

从键盘上输入一个后缀表达式,试编写算法计算表达式的值。规定:后缀表达式的长度不超过一行,以“=”作为输入结束,操作数之间用空格分隔,操作符只可能有+、−、*/四种运算。

输入

多组数据,每组数据一行,对应一个后缀算术表达式,每个表达式均以“=”结尾。当表达式只有一个“=”时,输入结束。

输出

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




#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring>
using namespace std;
#define MAX 100

typedef struct {
	double *base;
	double *top;
	int maxsize;
}Stack;

void Initstack(Stack &mysatck) {
	mysatck.base = new double[MAX];
	mysatck.top = mysatck.base;
	mysatck.maxsize = MAX;
}

double top(Stack mysatck) {
	return *(mysatck.top - 1);
}

void push(Stack &mystack, double e) {  //默认栈不满
	*(mystack.top) = e;
	mystack.top++;
}

void pop(Stack &mystack) { //判空
	mystack.top--;
}

void Calculate(Stack &mystack, char c) {
	if (c == '+') {
		double b = top(mystack); //右
		pop(mystack);
		double a = top(mystack); //左
		pop(mystack);
		double sum = a + b;
		push(mystack, sum);
	}
	else if (c == '-') {
		double b = top(mystack); //右
		pop(mystack);
		double a = top(mystack); //左
		pop(mystack);
		double sum = a - b;
		push(mystack, sum);
	}
	else if (c == '*') {
		double b = top(mystack); //右
		pop(mystack);
		double a = top(mystack); //左
		pop(mystack);
		double sum = a * b;
		push(mystack, sum);
	}
	else if (c == '/') {
		double b = top(mystack); //右
		pop(mystack);
		double a = top(mystack); //左
		pop(mystack);
		double sum = a / b;
		push(mystack, sum);
	}
}

int main() {
	char s[100];
	while (true)//这里由于需要读入空格,因此用cin,scanf读入不方便(遇见空格自动停止)
	{
		fgets(s, 100, stdin); //读取一整行,包括换行符\n
		if (s[0] == '=') 
			break;

		Stack mystack;
		Initstack(mystack);//建栈+初始化

		for (int i = 0; s[i] != '='; i++) {
			if (s[i] >= '0'&&s[i] <= '9') { //数字入栈
				double num = atof(s + i);
				push(mystack, num);
	   /*  while ((s[i] >= '0' && s[i] <= '9') || s[i] == '.')  //涉及到小数时可用
				{
					i++;  //寻找数字的组成部分
				}
				i--; //回到遍历的数字de末尾	
         */
			}
			//空格跳过
			else if (s[i] == ' ')
				continue;

			else  //运算符
			{
				char c = s[i];
				Calculate(mystack, c); //计算
			}
		}
		printf("%.2lf\n", top(mystack));//最后的栈顶元素 即为结果
		pop(mystack);
	}
}

### 基于的中缀算术表达式求值 基于的中缀算术表达式求值是一种经典的算法设计问题,其核心在于利用两个分别存储操作数和运算符来处理复杂的优先级关系。以下是该算法的设计思路以及其实现方法。 #### 算法原理 为了直接对中缀表达式进行计算而不将其转换为其他形式(如后缀或前缀),可以采用双结构: - **操作数**用于保存参与运算的具体数值。 - **运算符**用于管理待执行的操作及其优先级顺序。 当解析到一个新的字符时,依据它是数字还是运算符采取不同的动作: 1. 如果当前字符是一个数字,则读取完整的浮点数并压入操作数[^1]。 2. 若遇到左括号`(`,则直接推入运算符作为边界标记[^2]。 3. 对于右括号`)`,持续弹出运算符中的元素直到找到对应的左括号为止,在此过程中完成相应的计算并将结果重新存回操作数。 4. 当碰到普通的运算符(加减乘除)时,需比较它与顶现有运算符之间的优先级别决定是否立即展开计算或者等待后续更高级别的指令到来后再做进一步判断。 #### 实现细节 下面给出了一种可能的语言实现方式——Python版本: ```python def precedence(op): """定义各运算符的优先级""" if op in ('+', '-'): return 1 elif op in ('*', '/'): return 2 else: # '(' or ')' return 0 def apply_operation(a, b, operator): """应用指定运算符至a,b两数上""" if operator == '+': return a + b elif operator == '-': return a - b elif operator == '*': return a * b elif operator == '/': if b != 0: return a / b raise ZeroDivisionError('Cannot divide by zero') def evaluate(expression): numbers = [] # 存储操作数 operators = [] # 存储运算符 i = 0 # 遍历索引初始化 while i < len(expression): char = expression[i] if char.isdigit() or (char == '.' and any(c.isdigit() for c in expression[i:i+2])): num_str = "" decimal_found = False # 提取出整个连续的数字串 while i < len(expression) and ((expression[i].isdigit()) or (expression[i]=='.')): if expression[i]=='.':decimal_found=True num_str += expression[i] i+=1 number=float(num_str) if not(decimal_found)and int(number)==number:number=int(number)# 整形化整型数据 numbers.append(number) elif char == '(': operators.append(char) elif char == ')': while operators[-1] != '(': val2 = numbers.pop() val1 = numbers.pop() operation = operators.pop() result = apply_operation(val1, val2, operation) numbers.append(result) operators.pop() # 移除'(' elif char in "+-*/": while (operators and operators[-1]!='(' and precedence(operators[-1]) >= precedence(char)): val2 = numbers.pop() val1 = numbers.pop() operation = operators.pop() result = apply_operation(val1, val2, operation) numbers.append(result) operators.append(char) i += 1 while operators: val2 = numbers.pop() val1 = numbers.pop() operation = operators.pop() result = apply_operation(val1, val2, operation) numbers.append(result) return numbers[0] # 测试样例 expr = "3 + (5.5 * 2) - 8" print(f"The value of '{expr}' is {evaluate(expr)}") #[^1] ``` 上述代码实现了基本功能,并通过函数封装提高了可维护性和扩展性。注意这里假设输入字符串已经经过适当清理去除空白字符等干扰因素。 #### 注意事项 - 处理异常情况非常重要,比如非法输入、除零错误等情况都应在实际部署环境中加以考虑。 - 此外还需确保所有使用的库均支持所需的精度范围以满足题目对于double类型的约束条件.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值