堆栈的实际成对匹配和进制转换应用

本文涉及的产品
智能开放搜索 OpenSearch行业算法版,1GB 20LCU 1个月
实时数仓Hologres,5000CU*H 100GB 3个月
实时计算 Flink 版,1000CU*H 3个月
简介: 【7月更文挑战第5天】本文介绍使用栈实现括号匹配和十进制转二进制的算法。`parChecker`函数检查字符串中的括号是否成对,`divideBy2`函数将十进制数转换为任意进制。栈用于存储和反转二进制位。例如,`divideBy2(42, 2)`打印出42的二进制表示。

简介

本文介绍使用栈实现括号匹配和十进制转二进制的算法。并有完整代码示例和讲解说明。

1 成对匹配

比如括号验证,简单括号匹配。
栈也可以用于 XML,HTML的成对的关键字匹配校验。
括号一般用来指定表达式的运算优先级,多层括号的层级是否正确如,((()), ())))))。
规则,按栈的方式取值,第一个左括号 匹配 第一个右括号。
推广到 开闭校验,如 html。

我们将使用到 py中内置的一个函数,查找某个字符在 字符串中的序号,它就是 str 的index。
比如右括号是否与原 左括号匹配,它返回子串包含在 起始和结束位置。
选填参数 start,and 为子串切片的标记点。 如果是不支持的括号(即没有包含在可匹配字符中),将抛出错误。

  def matched(op, cs):

    opens = "([{"    
    closers = ")]}"    
    return opens.index(op) == closers.index(cs)

检查输入字符串中 右括号是否与原 左括号匹配。

我们首先定义一个堆栈。

    s = Stack()

并且默认输入字符串是 平衡对称的匹配的。

    balanced = True

并且开始遍历,当序号小于输入字符串长度,并且默认平衡因子为 true时,

我们获取字符串的当前序号的字符,并且判断如果字符在 目标待匹配括号时,将其压入堆中:

     symb = symb_str[index]
            if symb in "([{":
                s.push(symb)

如果子字符不在目标匹配括号中,则进行调整:

如果堆为空,平衡因子设置为 false

    if s.isEmpty():
                    balanced = False

否则,获取堆顶元素,并且与子字符进行匹配,不匹配,将平衡因子设置为 false,

     while index < len(symb_str) and balanced:

                symb = symb_str[index]
                if symb in "([{":
                    s.push(symb)
                else:
                    if s.isEmpty():
                        balanced = False
                    else:
                        top = s.pop()
                        if not matched(top, symb):   
                            balanced = False

否则 index 加1,进行下一循环,如此对传入符号的进行全部匹配校验。

            index = index + 1

如果全部字符都校验完成,平衡因子 仍然为 true,

而且堆已经全部取出校验,那么返回true,表示传入字符串时成对匹配的。

否则传入字符串不是成对匹配的,返回 false

        if balanced and s.isEmpty():
            return True
        else:
            return False

2 成对匹配完整代码:

简单括号成对匹配的完整代码。

  def parChecker(symb_str):

        s = Stack()
        balanced = True    
        index = 0
        while index < len(symb_str) and balanced:
            symb = symb_str[index]
            if symb in "([{":
                s.push(symb)
            else:
                if s.isEmpty():
                    balanced = False
                else:
                    top = s.pop()
                    if not matched(top, symb):   
                        balanced = False
            index = index + 1
        if balanced and s.isEmpty():
            return True
        else:
            return False

3 十进制转化为二进制

人们常用的计算方法为 十进制,计算机计算方法为二进制。

高级语言算法 会经常对 十进制和二进制进行转换。

十进制转换为二进制,可采用的是 除以2求余数的算法。

将整数不断除以2,每次得到的余数就是由低到高 的二进制。

   35 / 2  = 17  余 1  -- k0    # 低位
   17 /2 = 8   余   1  -- k1
   8/2 = 4   余  0  -- k2
   4/2 = 2  余  0  -- k3
   2/2 = 1 余  0   -- k4
   1/2 = 0 余  1  --  k5     # 高位

3 转换代码

使用堆来处理逆序算法。

传入两个参数,需要判断的数字:decNumber, 和进制约定 n

10进制转换为2进制,默认参数

@params  decNumber 要转换的数字
@params n 要转换为的进制,默认为2""

依照以上的原理,当待判断的数字不为0时,对其进行除以进制数,并将余数入堆。

最后把商赋予待处理数字。

   while decNumber > 0:
        rem = decNumber % n        
        remstack.push(rem)
        decNumber = decNumber // n    

最后取得相应的 进制组合成数字为最终结果

   binString = ''
    while not remstack.isEmpty():
        binString = binString + digits[remstack.pop()]   
    return binString

4 完整代码:

  • 一 10进制转换为任意进制(2~36)

    此为第一个方法。

    def divideBy2(decNumber, n=None):

    digits = "0123456789ABCDEF"
    if not n:
        n = 2
    remstack = Stack()   
    
    while decNumber > 0:
        rem = decNumber % n        
        remstack.push(rem)
        decNumber = decNumber // n     
    
    binString = ''
    while not remstack.isEmpty():
        binString = binString + digits[remstack.pop()]   
    return binString
    

5 如何使用

将42转换为 2进制

    print(divideBy2(42, 2))

将42转换为 8进制

    print(divideBy2(42, 8))

将42转换为 16进制

    print(divideBy2(42, 16))
目录
相关文章
|
存储 索引
数据结构各结构特点(数组、链表、栈、队列、树)(上)
数据结构各结构特点(数组、链表、栈、队列、树)
444 0
|
并行计算 算法 异构计算
antv/g6之图布局及切换布局
antv/g6之图布局及切换布局
1447 0
|
9月前
|
监控 Java 应用服务中间件
tomcat相关概念与部署tomcat多实例-zabbix监控(docker部署)
通过上述步骤,您可以在Ubuntu系统上成功编译并安装OpenCV 4.8。这种方法不仅使您能够定制OpenCV的功能,还可以优化性能以满足特定需求。确保按照每一步进行操作,以避免常见的编译问题。
160 22
|
Java
【数据结构】栈和队列的深度探索,从实现到应用详解
本文介绍了栈和队列这两种数据结构。栈是一种后进先出(LIFO)的数据结构,元素只能从栈顶进行插入和删除。栈的基本操作包括压栈、出栈、获取栈顶元素、判断是否为空及获取栈的大小。栈可以通过数组或链表实现,并可用于将递归转化为循环。队列则是一种先进先出(FIFO)的数据结构,元素只能从队尾插入,从队首移除。队列的基本操作包括入队、出队、获取队首元素、判断是否为空及获取队列大小。队列可通过双向链表或数组实现。此外,双端队列(Deque)支持两端插入和删除元素,提供了更丰富的操作。
263 0
【数据结构】栈和队列的深度探索,从实现到应用详解
|
Cloud Native 容器 Kubernetes
基于阿里云服务网格流量泳道的全链路流量管理(三):无侵入式的宽松模式泳道
本文简要讨论了使用流量泳道来实现全链路流量灰度管理的场景与方案,并回顾了阿里云服务网格 ASM 提供的严格与宽松两种模式的流量泳道、以及这两种模式各自的优势与挑战。接下来介绍了一种基于 OpenTelemetry 社区提出的 baggage 透传能力实现的无侵入式的宽松模式泳道,这种类型的流量泳道同时具有对业务代码侵入性低、同时保持宽松模式的灵活特性的特点。同时,我们还介绍了新的基于权重的流量引流策略,这种策略可以基于统一的流量匹配规则,将匹配到的流量以设定好的比例分发到不同的流量泳道。
73729 16
基于阿里云服务网格流量泳道的全链路流量管理(三):无侵入式的宽松模式泳道
|
自然语言处理 JavaScript 前端开发
一文梳理JavaScript中常见的七大继承方案
该文章系统地概述了JavaScript中七种常见的继承模式,包括原型链继承、构造函数继承、组合继承、原型式继承、寄生式继承、寄生组合继承等,并探讨了每种模式的实现方式及其优缺点。
一文梳理JavaScript中常见的七大继承方案
|
安全 算法 关系型数据库
线程安全--深入探究线程等待机制和死锁问题
线程安全--深入探究线程等待机制和死锁问题
432 1
|
安全 Go 开发者
文件锁深度剖析:获得锁的正确姿势
文件锁深度剖析:获得锁的正确姿势
380 0
|
网络安全 数据库 流计算
几个可能的原因会导致数据同步中断
几个可能的原因会导致数据同步中断
458 1
|
测试技术 C语言
【数据结构】—手把手带你用C语言实现栈和队列(超详细!)
【数据结构】—手把手带你用C语言实现栈和队列(超详细!)