文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

如何理解栈在括号匹配和表达式求值中的应用

2024-04-02 19:55

关注

这篇文章主要讲解了“如何理解栈在括号匹配和表达式求值中的应用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何理解栈在括号匹配和表达式求值中的应用”吧!

编程的本质来源于算法,而算法的本质来源于数学,编程只不过将数学题进行代码化。

算法,一门既不容易入门,也不容易精通的学问。

括号匹配这是Leetcode第20题,也是一道单调栈的简单题。

给定一个只包括'(',')','{','}','[',']'的字符串,判断字符串是否有效。

有效字符串需满足:

输入: "{[]}"输出: true单调栈关键在于如何入栈和出栈。

用栈保存为匹配的左括号,从左到右一次扫描字符串,当扫描到左括号时,则将其压入栈中;当扫描到右括号时,从栈顶取出一个左括号,如果能匹配上,则继续扫描剩下的字符串。如果扫描过程中,遇到不能配对的右括号,或者栈中没有数据,则说明为非法格式。

当所有的括号都扫描完成之后,如果栈为空,则说明字符串为合法格式;否则,说明未匹配的左括号为非法格式。

def isValid(s):     """     :type s: str     :rtype: bool     """     stack = []     paren_map ={')':'(',']':'[','}':'{'}     for c in s:         if c not in paren_map:             stack.append(c)         elif not stack or paren_map[c] !=stack.pop():             return False     return not stack s = input('输入括号字符:') print(isValid(s))

在此题中,也可以利用python种的replace函数将成对的可匹配括号用空字符代替 ,之后依次进行 ,若是有效的括号 ,必然经过有限次循环后  ,字符串为空 ,则最后判断字符串是否为空即可。思路简单,实现也很容易:

def isValid(s):     """     :type s: str     :rtype: bool     """     n = len(s)     if n == 0: return True     while '()' in s or '{}' in s or '[]' in s:         s = s.replace('{}','').replace('[]','').replace('()Val','')     return s == ''

数学表达

式首先,我们来看一下数学表达式的三种形式:前缀表达式,中缀表达式,后缀表达式。

数学表达式的三种形式示例如下:

如何理解栈在括号匹配和表达式求值中的应用

中缀表达式操作符是以中缀形式处于操作数的中间(例:3 + 4),中缀表达式是人们常用的算术表示方法。与前缀表达式(例:+ 1 2)或后缀表达式(例:1 2  +)相比,中缀表达式不容易被计算机解析,但仍被许多程序语言使用,因为它符合人们的普遍用法。

下面问题转为为:如何利用栈实现中缀表达式求值,比如:34+13*9+44-12/3=191思路:利用两个栈,其中一个用来保存操作数,另一个用来保存运算符。

我们从左向右遍历表达式,当遇到数字,我们就直接压入操作数栈;当遇到运算符,就与运算符栈的栈顶元素进行比较。

若比运算符栈顶元素优先级高,就将当前运算符压入栈,若比运算符栈顶元素的优先级低或者相同,从运算符栈中取出栈顶运算符,从操作数栈顶取出2个操作数,然后进行计算,把计算完的结果压入操作数栈,继续比较。

def infix_evaluator(infix_expression : str) -> int :     '''这是中缀表达式求值的函数     :参数 infix_expression:中缀表达式 需要用空格进行隔开     '''     token_list = infix_expression.split()     print(token_list)     # 运算符优先级字典     pre_dict = {'*':3,'/':3,'+':2,'-':2, '(':1}     # 运算符栈     operator_stack = []     # 操作数栈     operand_stack = []     for token in token_list:         # 数字进操作数栈         print(token)         # 10或者-10的情况         if token.isdecimal() or token[1:].isdecimal():              operand_stack.append(int(token))         # 左括号进运算符栈         elif token == '(':             operator_stack.append(token)         # 碰到右括号,就要把栈顶的左括号上面的运算符都弹出求值         elif token == ')':             top = operator_stack.pop()             while top != '(':                 # 每弹出一个运算符,就要弹出两个操作数来求值                 # 注意弹出操作数的顺序是反着的,先弹出的数是op2                 op2 = operand_stack.pop()                 op1 = operand_stack.pop()                 # 求出的值要压回操作数栈                 # 这里用到的函数get_value在下面有定义                 operand_stack.append(get_value(top,op1,op2))                 # 弹出下一个栈顶运算符                 top = operator_stack.pop()         # 碰到运算符,就要把栈顶优先级不低于它的都弹出求值         elif token in '+-*/':             while operator_stack and pre_dict[operator_stack[-1]] >= pre_dict[token]:                 top = operator_stack.pop()                 op2 = operand_stack.pop()                 op1 = operand_stack.pop()                 operand_stack.append(get_value(top,op1,op2))             # 别忘了最后让当前运算符进栈             operator_stack.append(token)     # 表达式遍历完成后,栈里剩下的操作符也都要求值        while operator_stack:         top = operator_stack.pop()         op2 = operand_stack.pop()         op1 = operand_stack.pop()         operand_stack.append(get_value(top,op1,op2))     # 最后栈里只剩下一个数字,这个数字就是整个表达式最终的结果     print(operand_stack)     print(operator_stack)     return operand_stack[0]   def get_value(operator : str, op1 : int, op2 : int):     '''这是四则运算函数     :参数 operator:运算符     :参数 op1:左边的操作数     :参数 op2:右边的操作数     '''     if operator == '+':         return op1 + op2     elif operator == '-':         return op1 - op2     elif operator == '*':         return op1 * op2     elif operator == '/':         return op1 / op2   # 用一个例子试试,得出了结果  17.0 print(infix_evaluator('9 + ( 3 - 1 * 2 ) * 3 + 10 / 2'))  17.0

上述程序只是使用四则运算表达式进行学习计算,但是输入需要加空格进行分隔,比如9 + ( 3 - 1 * 2 ) * 3 + 10 / 2分隔为['9',  '+', '(', '3', '-', '1', '*', '2', ')', '*', '3', '+', '10', '/', '2']。

后来尝将9+(3-1*2)*3+10/2分隔为['9', '+', '(', '3', '-', '1', '*', '2', ')', '*',  '3', '+', '10', '/', '2']。

后来想到了正则表达式1-9]\d*|[\+\-\*\/\(\)]。

import re s = '9+(3-1*2)*3+10/2' print(re.findall('[1-9]\d*|[\+\-\*\/\(\)]',s))  ['9', '+', '(', '3', '-', '1', '*', '2', ')', '*', '3', '+', '10', '/', '2']

因此利用栈实现中缀表达式求值中等偏难算法题基本完成。

感谢各位的阅读,以上就是“如何理解栈在括号匹配和表达式求值中的应用”的内容了,经过本文的学习后,相信大家对如何理解栈在括号匹配和表达式求值中的应用这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-前端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯