首页 > 其他分享 >算术表达式求值法(表达式求值)之前序表示法求值

算术表达式求值法(表达式求值)之前序表示法求值

时间:2023-09-25 23:33:18浏览次数:46  
标签:运算符 char 前序 表示法 求值 stack 表达式

概念

前序表示法,也称为前缀表示法或波兰表示法(Polish notation),是一种用于表示数学表达式和算术运算的方法。这种表示法的特点是将运算符置于操作数之前,而不是像传统的中缀表示法(例如,2 + 3)将运算符置于操作数之间。前序表示法具有一些优点,尤其在计算机科学和计算器设计中非常有用。下面详细解释前序表示法的特点和优点:

  1. 运算符在前:在前序表示法中,运算符出现在操作数之前。例如,加法操作符“+”写在两个操作数之前,如+ 2 3。这种顺序让解析器或计算机可以更容易地理解和处理表达式,因为它不需要像中缀表示法那样考虑运算符的优先级和括号的嵌套。

  2. 没有括号:前序表示法不需要括号来明确指定运算的顺序,因为运算符的位置已经清晰地表明了运算的顺序。这减少了编写和解析表达式时的复杂性,并避免了由于错误的括号使用而导致的问题。

  3. 一致性:前序表示法在整个表达式中保持了一致的结构,每个运算符都紧随在其操作数之前。这种一致性有助于编写计算机程序来处理这种类型的表达式,因为解析过程可以更容易地建立递归结构。

  4. 简化计算:前序表示法使得计算机程序可以使用堆栈(stack)数据结构来轻松地执行计算。解析器可以按顺序读取表达式中的符号,将操作数推入堆栈,并在遇到运算符时从堆栈中弹出操作数执行计算。这种方法非常高效,尤其对于计算器和编程语言中的表达式求值非常有用。

  5. 避免二义性:前序表示法消除了中缀表示法中由于运算符优先级和括号嵌套而导致的二义性。每个操作符都有一个明确定义的位置,使得表达式的含义变得清晰。

虽然前序表示法在计算机科学和计算器设计中有一些优点,但它在人类用户之间的广泛使用相对较少,因为它需要人们更多地适应非传统的表达方式。然而,它在某些领域,如计算机编程、逆波兰表示法的计算器和某些计算机科学应用中非常有用。

python示例

 1 def evaluate_prefix(expression):
 2     stack = []  # 创建一个空栈用于辅助计算
 3 
 4     # 遍历表达式的每个元素(从右到左)第1个元素是4,第2个是2,第3个是3,第4个*,第5个+
 5     for element in reversed(expression):  # 通过reversed函数让列表反序
 6         if element.isdigit() or (element[0] == '-' and element[1:].isdigit()):
 7             # 如果元素是数字或负数,将其转换为整数并入栈
 8             stack.append(int(element))
 9         else:
10             # 如果元素是运算符,则从栈中弹出两个操作数进行计算
11             operand1 = stack.pop()
12             operand2 = stack.pop()
13 
14             if element == '+':
15                 result = operand1 + operand2
16             elif element == '-':
17                 result = operand1 - operand2
18             elif element == '*':
19                 result = operand1 * operand2
20             elif element == '/':
21                 result = operand1 / operand2
22 
23             # 将计算结果入栈
24             stack.append(result)
25 
26     # 最终栈中剩下的元素就是表达式的计算结果
27     return stack[0]
28 
29 
30 expression = ['+', '*', '3', '2', '4']  # 对应表达式为 3 * 2 + 4
31 result = evaluate_prefix(expression)
32 print("表达式结果:", result)  # 10

中序表示法转前序表示法

 1 def infix_to_prefix(expression):
 2     # 定义操作符优先级,数字越大越优先
 3     precedence = {'+': 1, '-': 1, '*': 2, '/': 2, '^': 3}
 4     operators = "+-*/^"
 5     stack = []
 6     output = []  # 结果
 7 
 8     # 判断是否是操纵符
 9     def is_operator(char):
10         return char in operators
11 
12     # 判断操作符的优先级
13     def has_higher_precedence(op1, op2):
14         return precedence[op1] > precedence[op2]
15 
16     for char in reversed(expression):
17         if char.isalnum():
18             output.append(char)
19         elif char == ')':
20             stack.append(char)
21         elif char == '(':
22             while stack and stack[-1] != ')':
23                 output.append(stack.pop())
24             stack.pop()
25         elif is_operator(char):
26             # 当前字符没有栈顶字符优先大
27             while stack and stack[-1] != ')' and has_higher_precedence(stack[-1], char):
28                 output.append(stack.pop())
29             stack.append(char)
30 
31     while stack:
32         output.append(stack.pop())
33 
34     return ''.join(reversed(output))  # 顺序要反过来
35 
36 
37 # 测试
38 infix_expression = "2 + 3 * 4"
39 prefix_expression = infix_to_prefix(infix_expression)
40 print("前序表示法:", prefix_expression)  # 前序表示法: +2*34

 

标签:运算符,char,前序,表示法,求值,stack,表达式
From: https://www.cnblogs.com/allenxx/p/17729130.html

相关文章

  • 正则表达式输入中文英文名
    请输入正确的姓名,支持中文或者英文(20位字符内),例如:杨颖/^([\u4e00-\u9fa5]{1,20}|[a-zA-Z\.\s]{1,20})$/如果想要支持名字中间输入·和.这样写,例如:迪丽热巴·迪力木拉提/^[\u4e00-\u9fa5a-zA-Z·.]+$/......
  • 正则表达式
    #按照邮件地址的格式(用户名@域名.后缀)来编写正则表达式#该正则表达式中包含了四个部分:#1.用户名:由一个或多个字母、数字、下划线、点、减号组成,且必须以字母或数字开头(用于描述用户名的部分用小括号括起来)#2.@符号:该部分只包含一个@符号#3.域名:由一个或多个字母、数字......
  • Java 8 Lambda 表达式解析
    Lambda表达式,也可称为闭包,它是推动Java8发布的最重要新特性。使用Lambda表达式可以使代码变的更加简洁紧凑。坦白的说,初次看见Lambda表达式瞬间头就大了,为了更好的理解,我们可以把Lambda表达式当作是一种匿名函数(对Java而言这并不完全正确,但现在姑且这么认为),简单地说,就是......
  • 算术表达式的表示法(即求值法)
    说明算术表达式的表示法有多种,其中最常见的包括中缀表达法、前缀表达法和后缀表达法。这些表示法用于表示和求解数学表达式,它们在计算机科学和数学领域都有广泛的应用。中缀表达法、前缀表达法和后缀表达法是操作符的位置来分类的。操作符位于2个操作之间叫中缀表达法,操作符位于......
  • Bash-正则表达式
    一.正则表达式与通配符通配符:用来匹配符合条件的文件名(完全匹配),ls、find、cp这些命令不支持正则表达式,所以只能用通配符正则表达式:用来匹配符合条件的字符串(包含匹配),grep、awk、sed等命令支持正则表达式常用通配符:*(任意字符重复任意多次)、?、[]二.基础正则表达式*(匹配前一个......
  • Python 正则表达式
    正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配。Python自1.5版本起增加了re模块,它提供Perl风格的正则表达式模式。re模块使Python语言拥有全部的正则表达式功能。compile函数根据一个模式字符串和可选的标志参数生成一个正则表达式对象......
  • 在 Shell命令中,通常会使用通配符表达式来匹配一些文件
    #在Shell命令中,通常会使用通配符表达式来匹配一些文件*,?,[],{}例:字符含义实例匹配0或多个字符a*ba与b之间可以有任意长度的任意字符,也可以一个也没有,如aabcb,axyzb,a012b,ab。?匹配任意一个字符......
  • Rust的语句和表达式
    在Java中经常听到类似赋值语句、lambda表达式的说法,却从来没有在意过所谓的语句和表达式有什么区别,而在实际的使用中,它们好像确实没啥区别,但是在Rust中,语句和表达式就被严格区分开来了,《Rust程序设计语言》中提到Rust的函数体是由一系列语句和一个可选的结尾表达式来构成。Rust......
  • [leetcode] 10. 正则表达式匹配
    10.正则表达式匹配给你一个字符串s和一个字符规律p,请你来实现一个支持'.'和'*'的正则表达式匹配。'.'匹配任意单个字符'*'匹配零个或多个前面的那一个元素所谓匹配,是要涵盖整个字符串s的,而不是部分字符串。示例1:输入:s="aa",p="a"输出:false解释:"a"无......
  • 常用正则表达式
    一、校验数字的表达式数字:[1]*$n位的数字:^\d{n}$至少n位的数字:^\d{n,}$m-n位的数字:^\d{m,n}$零和非零开头的数字:^(0|[1-9][0-9]*)$非零开头的最多带两位小数的数字:^([1-9][0-9]*)+(.[0-9]{1,2})?$带1-2位小数的正数或负数:^(-)?\d+(.\d{1,2})$正数、负数、和小数:^(-|+)?\d......