栈是一系列对象组成的集合,这些对象的插入和删除操作遵循后进先出的原则。用户可以在任何时刻向栈中插入一个对象,但只能取得或删除最后插入的对象(即所谓的栈顶)
堆栈的示例
1网络浏览器将最近浏览的网址存放在一个栈中。每次当访问者访问一个新网站时,这个新网站的网址就被压入栈顶。这样浏览器就可以在用户单击后退按钮时,弹出先访问的网址,以回到其先前访问的网页
2文本编辑器通常提供一个“撤销”机制已取消最近的编辑操作并返回到先前的文本状态,这个撤销操作就是就是通过将文本的变化状态保存在一个栈中得以实现的
栈的抽象数据类型
以下用S作为栈的示例
S.push(e):将一个元素e添加到栈S的栈顶
S.pop(e) :从栈S中移除并返回栈顶的元素,如果此时栈为空 出错
S.top() :在不移除栈顶元素的前提下,返回一个栈S的栈顶元素;若栈为空,这个操作会出错
S.is_empty() :如果栈中不包含任何元素,则返回一个布尔值 “true"
len(S):返回栈S中元素的数量
简单的基于数组的栈实现
class Empty(Exception):
pass #占位语句
class ArrayStack:
def __init__(self):
self._data=[]
def __len__(self):
return len(self._data)
def is_empty(self):
return len(self._data)==0
def push(self,e):
self._data.append(e)
def top(self):
if self.is_empty():
raise Empty("Stack is empty")
return self._data[-1]
def pop(self):
if self.is_empty():
raise Empty("Stack is empty")
return self._data.pop()
S=ArrayStack()
S.push(8)
print(S.pop())
基于栈的括号匹配算法
class Empty(Exception):
pass #占位语句
class ArrayStack:
def __init__(self):
self._data=[]
def __len__(self):
return len(self._data)
def is_empty(self):
return len(self._data)==0
def push(self,e):
self._data.append(e)
def top(self):
if self.is_empty():
raise Empty("Stack is empty")
return self._data[-1]
def pop(self):
if self.is_empty():
raise Empty("Stack is empty")
return self._data.pop()
def is_matched(expr):
lefty='({['
righty=')}]'
S = ArrayStack()
for c in expr:
if c in lefty:
S.push(c)
elif c in righty:
if S.is_empty():
return False
if lefty.index(S.pop())!=righty.index(c):
return False
return S.is_empty()
print(is_matched('()(()){([()])}'))
print(is_matched(')((()){([()])}'))
测试一个HTML文本是否有匹配标签的函数
class Empty(Exception):
pass #占位语句
class ArrayStack:
def __init__(self):
self._data=[]
def __len__(self):
return len(self._data)
def is_empty(self):
return len(self._data)==0
def push(self,e):
self._data.append(e)
def top(self):
if self.is_empty():
raise Empty("Stack is empty")
return self._data[-1]
def pop(self):
if self.is_empty():
raise Empty("Stack is empty")
return self._data.pop()
'''Python find() 方法检测字符串中是否包含子字符串 str ,如果指定 beg(开始) 和 end(结束) 范围,则检查是否包含在指定范围内,
如果包含子字符串返回开始的索引值,否则返回-1 str.find(str, beg=0, end=len(string))
str -- 指定检索的字符串
beg -- 开始索引,默认为0。
end -- 结束索引,默认为字符串的长度。
'''
def is_matched_html(raw):
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.isempty():
return False
if tag[1:]!=S.pop():
return False
j=raw.find('<',k+1)
return S.is_empty()