【无标题】详解中缀表达式转化为后缀表达式并求值,附代码解释

uploading.4e448015.gif

正在上传…重新上传取消

 搜索

uploading.4e448015.gif

正在上传…重新上传取消

会员中心 

足迹

动态

消息

创作

详解中缀表达式转化为后缀表达式并求值,附代码解释

uploading.4e448015.gif

正在上传…重新上传取消

CoAAColA

uploading.4e448015.gif

正在上传…重新上传取消于 2021-03-10 15:27:44 发布100 收藏

分类专栏: c++ 文章标签:  c++

版权

​c++专栏收录该内容

19 篇文章0 订阅

订阅专栏

思路

首先我们需要知道如何转化表达式并求值:首先不同的运算符有不同的优先级:对于(,),优先级最高,其次是*,/,最低是+,-。在从左往右扫描字符串时,遇到数字,就将其直接压入数组中。遇到操作符时,如果当前为空,那么直接压入中,如果不为空,那么将栈顶操作符优先级大于等于当前操作符的操作符pop出,并压入数组,直到栈顶操作符优先级小于当前操作符或为空才停止此次操作,并将当前操作符压入中。
由于在我的代码中遇到左括号是直接递归,右括号return,因此上面的处理中不需要考虑括号。
得到表达式后,我们就需要进行求值,首先我们得到的是一个数组,其中按后缀表达式中的顺序存储着操作符以及数字。那么我们从左往右遍历数组,当遇到数字时,将其压入栈中,遇到操作符时,在栈中提取出两个元素,并将两个元素根据操作符计算得到的值压入栈中,最后栈顶元素即为表达式的值。

代码

#include <iostream>
#include <stack>
#include <string>
#include <vector>

using namespace std;

void showAndPush(vector<string> &expr, const string &s, char t = ' ') {
	expr.push_back(s);
	cout << s << t;
}

bool isOper(const string &s) { //数组中可能出现-2,+2等元素,因此size()==1为前提。
	return s.size() == 1 && (s[0] == '+' || s[0] == '-' || s[0] == '*' || s[0] == '/');
}

int cal(int num, int num1, char oper) {
	switch (oper) {
	case '+': return num + num1;
	case '-': return num - num1;
	case '*': return num * num1;
	case '/': return num / num1;
	}
}

//将输入的中缀表达式转化为后缀表达式
void infixToSuffix(int &p, const string &text, vector<string> &expr) {
	stack<char> stk;
	int len = text.length(), pre = expr.size();
	for (; p < len; ++p) {
		switch (text[p]) {
		case '+':
		case '-':
			while (!stk.empty()) {
				expr.emplace_back(1, stk.top());
				cout << stk.top(); stk.pop();
			}
			stk.push(text[p]);
			break;
		case '*':
		case '/':
			while (!stk.empty() && (stk.top() == '*' || stk.top() == '/')) {
				expr.emplace_back(1, stk.top());
				cout << stk.top(); stk.pop();
			}
			stk.push(text[p]);
			break;
		case '(':
			infixToSuffix(++p, text, expr); //遇到左括号就递归,将括号中的表达式当成一个独立的表达式,即可解决优先级的问题
			break;
		case ')':
			while (!stk.empty()) {
				showAndPush(expr, string(1, stk.top()));
				stk.pop();
			}
			return;
		case ' ': //遇到空格直接跳过不用处理
			break;
		default:
			string num;
			if (pre == expr.size() && !stk.empty()) { //这条if语句用于处理-2,(+2)等情况。这种情况下-+不算操作符。
				num.push_back(stk.top());
				stk.pop();
			}
			while (isdigit(text[p])) {
				num.push_back(text[p]);
				++p;
			}
			--p;
			showAndPush(expr, num);
		}
	}
	while (!stk.empty()) { //将栈中剩下的操作符全部压入数组中
		showAndPush(expr, string(1, stk.top()));
		stk.pop();
	}
}

int calculate(const vector<string> &expr) { //根据后缀表达式数组进行求值。
	stack<int> num;
	for (auto &iter : expr) {
		if (isOper(iter)) { //遇到操作符就将栈顶的两个元素出栈并求值,将结果再压入栈中,注意两个元素的顺序。
			int t = num.top(); num.pop();
			int t1 = num.top(); num.pop();
			num.push(cal(t1, t, iter[0]));
		} else {
			num.push(stoi(iter));
		}
	}
	return num.top(); //栈顶元素即为结果
}

void sln() {
	string text;
	getline(cin, text);
	vector<string> expr;
	int p = 0;
	infixToSuffix(p, text, expr); //将中缀表达式转化为后缀表达式
	cout << endl;
	cout << calculate(expr) << endl; //对后缀表达式求值
}

int main() {
	sln();
	return 0;
}


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108

创作打卡挑战赛正在上传…重新上传取消

赢取流量/现金/CSDN周边激励大奖

正在上传…重新上传取消CoAAColA

已关注

  • uploading.4e448015.gif

    正在上传…重新上传取消0
  • uploading.4e448015.gif

    正在上传…重新上传取消
  • 正在上传…重新上传取消0
  • uploading.4e448015.gif

    正在上传…重新上传取消0
  • uploading.4e448015.gif

    正在上传…重新上传取消
  • uploading.4e448015.gif

    正在上传…重新上传取消

专栏目录

uploading.4e448015.gif

正在上传…重新上传取消

uploading.4e448015.gif

正在上传…重新上传取消

uploading.4e448015.gif

正在上传…重新上传取消

相关推荐

uploading.4e448015.gif

正在上传…重新上传取消

c语言实现中缀表达式转后缀并求值

04-09

c语言实现中缀表达式转后缀表达式并求得计算结果,用顺序栈结构。 当输入者输入错误信息的时候需要报错,并说明错误的种类。

uploading.4e448015.gif

正在上传…重新上传取消

【数据结构】中缀表达式转后缀表达式求值

这里是Mae。

uploading.4e448015.gif

正在上传…重新上传取消 362

后缀表达式求值 首先需要将输入的中缀表达式转换成后缀表达式。 后缀表达式中,操作符在后 例如:1+2*(5-3)+4 后缀表达式:1253-*+4+ 1、中缀表达式转换成后缀表达式方法: 首先,需要定义一个操作符栈并且知道各运算符优先级,然后从左往右一次扫描字符(字符前后加#号),遇到数字直接输出,遇到操作符比较优先级。 栈顶优先级低,入栈; 栈顶优先级高,出栈并且输出; 优先级相等(即左右括号),出栈(不输出); 当扫描的字符为#并且栈顶字符为#时,此时输出的字符序列即为后缀表达式 2、后缀表达式求值过程

uploading.4e448015.gif

正在上传…重新上传取消

Python中缀表达式转后缀表达式并求值_滑稽研究所的博客...

4-26

  计算中缀表达式验证一下,发现结果正确。   到这里我们就完成了,中缀表达式转后缀表达式并求值的问题。最后需要说一点就是,转换的后缀表达式形式不是唯一的。比如上式我可以先计算24*3,也可以先计算(4-8)。那么就会产生下面...

uploading.4e448015.gif

正在上传…重新上传取消

...求值_leoyongyuan的博客_中缀表达式转后缀表达式并求值

3-10

中缀表达式转后缀表达式求值 慕课MOOC表达式求值 前言 一、后缀表达式是什么? 后缀表达式计算与前缀表达式类似,只是顺序是从左至右,具体过程如下: 从左至右扫描表达式,遇到数字时,将数字压入堆栈,遇到运算符时,弹出栈顶的两个数,用运算...

uploading.4e448015.gif

正在上传…重新上传取消

中缀表达式转换为后缀表达式并求值

qq_53843555的博客

uploading.4e448015.gif

正在上传…重新上传取消 490

中缀表达式转换为后缀表达式并求值 中缀表达式转换为后缀表达式并求值,就是将前两个组合起来。 函数懒得改,直接把两个函数都用上0.0 代码代码如下 #include <stdio.h> #include <stdlib.h> typedef char ElemType; typedef struct status* Status; struct status { ElemType Data; struct status* Next; }; Status Creatst

uploading.4e448015.gif

正在上传…重新上传取消

算术中缀表达式转化成后缀表达式,并利用后缀表达式求值(操作数为个位数)

乘风破浪Now 的博客

uploading.4e448015.gif

正在上传…重新上传取消 2068

算术中缀表达式与后缀表达式 后缀表达式有利于计算机进行计算,中缀表达式有利于人们阅读与表达。 中缀表达式:a+b*c+(d*e+f)*g 对应的后缀表达式:abc*+de*f+g*+ 将中缀表达式转化成后缀表达式 需要利用栈这种数据结构才能完成这一转化,在此用队列来存储后缀表达式: 中缀表达式的入栈规则: 1) 遇到操作数,直接输出到队列; 2)遇到操作符,输出到栈中,这个栈是一个...

uploading.4e448015.gif

正在上传…重新上传取消

中缀表达式转后缀表达式并求值_Gnomeshgh的博客

2-6

中缀表达式转后缀表达式并求值 因为在学校实在是太闲了,所以写了一个表达式求值的C语言程序,希望大佬可以多多指正。 基本思路: 就像把大象装进冰箱一样,我们需要三步进行表达式的求值工作。 输入一个中缀表达式(就是平常我们见的表达式)...

uploading.4e448015.gif

正在上传…重新上传取消

中缀表达式转换为后缀表达式(C语言代码+详解)

苍之羽

uploading.4e448015.gif

正在上传…重新上传取消 5万+

中缀表达式转换为后缀表达式 1.创建栈 2.从左向右顺序获取中缀表达式 a.数字直接输出 b.运算符 情况一:遇到左括号直接入栈,遇到右括号将栈中左括号之后入栈的运算符全部弹栈输出,同时左括号出栈但是不输出。 情况二:遇到乘号和除号直接入栈,直到遇到优先级比它更低的运算符,依次弹栈。 情况三:遇到加号和减号,如果此时栈空,则直接入栈,否则,将栈中优先级高的运算符依次弹栈(注意:加号和减号属于同一个...

uploading.4e448015.gif

正在上传…重新上传取消

C语言中缀表达式转成后缀表达式,并计算它的值

奋斗的龙猫的博客

uploading.4e448015.gif

正在上传…重新上传取消 1868

在C语言中,将中缀表达式转成后缀表达式,并计算它的结果,具体的思路如下: 1、定义两个栈,numStack用于存放运算对象,最后存放运算结果的,fuStack用于存放运算符号的 2、从左到右遍历字符串 3、如果当前的字符是一个数字,那么先不要着急将其转成数字,然后压入到numStack中,因为考虑到多位数字的情况,所以需要从当前下标开始遍历,一直遍历到第一个运算符出现,那么这时候才可以将运算符前面的数字转成字符串。然后调用atoi,将字符串转成一个数字。这时候,将这个数字输出,同时将其压入到numStack

uploading.4e448015.gif

正在上传…重新上传取消

表达式求值(中缀转后缀及后缀表达式求值)

小葱的博客

uploading.4e448015.gif

正在上传…重新上传取消 2万+

。中缀表达式转后缀表达式:中缀表达式转后缀表达式遵循以下原则: 1.遇到操作数,直接输出; 2.栈为空时,遇到运算符,入栈; 3.遇到左括号,将其入栈; 4.遇到右括号,执行出栈操作,并将出栈的元素输出,直到弹出栈的是左括号,左括号不输出; 5.遇到其他运算符’+”-”*”/’时,弹出所有优先级大于或等于该运

uploading.4e448015.gif

正在上传…重新上传取消

中缀表达式转后缀表达式,并求值

MokeeQian的博客

uploading.4e448015.gif

正在上传…重新上传取消 1419

数据结构之栈的应用 先实现求值这一步吧,已知后缀表达式 转换这一环节待更新… 上代码: /* 中缀表达式转后缀表达式(seqstack)以及求值 * version: 1.0(求值,需要自己输入后缀表达式) * 2.0(加上转化功能) * 算法: 创建一个操作数栈,自左向右遍历后缀表达式,遇到一个操作数就入栈, * 遇到一个操作符就从栈中取出两个操作数进行当前计算,...

uploading.4e448015.gif

正在上传…重新上传取消

将中缀表达式转换成后缀表达式并求值(栈)

txj的博客

uploading.4e448015.gif

正在上传…重新上传取消 694

中缀表达式转换成后缀表达式需要用到的是数据结构中的一种——栈。 中缀表达式 : 生活中进行正常加减乘除计算的表达式。如2+(3*4-6/2)。也就是算术表达式 后缀表达式 :也叫逆波兰表达式。只有运算符和数字没有括号,运算符的先后顺序存在优先级的关系。如: 234*62*2+ 。 (由于需要处理字符串的原因,目前只有个位数的算术运算) 给出的算术表达式通过代码实现很难计算出来,而转换成了后缀表达式的就很容易实现出来了。 当然,以下代码是很容易的出计算结果的。 public class Main

uploading.4e448015.gif

正在上传…重新上传取消

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

热门推荐

__七把刀__

uploading.4e448015.gif

正在上传…重新上传取消 14万+

一、后缀表达式求值 后缀表达式也叫逆波兰表达式,其求值过程可以用到栈来辅助存储。假定待求值的后缀表达式为:6  5  2  3  + 8 * + 3  +  *,则其求值过程如下: 1)遍历表达式,遇到的数字首先放入栈中,此时栈如下所示: 2)接着读到“+”,则弹出3和2,执行3+2,计算结果等于5,并将5压入到栈中。 3)读到8,将其直接放入栈中。 4)读到“*”,弹出8和

uploading.4e448015.gif

正在上传…重新上传取消

c语言实现中缀表达式转化为后缀表达式并求值

最新发布

skjgasjd的博客

uploading.4e448015.gif

正在上传…重新上传取消 295

//这里可以我将输入的a-g赋了值 #include <stdlib.h> #include <iostream> using namespace std; typedef char DataType; //采用链式栈 struct node{ DataType element; //数据元素 struct node *next; //指向下一个数据元素的指针 }; typedef struct node *PtrToNode; typedef PtrTo

uploading.4e448015.gif

正在上传…重新上传取消

中缀表达式转后缀表达式求值

wxf明的博客

uploading.4e448015.gif

正在上传…重新上传取消 3525

刚开始想一鼓作气把整个过程全部实现,但白费了那几个小时,调试了半天也没做出来,后来我是通过先实现中缀表达式转化为后缀表达式,然后实现后缀表达式的求值,然后将两块代码进行合成,刚才同学还笑着说:模块化编程。。。 直接在代码中解释。 中缀表达式转后缀表达式: # include <iostream> # include <string> # include &lt...

uploading.4e448015.gif

正在上传…重新上传取消

中缀表达式转换为后缀表达式并求值(python)

太子悦神的博客

uploading.4e448015.gif

正在上传…重新上传取消 168

class Stack(): __slots__ = '__items' def __init__(self): self.__items=[] def push(self,e): self.__items.append(e) def is_empty(self): return self.__items==[] def pop(self): if self.is_empty():

uploading.4e448015.gif

正在上传…重新上传取消

中缀表达式转后缀表达式并计算求值C/C++

linyuan703的博客

uploading.4e448015.gif

正在上传…重新上传取消 1551

//1.遇到操作数,直接输出;  //2.栈为空时,遇到运算符,入栈;  //3.遇到左括号,将其入栈;  //4.遇到右括号,执行出栈操作,并将出栈的元素输出,直到弹出栈的是左括号,左括号不输出;  //5.遇到其他运算符’+”-”*”/’时,弹出所有优先级大于或等于该运算符的栈顶元素,然后将该运算符入栈;  //6.最终将栈中的元素依次出栈,输出。  //经过上面的步骤,得到的输出既是转换得到...

uploading.4e448015.gif

正在上传…重新上传取消

中缀表达式转后缀表达式并求值(多位数)

m0_48508203的博客

uploading.4e448015.gif

正在上传…重新上传取消 729

中缀表达式转后缀表达式并求值(多位数) 一、问题简述 中缀表达式:是一种通用的算术或逻辑公式表示方法,操作符处于操作数的中间。中缀表达式是人们常用的算术表示方法,如3+5*8。 后缀表达式(逆波兰表达式):运算符位于两个相应操作数之后,更方便计算机的运算,如3 5 8 * +。 为了方便计算机的运算,我们需要把中缀表达式转成后缀表达式。(也可直接计算中缀表达式的值) 二、背景题目:中缀表达式的值(北大oj平台) 描述 人们熟悉的四则运算表达式称为中缀表达式,例如(23+34*45/(5+6+7))。

uploading.4e448015.gif

正在上传…重新上传取消

利用栈实现中缀转化成后缀表达式并求值

阿星的博客

uploading.4e448015.gif

正在上传…重新上传取消 1万+

后缀表达式 假设我们计算一个表达式:4*2+5+6*7=,他的计算顺序可以是将4*2的值存为A1,然后将A1和5相加,在将结果存入A1,然后在将6*7的值存为A2,最后将A1和A2相加,并将结果放入A1。那我们可以将这种操作顺序写成这样:4 2*5+6 7*+。这个写法就叫后缀(postfix)或逆波兰(reverse polish)写法。这种写法的在计算机中可以用一个栈来实现:遇见一个数,把他...

uploading.4e448015.gif

正在上传…重新上传取消

中缀表达式转后缀表达式并求值

shengjk1的博客

uploading.4e448015.gif

正在上传…重新上传取消 333

1.什么是中缀表达式? 2.什么是后缀表达式? 3.代码 package xmht.datastructuresandalgorithms.datastructure.stack; import java.util.ArrayList; import java.util.List; import java.util.Stack; /** * @author shengjk1 * @date...

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

  • uploading.4e448015.gif

    正在上传…重新上传取消

    非常没帮助

  • uploading.4e448015.gif

    正在上传…重新上传取消

    没帮助

  • uploading.4e448015.gif

    正在上传…重新上传取消

    一般

  • uploading.4e448015.gif

    正在上传…重新上传取消

    有帮助

  • uploading.4e448015.gif

    正在上传…重新上传取消

    非常有帮助

©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页

uploading.4e448015.gif

正在上传…重新上传取消

CoAAColA

码龄4年正在上传…重新上传取消 暂无认证

58

原创

13万+

周排名

54万+

总排名

1万+

访问

uploading.4e448015.gif

正在上传…重新上传取消

等级

675

积分

17

粉丝

23

获赞

13

评论

19

收藏

uploading.4e448015.gif

正在上传…重新上传取消

uploading.4e448015.gif

正在上传…重新上传取消

私信

已关注

uploading.4e448015.gif

正在上传…重新上传取消

热门文章

分类专栏

uploading.4e448015.gif

正在上传…重新上传取消

最新评论

您愿意向朋友推荐“博客详情页”吗?

  • uploading.4e448015.gif

    正在上传…重新上传取消

    强烈不推荐

  • uploading.4e448015.gif

    正在上传…重新上传取消

    不推荐

  • uploading.4e448015.gif

    正在上传…重新上传取消

    一般般

  • uploading.4e448015.gif

    正在上传…重新上传取消

    推荐

  • uploading.4e448015.gif

    正在上传…重新上传取消

    强烈推荐

最新文章

2021年2篇

2020年24篇

2019年24篇

2018年12篇

uploading.4e448015.gif

正在上传…重新上传取消

uploading.4e448015.gif

正在上传…重新上传取消举报

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
中缀表达式后缀表达式的具体步骤如下: 1. 初始化两个栈:运算符栈s1和储存中间结果的栈s2; 2. 从左至右扫描中缀表达式; 3. 遇到操作数时,将其压s2; 4. 遇到运算符时,比较其与s1栈顶运算符的优先级: 1. 如果s1为空,或栈顶运算符为左括号“(”,则直接将此运算符入栈; 2. 否则,若优先级比栈顶运算符的较高或相等,也将运算符压入s1; 3. 否则,将s1栈顶的运算符弹出并压入到s2中,再次转到(4-1)与s1中新的栈顶运算符相比较; 5. 遇到括号时: 1. 如果是左括号“(”,则直接压入s1; 2. 如果是右括号“)”,则依次弹出s1栈顶的运算符,并压入s2,直到遇到左括号为止,此时将这一对括号丢弃; 6. 重复步骤2至5,直到表达式的最右边; 7. 将s1中剩余的运算符依次弹出并压入s2; 8. 依次弹出s2中的元素并输出,结果的逆序即为中缀表达式对应的后缀表达式。 下面是一个Java实现的例子: ```java import java.util.Stack; public class InfixToPostfix { public static int getPriority(char operator) { switch (operator) { case '+': case '-': return 1; case '*': case '/': return 2; case '^': return 3; default: return 0; } } public static String infixToPostfix(String infix) { Stack<Character> stack = new Stack<>(); StringBuilder postfix = new StringBuilder(); for (int i = 0; i < infix.length(); i++) { char c = infix.charAt(i); if (Character.isDigit(c)) { postfix.append(c); } else if (c == '(') { stack.push(c); } else if (c == ')') { while (!stack.isEmpty() && stack.peek() != '(') { postfix.append(stack.pop()); } stack.pop(); } else { while (!stack.isEmpty() && getPriority(c) <= getPriority(stack.peek())) { postfix.append(stack.pop()); } stack.push(c); } } while (!stack.isEmpty()) { postfix.append(stack.pop()); } return postfix.toString(); } } ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值