四则运算(后缀表达式的应用)

一、引入

在程序中实现四则运算,我们不仅需要考虑加减乘除的顺序,还需要考虑括号的问题,这使得我们的程序非常麻烦,但基于这种数据结构,我们可以很方便的进行操作。

例如:中缀表达式 9+(3-1)*3+10/2,我们可以把它化为后缀表达式(也叫逆波兰表达式) 9 3 1 - 3 * + 10 2 / + 对于这样一串表达式,我们可以用栈来对它进行操作。

二、运用

基本思想是:

对于每一个元素,如果是数字,则入栈,如果是符号,则将栈顶的两个元素取出进行运算,再将运算结果入栈。

运算过程:

1、先将 9 3 1 入栈,下一个元素是减号,则将3 和1 取出,进行3 - 1 = 2 ,再将2入栈
2、将3 入栈后,下一个元素是乘号,则进行2 * 3 = 6 ,再将6入栈
3、进行9 + 6 = 15 然后入栈,10 、2 入栈后进行10 / 2 = 5 入栈,再进行15 + 5 = 20
最终得出答案等于20;

中缀表达式转换为后缀表达式

从左到右依次遍历中缀表达式,如果是数字则输出,如果是符号,则判断当前符号与此时栈顶的符号的优先级,若当前符号优先级高于栈顶,则入栈,否则将栈内符号全部出栈,将当前符号入栈;

过程
接下来引用《大话数据结构》里的图片:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

四、代码

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<algorithm>
#include<cmath>
#include<stack>
using namespace std;
typedef long long ll;
stack <char> st1;
stack <int> st2;
int fun(char c)		//判断符号的优先级
{
	if (c == '+' || c == '-')
		return 1;
	else if (c == '*' || c == '/')
		return 2;
	else
		return 3;
}
void js(char c)		//将栈顶两个数拿出来计算,并将结果压入栈中
{
	int b = st2.top();
	st2.pop();
	int a = st2.top();
	st2.pop();
	int tmp = 0;
	if (c == '+')
		tmp = a + b;
	else if (c == '-')
		tmp = a - b;
	else if (c == '*')
		tmp = a * b;
	else
		tmp = a / b;
	st2.push(tmp);
}
int main()
{
	string a;
	getline(cin, a);		//以字符串的形式输入
	int l = a.length();
	for (int i = 0; i < l; i++)
	{
		if (a[i] >= '0' && a[i] <= '9')
		{
			int tmp = 0;
			while (a[i] >= '0' && a[i] <= '9')
			{
				tmp = tmp * 10 + a[i] - '0';
				if (a[i + 1] >= '0' && a[i + 1] <= '9')
					i++;
				else break;
			}
			st2.push(tmp);	//可以读入多位数字
		}
		else
		{
			if (st1.empty())
				st1.push(a[i]);
			else
			{
				if (fun(a[i]) >= fun(st1.top())||fun(st1.top())==3)
				{
					st1.push(a[i]);
					if (a[i] == ')')		//	遇到括号则将左括号之前的符号全部输出进行运算
					{
						st1.pop();
						while (st1.top() != '(')
						{
							js(st1.top());
							st1.pop();
						}
						st1.pop();
					}
				}
				else
				{
					while (!st1.empty())		//如果当前符号优先级比栈顶的优先级小,则将栈中所有符号进行运算并将当前符号压入栈中
					{
						js(st1.top());
						st1.pop();
					}
					st1.push(a[i]);
				}
			}
		}
	}
	while (!st1.empty())		//	将剩余符号进行运算
	{
		js(st1.top());
		st1.pop();
	}
	cout << st2.top();
	return 0;
}
//9+(3-1)*3+10/2
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
好的,这是一个比较完整的代码,包括了输入、转换、计算和输出的过程。可以直接在Visual Studio 2019中新建一个C语言控制台应用程序,将以下代码复制到main函数中即可。 ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #define MAXSIZE 100 // 定义栈的最大容量 // 定义运算符优先级 int priority(char op) { switch (op) { case '+': case '-': return 1; case '*': case '/': return 2; default: return 0; } } // 中缀表达式转换为后缀表达式 int infix2postfix(char *infix, char *postfix) { char stack[MAXSIZE]; // 定义栈 int top = -1; // 栈顶指针 int i = 0, j = 0; // i遍历输入的中缀表达式,j指向输出的后缀表达式 while (infix[i] != '\0') { if (isdigit(infix[i])) { postfix[j++] = infix[i++]; while (isdigit(infix[i])) { // 处理多位数字 postfix[j++] = infix[i++]; } postfix[j++] = ' '; // 数字后面加个空格 } else if (infix[i] == '(') { stack[++top] = infix[i++]; } else if (infix[i] == ')') { while (stack[top] != '(') { postfix[j++] = stack[top--]; postfix[j++] = ' '; } top--; // 弹出左括号 i++; } else if (infix[i] == '+' || infix[i] == '-' || infix[i] == '*' || infix[i] == '/') { while (top >= 0 && priority(stack[top]) >= priority(infix[i])) { postfix[j++] = stack[top--]; postfix[j++] = ' '; } stack[++top] = infix[i++]; } else { // 忽略空格等非法字符 i++; } } while (top >= 0) { // 将栈中剩余的运算符弹出 postfix[j++] = stack[top--]; postfix[j++] = ' '; } postfix[j] = '\0'; // 后缀表达式字符串以'\0'结尾 return 0; } // 计算后缀表达式 int calc_postfix(char *postfix, double *result) { double stack[MAXSIZE]; // 定义栈 int top = -1; // 栈顶指针 int i = 0; double x, y, z; while (postfix[i] != '\0') { if (isdigit(postfix[i])) { sscanf(postfix + i, "%lf", &z); // 从字符串中读取数字 stack[++top] = z; // 数字入栈 while (isdigit(postfix[i]) || postfix[i] == '.') { // 跳过数字 i++; } i++; // 跳过空格 } else if (postfix[i] == '+' || postfix[i] == '-' || postfix[i] == '*' || postfix[i] == '/') { y = stack[top--]; // 弹出栈顶元素 x = stack[top--]; switch (postfix[i++]) { case '+': z = x + y; break; case '-': z = x - y; break; case '*': z = x * y; break; case '/': z = x / y; break; } stack[++top] = z; // 运算结果入栈 } else { // 忽略空格等非法字符 i++; } } *result = stack[top]; // 最终结果为栈中唯一元素 return 0; } int main() { char infix[MAXSIZE], postfix[MAXSIZE]; double result; printf("请输入中缀表达式:\n"); fgets(infix, MAXSIZE, stdin); // 从标准输入中读取一行字符 infix2postfix(infix, postfix); printf("后缀表达式为:%s\n", postfix); calc_postfix(postfix, &result); printf("计算结果为:%f\n", result); return 0; } ``` 这个程序可以处理整数和小数的四则运算表达式,支持加、减、乘、除、括号等运算符,可以自动跳过空格等非法字符。使用时只需要在控制台中输入中缀表达式,程序会自动输出后缀表达式和计算结果。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

橘落京城

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

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

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

打赏作者

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

抵扣说明:

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

余额充值