训练题
一.实现学生线性表
依次输入学生姓名:
赵壹,钱贰,孙叁,李肆,周伍,吴陆,郑柒,王捌
测试要求如下:
- 展示该班所有学生的姓名及班级人数
- 查找学生"赵肆"在表中的位置
- 在表中的学生"王捌"后加入新生"冯玖",删除班里的转走生"赵壹",展示该班的现有学生
from abc import ABCMeta,abstractmethod,abstractproperty
class IList(metaclass=ABCMeta):
@abstractmethod
def clear(self):
pass
@abstractmethod
def isEmpty(self):
pass
@abstractmethod
def length(self):
pass
@abstractmethod
def get(self,i):
pass
@abstractmethod
def insert(self,i,x):
pass
@abstractmethod
def remove(self,i):
pass
@abstractmethod
def indexOf(self,x):
pass
@abstractmethod
def display(self):
pass
class Node(object):
def __init__(self,data=None,next=None):
self.data=data
self.next=next
class LinkList(IList):
def __init__(self):
self.head=Node()
def create(self,L,order):
if order:
self.create_tail(L)
else:
self.create_head(L)
def create_tail(self,L):
for item in L:
self.insert(self.length(),item)
def create_head(self,L):
for item in L:
self.insert(0,item)
def clear(self):
self.head.data=None
self.head.next=None
def isEmpty(self):
return self.head.next==None
def length(self):
p=self.head.next
length=0
while p is not None:
p=p.next
length+=1
return length
def get(self,i):
p=self.head.next
j=0
while j<i and p is not None:
p=p.next
j+=1
if j>i or p is None:
raise Exception("第"+i+"个数据元素不存在")
return p.data
def insert(self,i,x):
# (带头节点)插入x作为第i个元素
"""
:param i: 第i个元素
:param x: 位置
:return:
"""
p=self.head
j=-1
while p is not None and j<i-1:
p=p.next
j+=1
if j>i-1 or p is None:
raise Exception("插入位置不合法")
s=Node(x)
p.next=s
"""
def insert(self,i,x):
# (不带头节点) 插入x作为第i个元素
p=self.head
j=-1
while p is not None and j<i-1:
p=p.next
j+=1
if j>i-1 or p is None:
raise Exception("插入位置不合法")
s=Node(data=x)
if i==0:
s.next=self.head
else:
s.next=p.next
p.next=s
"""
def remove(self,i):
p=self.head
j=-1
while p is not None and j<i-1:
p=p.next
j+=1
if j>i-1 or p.next is None:
raise Exception("删除位置不合法")
p.next=p.next.next
def indexOf(self,x):
p=self.head.next
j=0
while p is not None and not (p.data==x):
p=p.next
j+=1
if p is not None:
return j
else:
return -1
def display(self):
p=self.head.next
while p is not None:
print(p.data,end=" ")
p=p.next
L=LinkList()
Student=["赵壹","钱贰","孙叁","李肆","周伍","吴陆","郑柒","王捌"]
for i in range(8):
L.insert(i,Student[i])
print("(1)班级学生:",end=" ")
L.display()
print("班级人数:",end=" ")
print(L.length())
print("(2)李肆 在表中的位置:",L.indexOf("李肆"))
L.insert(L.indexOf("王捌")+1,"冯玖")
L.remove(L.indexOf("赵壹"))
print("(3)现在班级学生:",end=" ")
L.display()
(1)班级学生: 赵壹 钱贰 孙叁 李肆 周伍 吴陆 郑柒 王捌 班级人数: 8
(2)李肆 在表中的位置: 3
(3)现在班级学生: 钱贰 孙叁 李肆 周伍 吴陆 郑柒 王捌 冯玖
二.一元多项式的加法
p1=3x^3+ 5x^2+ 4x^1
p2=1x^5+ 3x^2
result=1x^5+ 3x^3+ 8x^2+ 4x^1
输入:从大到小依次输入所要输入的两个一元多项式的系数和指数
输出:输出一元多项式p1,p2以及两式相加的结果
from abc import ABCMeta,abstractmethod,abstractproperty
class IList(metaclass=ABCMeta):
@abstractmethod
def clear(self):
pass
@abstractmethod
def isEmpty(self):
pass
@abstractmethod
def length(self):
pass
@abstractmethod
def get(self,i):
pass
@abstractmethod
def insert(self,i,x):
pass
@abstractmethod
def remove(self,i):
pass
@abstractmethod
def indexOf(self,x):
pass
@abstractmethod
def display(self):
pass
class Node(object):
def __init__(self,data=None,next=None):
self.data=data
self.next=next
class LinkList(IList):
def __init__(self):
self.head=Node()
def create(self,L,order):
if order:
self.create_tail(L)
else:
self.create_head(L)
def create_tail(self,L):
for item in L:
self.insert(self.length(),item)
def create_head(self,L):
for item in L:
self.insert(0,item)
def clear(self):
self.head.data=None
self.head.next=None
def isEmpty(self):
return self.head.next==None
def length(self):
p=self.head.next
length=0
while p is not None:
p=p.next
length+=1
return length
def get(self,i):
p=self.head.next
j=0
while j<i and p is not None:
p=p.next
j+=1
if j>i or p is None:
raise Exception("第"+i+"个数据元素不存在")
return p.data
def insert(self,i,x):
# (带头节点)插入x作为第i个元素
"""
:param i: 第i个元素
:param x: 位置
:return:
"""
p=self.head
j=-1
while p is not None and j<i-1:
p=p.next
j+=1
if j>i-1 or p is None:
raise Exception("插入位置不合法")
s=Node(x)
p.next=s
"""
def insert(self,i,x):
# (不带头节点) 插入x作为第i个元素
p=self.head
j=-1
while p is not None and j<i-1:
p=p.next
j+=1
if j>i-1 or p is None:
raise Exception("插入位置不合法")
s=Node(data=x)
if i==0:
s.next=self.head
else:
s.next=p.next
p.next=s
"""
def remove(self,i):
p=self.head
j=-1
while p is not None and j<i-1:
p=p.next
j+=1
if j>i-1 or p.next is None:
raise Exception("删除位置不合法")
p.next=p.next.next
def indexOf(self,x):
p=self.head.next
j=0
while p is not None and not (p.data==x):
p=p.next
j+=1
if p is not None:
return j
else:
return -1
def display(self):
p=self.head.next
while p is not None:
print(p.data,end=" ")
p=p.next
class PloyNode(object):
def __init__(self,a,i):
self.a=a
self.i=i
def add(p1,p2):
L=LinkList()
i=j=0
while i<p1.length() and j<p2.length():
x,y=p1.get(i),p2.get(j)
if x.i==y.i:
L.insert(L.length(),PloyNode(x.a+y.a,x.i))
i+=1
j+=1
elif x.i>y.i:
L.insert(L.length(),PloyNode(x.a,x.i))
i+=1
else:
L.insert(L.length(),PloyNode(y.a,y.i))
j+=1
while i<p1.length():
x=p1.get(i)
L.insert(L.length(),PloyNode(x.a,x.i))
i+=1
while j<p2.length():
y=p2.get(j)
L.insert(L.length(),PloyNode(y.a,y.i))
j+=1
return L
p1=LinkList()
p2=LinkList()
p1.insert(0,PloyNode(3,3))
p1.insert(1,PloyNode(5,2))
p1.insert(2,PloyNode(4,1))
p2.insert(0,PloyNode(1,5))
p2.insert(1,PloyNode(3,2))
L=add(p1,p2)
for i in range(L.length()-1):
x=L.get(i)
print("%sx^%s+"%(x.a,x.i),end=" ")
x=L.get(L.length()-1)
print("%sx^%s"%(x.a,x.i))
1x^5+ 3x^3+ 8x^2+ 4x^1
三.双向链表的约瑟夫问题
class JosephusNode(object):
def __init__(self,data,next=None,prior=None):
self.data=data
self.next=next
self.prior=prior
class JosephusList(object):
def __init__(self):
self.curLen=0
self.head=None
def insert(self,x):
if self.head is None:
self.head=JosephusNode(x)
self.head.next=self.head
self.head.prior=self.head
else:
s=JosephusNode(x)
s.next=self.head
s.prior=self.head.prior
self.head.prior.next=s
self.head.prior=s
self.curLen+=1
def remove(self,x):
p=self.head
while True:
if p.data==x:
p.prior.next=p.next
p.next.prior=p.prior
if p is self.head:
self.head=p.next
self.curLen-=1
break
p=p.next
if p is self.head:
break
def display(self):
p=self.head
while True:
print(p.data,end=" ")
p=p.next
if p is self.head:
break
N=6
M=5
J=JosephusList()
for i in range(1,N+1):
J.insert(i)
p=J.head
while J.curLen>1:
for i in range(M-1):
p=p.next
print(p.data,"出局")
J.remove(p.data)
p=p.next
print(p.data,"胜出")
5 出局
4 出局
6 出局
2 出局
3 出局
1 胜出
四.括号匹配
对输入的一串字符串依次扫描,检查括号匹配是否成功
from abc import ABCMeta,abstractmethod,abstractproperty
class IStack(metaclass=ABCMeta):
@abstractmethod
def clear(self):
pass
@abstractmethod
def isEmpty(self):
pass
@abstractmethod
def length(self):
pass
@abstractmethod
def peek(self):
pass
@abstractmethod
def push(self,x):
pass
@abstractmethod
def pop(self):
pass
@abstractmethod
def display(self):
pass
class SqStack(IStack):
def __init__(self,maxSize):
self.maxSize=maxSize
self.stackElem=[None]*self.maxSize
self.top=0
def clear(self):
self.top=0
def isEmpty(self):
return self.top==0
def length(self):
return self.top
def peek(self):
if not self.isEmpty():
return self.stackElem[self.top-1]
else:
return None
def push(self,x):
if self.top==self.maxSize:
raise Exception("栈已满")
self.stackElem[self.top]=x
self.top+=1
def pop(self):
if self.isEmpty():
return None
self.top-=1
return self.stackElem[self.top]
def display(self):
for i in range(self.top-1,-1,-1):
print(self.stackElem[i],end=" ")
def IsMatch(str):
backref={
')':'(',
']':'[',
'}':'{'
}
s=SqStack(100)
for c in str:
if c=='(' or c=='[' or c=='{':
s.push(c)
if c==')' or c==']' or c=='}':
if s.isEmpty():
return False
if s.peek()==backref[c]:
s.pop()
else:
return False
if s.isEmpty():
return True
else:
return False
s1="{{}}()(hello){({world}{})}"
s2="{{}}()(hello){({world}(})}"
print(s1,end=" ")
if IsMatch(s1):
print("括号匹配成功")
else:
print("括号匹配失败")
print(s2,end=" ")
if IsMatch(s2):
print("括号匹配成功")
else:
print("括号匹配失败")
{{}}()(hello){({world}{})} 括号匹配成功
{{}}()(hello){({world}(})} 括号匹配失败
五.杨辉三角
基于队列实现杨辉三角形
from abc import ABCMeta,abstractmethod,abstractproperty
class IQueue(metaclass=ABCMeta):
@abstractmethod
def clear(self):
pass
@abstractmethod
def isEmpty(self):
pass
@abstractmethod
def length(self):
pass
@abstractmethod
def peek(self):
pass
@abstractmethod
def offer(self,x):
pass
@abstractmethod
def poll(self):
pass
@abstractmethod
def display(self):
pass
class Node(object):
def __init__(self,data=None,next=None):
self.data=data
self.next=next
class LinkQueue(IQueue):
def __init__(self):
self.front=None
self.rear=None
def clear(self):
self.front=None
self.rear=None
def isEmpty(self):
return self.front is None
def length(self):
p=self.front
i=0
while p is not None:
p=p.next
i+=1
return i
def peek(self):
if self.isEmpty():
return None
else:
return self.front.data
def offer(self,x):
s=Node(x,None)
if not self.isEmpty():
self.rear.next=s
else:
self.front=s
self.rear=s
def poll(self):
if self.isEmpty():
return None
p=self.front
self.front=self.front.next
if p==self.rear:
self.rear=None
return p.data
def display(self):
p=self.front
while p is not None:
print(p.data,end=" ")
p=p.next
N=5
q=LinkQueue()
s=0
q.offer(1)
q.offer(1)
for i in range(1,N+1):
q.offer(0)
for j in range(1,i+3):
temp=q.poll()
q.offer(temp+s)
s=temp
if j!=i+2:
print(s,end=" ")
print()
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
六.构造二叉树
以[1,2,3,4,5,6,7,8,9]为元素构造一棵二叉树,并输出它的先序遍历,中序遍历和后序遍历的结果
from abc import ABCMeta,abstractmethod,abstractproperty
class IQueue(metaclass=ABCMeta):
@abstractmethod
def clear(self):
pass
@abstractmethod
def isEmpty(self):
pass
@abstractmethod
def length(self):
pass
@abstractmethod
def peek(self):
pass
@abstractmethod
def offer(self,x):
pass
@abstractmethod
def poll(self):
pass
@abstractmethod
def display(self):
pass
class Node(object):
def __init__(self,data=None,next=None):
self.data=data
self.next=next
class LinkQueue(IQueue):
def __init__(self):
self.front=None
self.rear=None
def clear(self):
self.front=None
self.rear=None
def isEmpty(self):
return self.front is None
def length(self):
p=self.front
i=0
while p is not None:
p=p.next
i+=1
return i
def peek(self):
if self.isEmpty():
return None
else:
return self.front.data
def offer(self,x):
s=Node(x,None)
if not self.isEmpty():
self.rear.next=s
else:
self.front=s
self.rear=s
def poll(self):
if self.isEmpty():
return None
p=self.front
self.front=self.front.next
if p==self.rear:
self.rear=None
return p.data
def display(self):
p=self.front
while p is not None:
print(p.data,end=" ")
p=p.next
class BiNode(object):
def __init__(self,data=None,lchild=None,rchild=None):
self.data=data
self.lchild=lchild
self.rchild=rchild
class BiTree(object):
def __init__(self,root=None):
self.root=root
def createBiTree(order):
q=LinkQueue()
root=BiNode(order[0])
bt=BiTree(root)
q.offer(root)
for i in range(1,len(order)):
c=order[i]
node=q.peek()
if node.lchild is None:
newNode=BiNode(c)
node.lchild=newNode
q.offer(newNode)
elif node.rchild is None:
newNode=BiNode(c)
node.rchild=newNode
q.offer(newNode)
q.poll()
return bt
def preOrder(root):
if root is not None:
print(root.data,end=" ")
BiTree.preOrder(root.lchild)
BiTree.preOrder(root.rchild)
def inOrder(root):
if root is not None:
BiTree.inOrder(root.lchild)
print(root.data,end=" ")
BiTree.inOrder(root.rchild)
def postOrder(root):
if root is not None:
BiTree.postOrder(root.lchild)
BiTree.postOrder(root.rchild)
print(root.data,end=" ")
bt=BiTree.createBiTree("123456789")
print("先序遍历:")
BiTree.preOrder(bt.root)
print()
print("中序遍历:")
BiTree.inOrder(bt.root)
print()
print("后序遍历:")
BiTree.postOrder(bt.root)
先序遍历:
1 2 4 8 9 5 3 6 7
中序遍历:
8 4 9 2 5 1 6 3 7
后序遍历:
8 9 4 5 2 6 7 3 1
七.一个点到所有点的最短路径
from abc import ABCMeta,abstractmethod,abstractproperty
import sys
class IGraph(metaclass=ABCMeta):
@abstractmethod
def createGraph(self):
pass
@abstractmethod
def getVNum(self):
pass
@abstractmethod
def getENum(self):
pass
@abstractmethod
def getVex(self,i):
pass
@abstractmethod
def locateVex(self,x):
pass
@abstractmethod
def firstAdj(self,i):
pass
@abstractmethod
def nextAdj(self,i,j):
pass
class MGraph(IGraph):
GRAPHKIND_UDG='UDG'
GRAPHKIND_DG='DG'
GRAPHKIND_UDN='UDN'
GRAPHKIND_DN='DN'
def __init__(self,kind=None,vNum=0,eNum=0,v=None,e=None):
self.kind=kind
self.vNum=vNum
self.eNum=eNum
self.v=v
self.e=e
def createUDG(self,vNum,eNum,v,e):
self.vNum=vNum
self.eNum=eNum
self.v=[None]*vNum
for i in range(eNum):
self.v[i]=v[i]
self.e=[[0]*vNum]*vNum
for i in range(eNum):
a,b=e[i]
m,n=self.locateVex(a),self.locateVex(b)
self.e[m][n]=self.e[n][m]=1
def createDG(self,vNum,eNum,v,e):
self.vNum=vNum
self.eNum=eNum
self.v=[None]*vNum
for i in range(vNum):
self.v[i]=v[i]
self.e=[[0]*vNum]*vNum
for i in range(eNum):
a,b=e[i]
m,n=self.locateVex(a),self.locateVex(b)
self.e[m][n]=1
def createUDN(self,vNum,eNum,v,e):
self.vNum=vNum
self.eNum=eNum
self.v=[None]*vNum
for i in range(vNum):
self.v[i]=v[i]
self.e=[[sys.maxsize]*vNum]*vNum
for i in range(eNum):
a,b,w=e[i]
m,n=self.locateVex(a),self.locateVex(b)
self.e[m][n]=self[n][m]=w
def createDN(self):
八.冒泡排序
class RecordNode(object):
def __init__(self,key,data):
self.key=key
self.data=data
class SqList(object):
def __init__(self,maxSize):
self.maxSize=maxSize
self.list=[None]*self.maxSize
self.len=0
def insert(self,i,x):
if self.len==self.maxSize:
raise Exception("顺序表已满")
if i<0 or i>self.len:
raise Exception("插入位置不合理")
for j in range(self.len,i,-1):
self.list[j]=self.list[j-1]
self.list[i]=x
self.len+=1
def display(self):
for i in range(self.len):
print(self.list[i].key,end=" ")
print()
def BubbleSort(self):
flag=True
i=1
while i<self.len and flag:
flag=False
for j in range(self.len-i):
if self.list[j+1].key<self.list[j].key:
p=self.list[j]
self.list[j]=self.list[j+1]
self.list[j+1]=p
flag=True
i+=1
sl=SqList(8)
data=[1,2,5,4,7,6,3,0]
for i,x in zip(range(len(data)),data):
sl.insert(i,RecordNode(x,x))
sl.BubbleSort()
sl.display()
0 1 2 3 4 5 6 7
九.快速排序
class RecordNode(object):
def __init__(self,key,data):
self.key=key
self.data=data
class SqList(object):
def __init__(self,maxSize):
self.maxSize=maxSize
self.list=[None]*self.maxSize
self.len=0
def insert(self,i,x):
if self.len==self.maxSize:
raise Exception("顺序表已满")
if i<0 or i>self.len:
raise Exception("插入位置不合理")
for j in range(self.len,i,-1):
self.list[j]=self.list[j-1]
self.list[i]=x
self.len+=1
def display(self):
for i in range(self.len):
print(self.list[i].key,end=" ")
print()
def qSort(self,low,high):
if low<high:
p=self.Partition(low,high)
self.qSort(low,p-1)
self.qSort(p+1,high)
def Partition(self,low,high):
p=self.list[low]
while low<high:
while low<high and self.list[high].key>p.key:
high-=1
if low<high:
self.list[low]=self.list[high]
low+=1
while low<high and self.list[low].key<p.key:
low+=1
if low<high:
self.list[high]=self.list[low]
high-=1
self.list[low]=p
return low
sl=SqList(8)
data=[1,2,5,4,7,6,3,0]
for i,x in zip(range(len(data)),data):
sl.insert(i,RecordNode(x,x))
sl.qSort(0,sl.len-1)
sl.display()
0 1 2 3 4 5 6 7
十.归并排序
class RecordNode(object):
def __init__(self,key,data):
self.key=key
self.data=data
class SqList(object):
def __init__(self,maxSize):
self.maxSize=maxSize
self.list=[None]*self.maxSize
self.len=0
def insert(self,i,x):
if self.len==self.maxSize:
raise Exception("顺序表已满")
if i<0 or i>self.len:
raise Exception("插入位置不合理")
for j in range(self.len,i,-1):
self.list[j]=self.list[j-1]
self.list[i]=x
self.len+=1
def display(self):
for i in range(self.len):
print(self.list[i].key,end=" ")
print()
def merge(self,order,a,i,k,j):
t=i
m=i
n=k+1
while m<=k and n<=j:
if a[m].key<=a[n].key:
order[t]=a[m]
t+=1
m+=1
else:
order[t]=a[n]
t+=1
n+=1
while m<=k:
order[t]=a[m]
t+=1
m+=1
while n<=j:
order[t]=a[n]
t+=1
n+=1
def mergePass(self,order,a,s,n):
p=0
while p+2*s-1<=n-1:
self.merge(order,a,p,p+s-1,p+2*s-1)
p=p+2*s
if p+s-1<n-1:
self.merge(order,a,p,p+s-1,n-1)
else:
for i in range(p,n):
order[i]=a[i]
def mergeSort(self):
s=1
order=[None]*self.len
while s<self.len:
self.mergePass(order,self.list,s,self.len)
s=s*2
self.mergePass(self.list,order,s,self.len)
s=s*2
sl=SqList(50)
data=[1,2,5,4,7,6,3,0]
for i,x in zip(range(len(data)),data):
sl.insert(i,RecordNode(x,x))
sl.mergeSort()
sl.display()
0 1 2 3 4 5 6 7
十一.查找最长合法括号子串长度
def LongestValidParentheses(s):
left=right=ans=0
length=len(s)
for i in range(length):
if s[i]=="(":
left+=1
else:
right+=1
if left==right:
ans=max(ans,2*right)
elif right>left:
left=right=0
left=right=0
for i in range(length-1,-1,-1):
if s[i]==")":
right+=1
else:
left+=1
if left==right:
ans=max(ans,2*left)
elif left>right:
left=right=0
return ans
if __name__=="__main__":
s="()()("
print(LongestValidParentheses(s))
4
十二.实现二叉查找树
class BiTreeNode(object):
def __init__(self,key,data,lchild=None,rchild=None):
self.key=key
self.data=data
self.lchild=lchild
self.rchild=rchild
class BSTree(object):
def __init__(self,root=None):
self.root=root
def display(self,p):
if p is not None:
print(p.data,end="")
print("(",end="")
self.display(p.lchild)
print(",",end="")
self.display(p.rchild)
print(")",end="")
def search(self,key):
return self.searchBST(key,self.root)
def searchBST(self,key,p):
if p is None:
return None
if key==p.key:
return p.data
elif key<p.key:
return self.searchBST(key,p.lchild)
else:
return self.searchBST(key,p.rchild)
def insert(self,key,data):
p=BiTreeNode(key,data)
if self.root is None:
self.root=p
else:
self.insertBST(self.root,p)
def insertBST(self,r,p):
if r.key<p.key:
if r.rchild is None:
r.rchild=p
else:
self.insertBST(r.rchild,p)
else:
if r.lchild is None:
r.lchild=p
else:
self.insertBST(r.lchild,p)
def remove(self,key):
self.removeBST(key,self.root,None)
def removeBST(self,key,p,parent):
if p is None:
return
if p.key>key:
self.removeBST(key,p.lchild,p)
elif p.key<key:
self.removeBST(key,p.rchild,p)
elif p.lchild is not None and p.rchild is not None:
inNext=p.rchild
while inNext.lchild is not None:
inNext=inNext.lchild
p.data=inNext.data
p.key=inNext.key
self.removeBST(p.key,p.rchild,p)
else:
if parent is None:
if p.lchild is not None:
self.root=p.lchild
else:
self.root=p.rchild
return
if p==parent.lchild:
if p.lchild is not None:
parent.lchild=p.lchild
else:
parent.lchild=p.rchild
elif p==parent.rchild:
if p.lchild is not None:
parent.rchild=p.lchild
else:
parent.rchild=p.rchild
def inOrder(root,data):
if root is not None:
BSTree.inOrder(root.lchild,data)
data.append(root.data)
BSTree.inOrder(root.rchild,data)
def toList(self):
data=[]
BSTree.inOrder(self.root,data)
return data
def createBSTree(nums):
bst=BSTree()
for num in nums:
bst.insert(num,num)
return bst
bst=BSTree.createBSTree([15,5,3,12,10,13,6,7,16,20,18,23])
bst.display(bst.root)
print()
print(bst.toList())
bst.insert(11,11)
bst.display(bst.root)
print()
print(bst.toList())
bst.remove(13)
bst.display(bst.root)
print()
print(bst.toList())
15(5(3(,),12(10(6(,7(,)),),13(,))),16(,20(18(,),23(,))))
[3, 5, 6, 7, 10, 12, 13, 15, 16, 18, 20, 23]
15(5(3(,),12(10(6(,7(,)),11(,)),13(,))),16(,20(18(,),23(,))))
[3, 5, 6, 7, 10, 11, 12, 13, 15, 16, 18, 20, 23]
15(5(3(,),12(10(6(,7(,)),11(,)),)),16(,20(18(,),23(,))))
[3, 5, 6, 7, 10, 11, 12, 15, 16, 18, 20, 23]
十三.设计next函数和使用KMP算法实施串的模式匹配
from abc import ABCMeta,abstractmethod,abstractproperty
class IString(metaclass=ABCMeta):
@abstractmethod
def clear(self):
pass
@abstractmethod
def isEmpty(self):
pass
@abstractmethod
def length(self):
pass
@abstractmethod
def charAt(self,i):
pass
@abstractmethod
def subString(self,begin,end):
pass
@abstractmethod
def insert(self,i,str):
pass
@abstractmethod
def delete(self,begin,end):
pass
@abstractmethod
def concat(self,str):
pass
@abstractmethod
def compareTo(self,str):
pass
@abstractmethod
def indexOf(self,str,begin):
pass
class SqString(IString):
def __init__(self,obj=None):
if obj is None:
self.strValue=[]
self.curLen=0
elif isinstance(obj,str):
self.curLen=len(obj)
self.strValue=[None]*self.curLen
for i in range(self.curLen):
self.strValue[i]=obj[i]
elif isinstance(obj,list):
self.curLen=len(obj)
self.strValue=[None]*self.curLen
for i in range(self.curLen):
self.strValue[i]=obj[i]
def clear(self):
self.curLen=0
def isEmpty(self):
return self.curLen==0
def length(self):
return self.curLen
def charAt(self,i):
if i<0 or i>=self.curLen:
raise IndexError("String index out of range")
return self.strValue[i]
def allocate(self,newCapacity):
tmp=self.strValue
self.strValue=[None]*newCapacity
for i in range(self.curLen):
self.strValue[i]=tmp[i]
def subString(self,begin,end):
if begin<0 or begin>=end or end>self.curLen:
raise IndexError("参数不合法")
tmp=[None]*(end-begin)
for i in range(begin,end):
tmp[i-begin]=self.strValue[i]
return SqString(tmp)
def insert(self,i,str):
if i<0 or i>self.curLen:
raise IndexError("插入位置不合法")
length=str.length()
newCapacity=self.curLen+length
self.allocate(newCapacity)
for j in range(self.curLen-1,i-1,-1):
self.strValue[j+length]=self.strValue[j]
for j in range(i,i+length):
self.strValue[j]=str.charAt(j-i)
self.curLen=newCapacity
def delete(self,begin,end):
if begin<0 or begin>=end or end>self.curLen:
raise IndexError("参数不合法")
for i in range(begin,end):
self.strValue[i]=self.strValue[i+end-begin]
self.curLen=self.curLen-end+begin
def concat(self,str):
self.insert(self.curLen,str)
def compareTo(self,str):
n=self.curLen if self.curLen<str.length() else str.length()
for i in range(n):
if self.strValue[i]>str.charAt(i):
return 1
if self.strValue[i]<str.charAt(i):
return -1
if self.curLen>str.length():
return 1
elif self.curLen<str.length():
return -1
return 0
def indexOf(self,str,begin):
pass
def BF(self,str,begin):
count=0
if str.length()<=self.curLen and str is not None and self.curLen>0:
i=begin
length=str.length()
while i<=self.curLen-length:
for j in range(length):
count+=1
if str.charAt(j)!=self.strValue[j+1]:
i+=1
break
elif j==length-1:
return i,count
return -1,count
def next(p):
next=[0]*p.length() # next数组
k=0 # 模式串指针
j=1 # 主串指针
next[0]=-1
next[1]=0
while j<p.length()-1:
if p.charAt(j)==p.charAt(k):
next[j+1]=k+1
k+=1
j+=1
elif k==0:
next[j+1]=0
j+=1
else:
k=next[k]
return next
def KMP(self,p,begin):
count=0
next=SqString.next(p) # 计算next值
i=begin # i为主串的字符指针
j=0
while i<self.curLen and j<p.length():
count+=1
if j==-1 or self.strValue[i]==p.charAt(j):
i+=1
j+=1
else:
j=next[j]
if j==p.length():
return i-j,count # 匹配
else:
return -1,count
def display(self):
for i in range(self.curLen):
print(self.strValue[i],end=" ")
if __name__=="__main__":
s=SqString("abcbcaabc")
p=SqString("bcaa")
i,c=s.KMP(p,0)
if i>0:
print("匹配")
else:
print("不匹配")
匹配
十四.十字链表的存储
当稀疏矩阵中非零元素的位置或个数经常发生变化时不宜采用三元组顺序表存储结构,而应该采用链表存储结构表示.十字链表是稀疏矩阵的另一种存储结构,在十字链表中稀疏矩阵的非零元素用一个节点来表示,每个节点有5个域组成,如下图所示.其中row域存放该元素的行号,col域存放该元素的列号,value域存放该元素的值,right域存放与该元素同行的下一个非零元素节点的指针,down域存放与该元素同列的下一个非零元素.每个非零数据元素节点既是某个行链表中的一个节点,也是某个列链表中的节点,整个稀疏矩阵构成了一个十字交叉的链表,这样的链表称为十字链表
from IPython.display import Image
Image(filename="./data/test.png",width=500)
构建3个类,即三元组节点类TripleNode,十字链表存储的节点类OLNode和十字链表存储类CrossList,实现十字链表的存储.当输入一组稀疏矩阵数据时能输出矩阵的非零元素的个数,并分别从行和列输出非零元素
class OLNode(object):
def __init__(self,data=None,right=None,down=None):
self.data=data
self.right=right
self.down=down
class TripleNode(object):
def __init__(self,value,row,col):
self.value=value
self.row=row
self.col=col
class CrossList(object):
def __init__(self,rows,cols):
self.initHeader(rows,cols)
def initHeader(self,rows,cols):
self.rows=rows
self.cols=cols
self.rhead=[None]*rows
self.chead=[None]*cols
self.nums=0
for i in range(rows):
self.rhead[i]=OLNode()
for i in range(cols):
self.chead[i]=OLNode()
def insert(self,row,col,value):
self.nums+=1
data=TripleNode(value,row,col)
newNode=OLNode(data)
t=self.rhead[row]
while t.right is not None:
t=t.right
t.right=newNode
t=self.chead[col]
while t.down is not None:
t=t.down
t.down=newNode
def PrintArrOfRC(self):
print("原始矩阵共%s行%s列,%s个非零元素"%(self.rows,self.cols,self.nums))
print("------------------------------")
print("从行来看")
for row in range(self.rows):
print("行%s:"%row,end=" ")
t=self.rhead[row].right
while t is not None:
data=t.data
print("(value:%s,row:%s,col:%s)"%(data.value,data.row,data.col),end=" ")
t=t.right
print()
print("------------------------------")
print("从列来看")
for col in range(self.cols):
print("列%s:" % col, end=" ")
t = self.chead[col].down
while t is not None:
data = t.data
print("(value:%s,row:%s,col:%s)" % (data.value, data.row, data.col), end=" ")
t = t.down
print()
def List2CrossList(datas):
rows=len(datas)
cols=len(datas[0])
cl=CrossList(rows,cols)
for row in range(rows):
for col in range(cols):
value=datas[row][col]
if value!=0:
cl.insert(row,col,value)
return cl
if __name__=="__main__":
cl=CrossList.List2CrossList([
[0,0,1,0],
[1,0,0,4],
[0,0,3,0],
[1,2,0,4]
])
cl.PrintArrOfRC()
原始矩阵共4行4列,7个非零元素
------------------------------
从行来看
行0: (value:1,row:0,col:2)
行1: (value:1,row:1,col:0) (value:4,row:1,col:3)
行2: (value:3,row:2,col:2)
行3: (value:1,row:3,col:0) (value:2,row:3,col:1) (value:4,row:3,col:3)
------------------------------
从列来看
列0: (value:1,row:1,col:0) (value:1,row:3,col:0)
列1: (value:2,row:3,col:1)
列2: (value:1,row:0,col:2) (value:3,row:2,col:2)
列3: (value:4,row:1,col:3) (value:4,row:3,col:3)