首页 > 其他分享 >数据结构笔记之表达式求值

数据结构笔记之表达式求值

时间:2024-07-12 10:56:11浏览次数:10  
标签:操作数 int s2 top2 top1 运符 求值 数据结构 表达式

  1. 概念:运算是由运符和操作数组成的,DIY概念指的是左操作数、右操作数和运符之间的关系。
  2. 中缀表达式:运符位于操作数之间,这是我们日常生活中最常用的表达式形式。
  3. 后缀表达式:运符在操作数后面,这种表达式形式没有括号,易于解析。
  4. 前缀表达式:运符在操作数前面,同样没有括号,但需要遵循不同的规则来解析。

转换过程

  1. 中缀转后缀:按照“左优先”的原则确定运符的运序序列,依次将各个运符和与其相邻的两个操作数压入栈,遇到运符则弹出栈顶的两个操作数进行运算,结果再入栈。注意:先弹出的元素是“右操作数”。这种方法避免了处理括号的问题,使得表达式的求值变得简单。
  2. 后缀转中缀:从左往右扫描,遇到操作数就入栈,遇到运符则弹出栈顶的两个操作数进行运算,结果再入栈。注意:先弹出的元素是“右操作数”。
  3. 中缀转前缀:同理,按照“右优先”的原则确定运符的运序序列,依次将各个运符和与其相邻的两个操作数压入栈,遇到运符则弹出栈顶的两个操作数进行运算,结果再入栈。注意:先弹出的元素是“左操作数”。

计算过程

  1. 对于后缀表达式,从左往右扫描,遇到操作数就入栈,遇到运符则弹出栈顶的两个操作数进行运算,结果再入栈。这样就可以得到最终的结果。
  2. 对于前缀表达式,也是从左往右扫描,遇到操作数就入栈,遇到运符则弹出栈顶的两个操作数进行运算,结果再入栈。但是要注意,这里先弹出的元素是“左操作数”。

利用中缀转后缀求值(c语言):

#include <stdio.h>
#include <string.h>

// 设置符号优先级
int compareReturn(char str1) {
	if (str1 == '+' || str1 == '-') {
		return 1;
	} else if (str1 == '*' || str1 == '/') {
		return 2;
	} else if (str1 == '(') {
		return 3;
	} else {
		// 此时为数字
		return -1;
	}
}

int evaluate(int b, int a, char c) {
	switch (c) {
		case '+':
			return a + b;
			break;
		case '-':
			return a - b;
			break;
		case '*':
			return a * b;
			break;
		case '/':
			return a / b;
			break;
	}
	return 0;
}

int main () {
	char s1[100];
	int top1 = -1;
	int s2[100];
	char top2 = -1;
	char str[100];
	printf("请输入中缀表达式\n");
	scanf("%s", str);
	int length = (int)strlen(str);
	for (int i = 0; i < length; ) {
		if (compareReturn(str[i]) == -1) {
			s2[++top2] = str[i] - '0';
			i++;
		} else if (str[i] == ')') {
			while (s1[top1] != '(') {
				int a1 = s2[top2--];
				int a2 = s2[top2--];
				s2[++top2] = evaluate(a1, a2, s1[top1--]);
			}
			top1--;
			i++;
		} else {

			if (top1 == -1 || compareReturn(s1[top1]) < compareReturn(str[i]) || s1[top1] == '(') {
				s1[++top1] = str[i++];
			} else {
				int a1 = s2[top2--];
				int a2 = s2[top2--];
				s2[++top2] = evaluate(a1, a2, s1[top1--]);
				s1[++top1] = str[i++];
			}

		}
	}

	while (top1 != -1) {
		int a1 = s2[top2--];
		int a2 = s2[top2--];
		s2[++top2] = evaluate(a1, a2, s1[top1--]);
	}
	printf("%d", s2[top2]);

	return 0;

}


标签:操作数,int,s2,top2,top1,运符,求值,数据结构,表达式
From: https://blog.csdn.net/weixin_67855163/article/details/140262836

相关文章

  • Java 算法和数据结构 答案整理,最新面试题
    Java中如何使用动态规划求解背包问题?1、定义子问题:首先确定动态规划状态,通常以物品数量和背包容量为变量定义子问题,例如dp[i][j]表示前i件物品放入容量为j的背包所能获得的最大价值。2、确定状态转移方程:基于是否选择当前物品,将问题分为两个子问题,即dp[i][j]=......
  • 【C++】通讯录管理系统+少量数据结构
    #include<iostream>#include<string>usingnamespacestd;#definemax1000structnewp{ stringname; intsex; intage; stringnumber; stringadd;};structbooks{ structnewpa[max]; intsize;};staticvoidshowMenu(){ cou......
  • 数据结构复习计划之复杂度分析(时间、空间)
    第二节:算法时间复杂度和空间复杂度算法(Algorithm):是对特定问题求解方法(步骤)的一种描述,是指令的有限序列,其中每一条指令表示一个或多个操作。算法可以有三种表示形式: 伪代码 自然语言 流程图算法的五个特性①有穷性:一个算法必须总是在执行有穷步......
  • 【数据结构】双向链表
    Hi~!这里是奋斗的小羊,很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎~~......
  • Go语言---面向对象编程-匿名字段、同名字段、方法、方法集、方法的继承与重写、方法值
    基本概念对于面向对象编程的支持Go语言设计得非常简洁而优雅。因为,Go语言并没有沿袭传统面问对象编程中的诸多概念,比如继承(不支持继承,尽管匿名字段的内存布局和行为类似继承,但它并不是继承)、虚函数、构造所数和析构函数、隐藏的this指针等。尽管Go语言中没有封......
  • 数据结构(复杂度)
    复杂度算法在编写成可执行程序后,运⾏时需要耗费时间资源和空间(内存)资源。因此衡量⼀个算法的好坏,⼀般是从时间和空间两个维度来衡量的,即时间复杂度和空间复杂度。时间复杂度主要衡量⼀个算法的运⾏快慢,⽽空间复杂度主要衡量⼀个算法运⾏所需要的额外空间。在计算机发展的......
  • 正则表达式
    正则表达式RegularExpress【1】、三剑客与正则表达式1、注意事项正则符号都是英文符号,避免使用中文符号推荐使用grep/egrep命令,默认设置了别名alias,自动加上颜色【2】、符号概述正则:regularexpression(RE)正则表达式regularexpression符号基础正则BRE^......
  • cron表达式和crontab表达式
    每次写cron表达式老是迷迷糊糊不敢肯定,特此记录crontab表达式*****分时日月周域值范围域数值字符备注秒[第一位]0~59-*/,-分[第二位]0~59-*/ ,-时[第三位]0~59-*/ ,-日[第四位]1~31-*?/ ,LWC -月[第五位]1~12JAN-DEC[月份简写] -*/ ,-......
  • [C++] C++20约束表达式和requires子句
    约束约束是逻辑操作和操作数的序列,它指定了对模板实参的要求。合取两个约束的合取是用&&运算符。template<typenameT>conceptluser=std::integral<T>&&std::signed_integral<T>;需要约束同时满足两个要求。合取判断的时候,使用短路检测,即对std::integra......
  • 嵌入式学习——C语言数据结构(三)
    七、赋值运算符    1、+=     加且赋值         C += A;等价于C=C+A    2、-=      减且赋值         C -= A;等价于C=C-A    3、*=      乘且赋值      ......