python 数据结构 栈 使用

# encoding=UTF-8

"""
    用 python 列表作为存储实现一个栈
    采用适配器模式,在内部维护一个数组,对栈不需要的方法进行隐藏
"""


class ArrayStack:
    """LIFO stack implementation using a python list as underlying storage"""

    def __init__(self):
        """create an empty stack"""
        self._data = []                 # nonpublic list instance

    def __len__(self):
        """return the number of elements in the stack"""
        return len(self._data)

    def is_empty(self):
        """retutn True if the stack is empty"""
        return len(self._data) == 0

    def push(self, e):
        """add element e to the top of the stack"""
        self._data.append(e)            # new item stored at end of list

    def top(self):
        """return (but do not remove) the elemnet at the top of the stack
           raise empty exception if the stack is empty
        """
        if self.is_empty():
            raise Empty('stack is empty')
        return self._data[-1]           # the last item in the list

    def pop(self):
        """remove and return the element form the top of the stack (i.e., LIFO)
           raise empty exception if the stack is empty
        """
        if self.is_empty():
            raise Empty('stack is empty')
        return self._data.pop()         # remove last item from list

    def __str__(self):
        return str(self._data)


class Empty(Exception):
    """error atttempting to access an element from an empty container"""
    pass


def reverse_file(filename):
    """overwrite given file with its contents line-by-line reversed"""
    s = ArrayStack()
    with open(filename) as original:
        for line in original:
            s.push(line.rstrip('\n'))       # we will re-insert newlines when writing

    # now we overwrite with contents in LIFO order
    with open(filename, 'w') as ouput:      # reopening file overwrites original
        while not s.is_empty():
            ouput.write(s.pop() + '\n')     # re-insert newline characters


def is_matched(expr):
    """return True if all delimiters are properly match; False otherwise"""
    lefty = '({['
    righty = ')}]'
    s = ArrayStack()
    for c in expr:
        print(c)
        if c in lefty:
            s.push(c)
        elif c in righty:
            if s.is_empty():
                return False
            if righty.index(c) != lefty.index(s.pop()):
                return False
    return s.is_empty()


def is_matched_html(raw:str):
    """return True if all html tags are properly match; False otherwise"""
    s = ArrayStack()
    j = raw.find('<')
    while j != -1:
        k = raw.find('>', j+1)
        if k == -1:
            return False
        tag = raw[j+1:k]
        if not tag.startswith('/'):
            s.push(tag)
        else:
            if s.is_empty():
                return False
            if tag[1:] != s.pop():
                return False
        j = raw.find('<', k+1)
    return s.is_empty()


if __name__ == '__main__':
    """
    测试栈功能
    """
    # s = ArrayStack()
    # s.push(5)
    # s.push(3)
    # print(s.top())
    # print(len(s))
    # print(s.pop())
    # print(s.is_empty())
    # print(s.pop())
    # print(s.is_empty())

    """
    使用栈实现数据的逆置
    """
    # reverse_file('./log/basicinfo.txt')

    """
    在算数表达式中分割符匹配算法的函数实现
        每次遇到开始符时,我们都将其压入栈中;每次遇到结束符时,我们从栈顶弹出一个分割符(假定栈不为空),并检查这两个分割符是否能够
        组成有效的一对。如果扫描到表达式的最后并且栈为空,则表明原来的算数表达式匹配正确;否则,栈中一定存在一个开始分割符没有被匹配。
        
    算法时间复杂度
        如果原始算数表达式的长度为 n,这个算法将最多 n 次调用 push 和 n 次调用 pop。即使假设这些调用的均摊复杂度边界为 O(1),这些
        调用总运行时间仍为 O(n)。
    """
    # print(is_matched('[(5+x)-(y+z)]'))

    """
    测试一个 html 文本是否匹配标签的函数
    """

    html_content = '''
    <html>

    <head>
    <title>我的第一个 HTML 页面</title>
    </head>
    
    <body>
    <p>body 元素的内容会显示在浏览器中。</p>
    <p>title 元素的内容会显示在浏览器的标题栏中。</p>
    </body>
    
    </html>
    '''
    print(is_matched_html(html_content))

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值