数据结构与算法Python版p15-p20

B站视频-数据结构与算法Python版

一、创建Stack类p15

在这里插入图片描述

1.1右边是栈顶

# 右边是栈顶
class Stack:
    def __init__(self):
        self.items = []
    def isEmpty(self):
        return self.items ==[]
    def push(self,item):
        self.items.append(item)
    def pop(self):#取出栈顶元素并返回
        return self.items.pop()
    def size(self):#栈长度
        return len(self.items)
    def peek(self):
        if self.isEmpty():
            print('空栈')
        else:
            return self.items[len(self.items) - 1]
# 测试代码
s = Stack()
print(s.isEmpty())
s.push(4)
s.push('dog')
print(s.peek())
s.push(True)
print(s.size())
print(s.isEmpty())
s.push(8.4)
print(s.pop())
print(s.pop())
print(s.size())

输出

True
dog
3
False
8.4
True
2

1.2左边是栈顶

# # 左边是栈顶
# class Stack:
#     def __init__(self):
#         self.items = []
#     def isEmpty(self):
#         return self.items ==[]
#     # 最左边插入元素
#     def push(self,item):
#         self.items.insert(0,item)
#     # 最左边取出元素
#     def pop(self):
#         return self.items.pop(0)
#     def size(self):
#         return len(self.items)
#     # 返回栈顶元素,最左边
#     def peek(self):
#         if self.isEmpty():
#             print('空栈')
#         else:
#             return self.items[0]

二、通用括号匹配p16

# 通用括号匹配()[]{}
def parChecker(string):
    left = list('([{')
    right = list(')]}')
    # 初始化一个栈
    s = Stack()
    for i in list(string):
        if i in left:#所有左括号全部push进栈
            s.push(i)
        else:
            if s.isEmpty():
            # 如果是右括号,而且栈是空的,字符串一定是错的
                return False
            elif left.index(s.peek()) == right.index(i):
            # 判断栈顶元素和当前元素是否匹配,匹配就出栈,继续循环匹配
                s.pop()
            else:
                return False
    return True

# 测试
print(parChecker('{{([][])}()}'))
print(parChecker('{{([])}()}'))
print(parChecker('{{([][)}()}'))
print(parChecker(''))
print(parChecker('[}'))

输出

True
True
False
True
False

三、十进制转换为十六以下任意进制p17

# 十进制转换为十六以下任意进制
def baseConverter(number,base):
    digits = '0123456789ABCDEF'
    s = Stack()
    if number == 0:
        return '0'
    while number > 0:
    # a/2是2进制最后一位,商再除2,倒数第二位,依次进栈
        s.push(number % base)
        number = number // base
    result = ''
    # 翻转过来
    for i in range(s.size()):
        result = result + digits[s.pop()]
    return result
# 测试
print(baseConverter(0,16))
print(baseConverter(233,16))

输出

0
E9

四、表达式转换p18-p19

4.1全括号中缀转后缀

由于是全括号表达式,每一个运算符对应一个括号,那么只需要将运算符移到相应括号的右括号的前面就可以了,最后再删掉所有括号即可。如:
((2+3)/(5*6)) ⇒ \quad\Rightarrow\quad ((2 3 +) (5 6 *)/) ⇒ \quad\Rightarrow\quad 2 3 + 5 6 + /

def convert(string):
    s = Stack()
    result = []
    raw_data = string.split()
    # 遇到运算符,将运算符压入栈s中,其余全部保留
    for i in raw_data:
        if i in '+-*/':
            s.push(i)
        elif i == ')':
        # 当遇到右括号把栈顶元素放下,并保留右括号
            result.append(s.pop())
            result.append(')')
        else:
            result.append(i)
    # 去掉括号
    result = [i for i in result if i not in '()']
    result = ' '.join(result)
    return result

4.2通用的中缀转后缀

这个比较麻烦,主要是运算符有优先级,而且还有括号,比如(A+B) × \times ×C的后缀为AB+C × \times ×,A+B × \times ×C的后缀为ABC × \times ×+,思路仍然是初始化一个栈和一个列表,栈用于存储运算符,列表为返回值,依次从左往右读取,记录运算符,只不过需要在合适的时候pop。为什么这个要用栈这个数据结构,是因为对于最简单的情形即全加全减,是从左往右的只需要push进栈里,遇到下一个在pop,这样push,pop,push,pop······,对于加法在前面,乘法在后面,我们反而需要先乘后加,反映在后缀表达式上就是乘法那个符号在加法那个符号的前面,但是读取的时候是先读到加法,再乘法,所以先进的后出,符合栈的特性。
在这里插入图片描述

def major(operator1,operator2):
    major_dict = {'*':2,'/':2,'+':1,'-':1}
    if major_dict[operator2] > major_dict[operator1]:
        return True
    else:
        return False
def infixToPostfix(infixexpr):
    s = Stack()
    result = []
    raw_data = infixexpr.split()
    for i in raw_data:
        if i == '(':
            s.push(i)
        elif i == ')':
        # 遇到右括号,运算符出栈跟在结果后面,直到栈顶是左括号,这时候就匹配了,把左括号扔掉
            while s.peek() != '(':
                result.append(s.pop())
            s.pop()
        elif i in '+-*/':
            if s.size() == 0:
                s.push(i)
            elif s.peek() == '(':
                s.push(i)
            # 遇到运算符判断一下,优先级大于栈顶的优先级,也push进去,小于等于出栈跟在结果后面,同时当前元素入栈,上面两个是特殊情况,要一开始push运算符进去,不需要比较
            elif major(s.peek(),i):
                s.push(i)
            else:
                result.append(s.pop())
                s.push(i)
        else:
            result.append(i)
    # 注意循环完之后,栈里面可能还有运算符,要全部出来,如5+2,循环完是5 2,栈里面还有一个+
    while (not s.isEmpty()):
        result.append(s.pop())
    result = ' '.join(result)
    return result

五、后缀表达式求值p20

def doMath(op,op1,op2):
	# 定义计算函数,op是运算符,op1,op2是操作的两个数
    if op == '*':
        return op1 * op2
    elif op == '/':
        return op1 / op2
    elif op == '-':
        return op1 - op2
    else :
        return op1 + op2
def postfixEval(string):
	# 初始化一个栈,存入操作数
    s = Stack()
    raw_data = string.split()
    for i in raw_data:
        if i in '+-*/':
        	# 遇到运算符,将栈里最近的两个数pop出来做运算,并将结果push进栈里,继续向后读取操作数
            num2 = int(s.pop())
            num1 = int(s.pop())
            s.push(doMath(i,num1,num2))
        else:
            s.push(i)
    return s.items[0]
# 测试
print(postfixEval('10 2 5 * /'))
```!
输出

```python
1.0

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值