堆栈应用于通用进制转换和表达式转换

本文涉及的产品
实时数仓Hologres,5000CU*H 100GB 3个月
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
智能开放搜索 OpenSearch行业算法版,1GB 20LCU 1个月
简介: 【7月更文挑战第5天】该文主要介绍两种转换方法:还提供了完整的Python代码实现,包括进制转换函数`transfAny`和中缀到后缀表达式转换的`infixToPostfix`函数。

简介

本文介绍两种转换方式,任意进制转换和表达式转换。

1 其他的进制转换方法

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

    本方法将 目标字符srcNum 转换为 10 进制,然后转换为 目标进制

    将原字符M进制数,转换为10进制

    将10进制转换为 目标进制 N 进制数

    2 <= M,N <= 36

    :params M, 原10 进制数, 表示原数据是多少进制的

    :params N, 目标10 进制数, 表示原数据将要转换为多少进制

    :params srcNum

    def transfAny(M, N, srcNum):

        src_list = list(str(srcNum))
        ten_value = transfToTen(decNumber = srcNum, n=M)    
        dest_value = transform(decNumber = ten_value, dn=N)  

        return dest_value

n 表示字符的原进制

如果没有说明是几进制的,默认按10进制处理,栈来处理逆序算法 。

当目标字符串不为空,则不断取出,并取得字符在 原进制中表示多少值。

判断计算该位置表示多少,以10进制计。

累积10进制中的总数,

然后进入下一个字符的判断。

子函数,判断某个字符并取得字符表示 多少值

判断该值在进制范围内,否则报错

:param word 字符代表了10进制多少值

:param n 表示该字符属于几进制

    def map_index(word, n):

        dicmap = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
        if word not in dicmap:
            return False
        else:
            value = dicmap.index(word)    
            assert value <= n    
            return value

    def transfToTen(decNumber, n=None):

        dicmap = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"

        if not n:    
            n = 10

        remstack = Stack()    
        dec_lis = list(str(decNumber))  
        destNum = 0
        loop_n = 0
        while len(dec_lis) > 0:
            current_top = dec_lis.pop()    
            real_value = map_index(current_top, n)  
            sums =  real_value * (n ** loop_n)   # 
            destNum = destNum + sums 
            loop_n += 1      # 

        return destNum

2 表达式转换

中缀表达式。A*B 类似这样,操作符介于操作数 operabd 中间的表示法,称为 中缀 表示法

有括号时,括号表示强制优先级,嵌套括号中,内层优先级更高

以操作符相对于操作数的位置来定义,

前缀表达式。+AB, A+BC 的前缀表达式为 +ABC

后缀表达式。AB+, A+BC 的后缀表达式为 ABC+

中缀 转换为前缀或后缀表达式两个步骤:

  1,中缀表达式 转换为 全括号形式  
  2,把运算符移到 左括号(前缀)  或 右括号(后缀)并替换,然后删除所有括号即可。

依据以上规则,我们定义如下字典,分别映射对应其优先级:

        prec = {}
        prec["*"] = 3
        prec["/"] = 3
        prec["+"] = 2
        prec["-"] = 2
        prec["("] = 1

3 表达式转换完整代码

输入参数为需要转换的 表达式字符串:

   @param: infixexpr

解析表达式到单词列表

   tokenList = list(infixexpr)  

将表达式转换为列表,并进行遍历,如果在约定的字符内,则加入表达式字符列表中:

    if token in "ABCDEFGHIJKLMNOPQRSTUVWXYZ"  or token in "0123456789":
                postfixList.append(token)    

如果为 前小括号,则入堆 ,后小括号则从堆中弹出一个值

    elif token == "(":
                opStack.push(token)

    elif token == ")":
        topToken = opStack.pop()
        while topToken != "(":
            postfixList.append(topToken)
            topToken = opStack.pop()

如果不是小括号, 操作符添加堆顶的字符,知道堆取完为空

    else:     
        while (not opStack.isEmpty()) and (prec[opStack.peek()] >= prec[token]):
            postfixList.append(opStack.pop())
            print('peek postfixList:{}'.format(postfixList))
        opStack.push(token)

逻辑处理的完整代码:

    for token in tokenList:
            if token in "ABCDEFGHIJKLMNOPQRSTUVWXYZ"  or token in "0123456789":
                postfixList.append(token)        

            elif token == "(":
                opStack.push(token)

            elif token == ")":
                topToken = opStack.pop()
                while topToken != "(":
                    postfixList.append(topToken)
                    topToken = opStack.pop()

            else:     
                while (not opStack.isEmpty()) and (prec[opStack.peek()] >= prec[token]):
                    postfixList.append(opStack.pop())

                opStack.push(token)

最后将列表合成为 后缀表达式字符,并且返回

  while not opStack.isEmpty():
            postfixList.append(opStack.pop())    

  return "".join(postfixList)   

4 程序完整代码

    def infixToPostfix(infixexpr):

        prec = {}
        prec["*"] = 3
        prec["/"] = 3
        prec["+"] = 2
        prec["-"] = 2
        prec["("] = 1

        opStack = Stack()
        postfixList = []  
        tokenList = list(infixexpr)       

        words = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 
        nums = "0123456789"

        for token in tokenList:
            if token in "ABCDEFGHIJKLMNOPQRSTUVWXYZ"  or token in "0123456789":
                postfixList.append(token)         

             elif token == "(":
                opStack.push(token)

            elif token == ")":
                topToken = opStack.pop()
                while topToken != "(":
                    postfixList.append(topToken)
                    topToken = opStack.pop()

            else:     
                while (not opStack.isEmpty()) and (prec[opStack.peek()] >= prec[token]):
                    postfixList.append(opStack.pop())

                opStack.push(token)


        while not opStack.isEmpty():
            postfixList.append(opStack.pop())    

        return "".join(postfixList)    

5 小结

这里我们比较完整地归集了一些堆的基本应用例子。主要介绍两种转换方法:

    1) 任意进制转换,通过将数字从源进制转为10进制,再转为目标进制,支持2到36进制间的转换;
    2) 中缀表达式到后缀表达式的转换,用于解决运算符优先级问题,通过全括号形式和堆来实现。

还提供了完整的Python代码实现,包括进制转换函数transfAny和中缀到后缀表达式转换的infixToPostfix函数。

目录
相关文章
|
6月前
|
存储
算术表达式的转换
算术表达式的转换
|
6月前
|
程序员 C#
深入理解 C# 编程:枚举、文件处理、异常处理和数字相加
枚举是一个特殊的“类”,表示一组常量(不可更改/只读变量)。 要创建枚举,请使用 enum 关键字(而不是 class 或 interface),并用逗号分隔枚举项:
68 0
|
存储 C语言 C++
C语言之数据的存储2(浮点数在内存中如何存储,如何输出,查看不同类型数据在内存中表示的范围的方法,十进制浮点数转化为二进制的方法)
C语言之数据的存储2(浮点数在内存中如何存储,如何输出,查看不同类型数据在内存中表示的范围的方法,十进制浮点数转化为二进制的方法)
130 0
|
3月前
运算符有哪些?优先级是怎么样的?转换数据类型的方法?(最少4种)
运算符有哪些?优先级是怎么样的?转换数据类型的方法?(最少4种)
31 0
|
4月前
|
XML 存储 算法
堆栈的实际成对匹配和进制转换应用
【7月更文挑战第5天】本文介绍使用栈实现括号匹配和十进制转二进制的算法。`parChecker`函数检查字符串中的括号是否成对,`divideBy2`函数将十进制数转换为任意进制。栈用于存储和反转二进制位。例如,`divideBy2(42, 2)`打印出42的二进制表示。
48 0
|
6月前
|
编译器
常用的算术转换
常用的算术转换
39 5
|
算法
表达式转换-中缀转后缀表达式后计算-数据结构与算法
表达式转换-中缀转后缀表达式后计算-数据结构与算法
392 0
表达式转换-中缀转后缀表达式后计算-数据结构与算法
|
存储 算法
算术转换
算术转换
|
编译器 C++
c++中基本类型详细解释外加基本运算规则
类型 含义 wchat_t 宽字符 bool 布尔类型 char 字符 chat16_t unicode字符 chat_32 unicode字符 short 短整型 int 整形 long 长整型 longlong 长整型 float 单精度浮点型 double 双精度浮点型 longdouble 扩展精度浮点型
120 1
|
存储 算法 编译器
你是真的“C”——操作符详解【下篇】+整形提升+算术转换
详解C语言中操作符+算术转换+整形提升知识点~
175 1
你是真的“C”——操作符详解【下篇】+整形提升+算术转换
下一篇
无影云桌面