This commit is contained in:
mbinary 2019-05-23 23:51:44 +08:00
parent b3a7aa9a9f
commit 936d05bb32
9 changed files with 459 additions and 626 deletions

187
dataStructure/LRU/allOne.py Normal file
View File

@ -0,0 +1,187 @@
''' mbinary
#########################################################################
# File : allOne.py
# Author: mbinary
# Mail: zhuheqin1@gmail.com
# Blog: https://mbinary.xyz
# Github: https://github.com/mbinary
# Created Time: 2018-05-19 23:07
# Description:
#########################################################################
'''
class node:
def __init__(self, val=None, keys=None, pre=None, next=None):
self.val = val
self.keys = set() if keys is None else keys
self.pre = pre
self.next = next
def __lt__(self, nd):
return self.val < nd.val
def __contains__(self, k):
return k in self.keys
def __bool__(self):
return len(self.keys) != 0
def __repr__(self):
return 'node({},{})'.format(self.val, self.keys)
def addKey(self, key):
self.keys.add(key)
def remove(self, key):
self.keys.remove(key)
def getOneKey(self):
if self:
key = self.keys.pop()
self.keys.add(key)
return key
return None
class allOne:
def __init__(self):
self.head = self.tail = node(0)
self.head.next = self.head
self.head.pre = self.head
self.val_node = {0: self.head}
self.key_value = {}
def __str__(self):
li = list(self.val_node.values())
li = [str(i) for i in li]
return 'min:{}, max:{}\n'.format(self.head.val,self.tail.val) \
+ '\n'.join(li)
def __contains__(self,k):
return k in self.key_value
def getMaxKey(self):
return self.tail.getOneKey()
def getMinKey(self):
return self.head.getOneKey()
def getMaxVal(self):
k = self.getMaxKey()
if k is not None:
return self.key_value[k]
def getMinVal(self):
k = self.getMinKey()
if k is not None:
return self.key_value[k]
def addIncNode(self, val):
# when adding a node,inc 1, so it's guranted that node(val-1) exists
self.val_node[val] = node(val)
self.val_node[val].pre = self.val_node[val - 1]
self.val_node[val].next = self.val_node[val - 1].next
self.val_node[val - 1].next.pre = self.val_node[
val - 1].next = self.val_node[val]
if self.tail.val < val:
self.tail = self.val_node[val]
if self.head.val > val or self.head.val == 0:
self.head = self.val_node[val]
def addDecNode(self, val):
# when adding a node,dec 1, so it's guranted that node(val+1) exists
self.val_node[val] = node(val)
self.val_node[val].next = self.val_node[val + 1]
self.val_node[val].pre = self.val_node[val + 1].pre
self.val_node[val + 1].pre.next = self.val_node[
val + 1].pre = self.val_node[val]
if self.head.val > val:
self.head = self.val_node[val]
def delNode(self, val):
self.val_node[val].next.pre = self.val_node[val].pre
self.val_node[val].pre.next = self.val_node[val].next
if self.tail.val == val: self.tail = self.val_node[val].pre
if self.head.val == val: self.head = self.val_node[val].next
del self.val_node[val]
def inc(self, key):
''' inc key to value val'''
val = 1
if key in self.key_value:
val += self.key_value[key]
self.key_value[key] = val
if val not in self.val_node:
self.addIncNode(val)
self.val_node[val].addKey(key)
if val != 1: # key in the pre node
preVal = val - 1
nd = self.val_node[preVal]
if key in nd:
nd.remove(key)
if not nd:
self.delNode(preVal)
def dec(self, key):
if key in self.key_value:
self.key_value[key] -= 1
val = self.key_value[key]
if val == 0:
del self.key_value[key]
elif val>0:
if val not in self.val_node:
self.addDecNode(val)
# notice that the headnode(0) shouldn't add key
self.val_node[val].addKey(key)
nextVal = val + 1
nd = self.val_node[nextVal]
if key in nd:
nd.remove(key)
if not nd:
self.delNode(nextVal)
def delMinKey(self):
key = self.getMinKey()
if key is not None:
val = self.key_value.pop(key)
nd = self.val_node[val]
nd.remove(key)
if not nd:
self.delNode(val)
return key
def append(self,key):
if key in self.key_value:
raise Exception(f'[Error]: key "{key}" exists')
if self.key_value:
val = self.key_value[self.getMaxKey()]
self.key_value[key] = val
self.val_node[val].addKey(key)
self.inc(key)
def move_to_end(self,key):
val = self.key_value.pop(key)
nd = self.val_node[val]
nd.remove(key)
if not nd:
self.delNode(val)
self.append(key)
if __name__ == '__main__':
ops = [
"inc", "inc", "inc", "inc", "inc", "dec", "dec", "getMaxKey",
"getMinKey",'dec'
]
obj = allOne()
data = [["a"], ["b"], ["b"], ["b"], ["b"], ["b"], ["b"], [], [],['a']]
operate = {
"inc": obj.inc,
"dec": obj.dec,
"getMaxKey": obj.getMaxKey,
"getMinKey": obj.getMinKey
}
for op, datum in zip(ops, data):
print(f'{op}({datum}): {operate[op](*datum)}')
print(obj)
print()

View File

@ -0,0 +1,36 @@
from allOne import allOne
'''In this implementation, the lru doesn't use some funcs of allOne,
such as dec,addDecNode
'''
class lru:
def __init__(self, capacity):
self.capacity = capacity
self.allOne = allOne()
self.data = {}
def get(self,key):
if key in self.data:
self.allOne.move_to_end(key)
return self.data[key]
return -1
def put(self,key,value):
if key not in self.data:
if len(self.data)==self.capacity:
k = self.allOne.delMinKey()
if k in self.data:
del self.data[k]
self.data[key]=value
self.allOne.append(key)
else:
self.data[key]=value
self.allOne.move_to_end(key)
if __name__ == '__main__':
ops = ["put","put","get","put","get","put","get","get","get"]
data = [[1,1],[2,2],[1],[3,3],[2],[4,4],[1],[3],[4]]
obj = lru(2)
operate = {'get':obj.get,'put':obj.put}
for op, args in zip(ops,data):
print(f'{op}({args}): {operate[op](*args)}\n{obj.data}\n')

View File

@ -0,0 +1,14 @@
class LRUCache(object):
def __init__(self, capacity):
self.od, self.cap = collections.OrderedDict(), capacity
def get(self, key):
if key not in self.od: return -1
self.od.move_to_end(key)
return self.od[key]
def put(self, key, value):
if key in self.od: del self.od[key]
elif len(self.od) == self.cap: self.od.popitem(False)
self.od[key] = value

View File

@ -10,7 +10,7 @@
#########################################################################
'''
from allOone import AllOne
from allOne import allOne
from time import time
from random import choice,sample,randint
@ -49,12 +49,18 @@ def testCase(n=1000):
def test(repeat=100):
t1,t2=0,0
for i in range(repeat):
allOne = AllOne()
obj = allOne()
operate = {
"inc": obj.inc,
"dec": obj.dec,
"getMaxKey": obj.getMaxKey,
"getMinKey": obj.getMinKey
}
hsmp = hashMap()
ops,data = testCase()
t1-=time()
for op,datum in zip(ops,data):
allOne.op[op](*datum)
operate[op](*datum)
t1+=time()
t2-=time()
@ -66,5 +72,5 @@ def test(repeat=100):
if __name__=='__main__':
t1,t2= test()
print(f'allOone: {t1}')
print(f'allOne: {t1}')
print(f'hashmap: {t2}')

View File

@ -1,213 +0,0 @@
''' mbinary
#########################################################################
# File : allOoneDS.py
# Author: mbinary
# Mail: zhuheqin1@gmail.com
# Blog: https://mbinary.xyz
# Github: https://github.com/mbinary
# Created Time: 2018-05-19 23:07
# Description:
#########################################################################
'''
class node:
def __init__(self,val=None,data_mp=None,pre=None,next=None):
self.val=val
self.data_mp = {} if data_mp is None else data_mp
self.pre=pre
self.next=next
def __lt__(self,nd):
return self.val<nd.val
def getOne(self):
if not self.data_mp:
return ''
else:return list(self.data_mp.items())[0][0]
def __getitem__(self,key):
return self.data_mp[key]
def __iter__(self):
return iter(self.data_mp)
def __delitem__(self,key):
del self.data_mp[key]
def __setitem__(self,key,val):
self.data_mp[key]= val
def isEmpty(self):
return self.data_mp=={}
def __repr__(self):
return 'node({},{})'.format(self.val,self.data_mp)
class doubleLinkedList:
def __init__(self):
self.head= self.tail = node(0)
self.head.next = self.head
self.head.pre = self.head
self.chain_mp={0:self.head}
def __str__(self):
li = list(self.chain_mp.values())
li = [str(i) for i in li]
return 'min:{}, max:{}\n'.format(self.head.val,self.tail.val) \
+ '\n'.join(li)
def getMax(self):
return self.tail.getOne()
def getMin(self):
return self.head.getOne()
def addIncNode(self,val):
# when adding a node,inc 1, so it's guranted that node(val-1) exists
self.chain_mp[val].pre= self.chain_mp[val-1]
self.chain_mp[val].next= self.chain_mp[val-1].next
self.chain_mp[val-1].next.pre = self.chain_mp[val-1].next = self.chain_mp[val]
def addDecNode(self,val):
# when adding a node,dec 1, so it's guranted that node(val+1) exists
self.chain_mp[val].next= self.chain_mp[val+1]
self.chain_mp[val].pre= self.chain_mp[val+1].pre
self.chain_mp[val+1].pre.next = self.chain_mp[val+1].pre = self.chain_mp[val]
def addNode(self,val,dec=False):
self.chain_mp[val] = node(val)
if dec:self.addDecNode(val)
else:self.addIncNode(val)
if self.tail.val<val:self.tail = self.chain_mp[val]
if self.head.val>val or self.head.val==0:self.head= self.chain_mp[val]
def delNode(self,val):
self.chain_mp[val].next.pre = self.chain_mp[val].pre
self.chain_mp[val].pre.next = self.chain_mp[val].next
if self.tail.val==val:self.tail = self.chain_mp[val].pre
if self.head.val==val:self.head = self.chain_mp[val].next
del self.chain_mp[val]
def incTo(self,key,val):
if val not in self.chain_mp:
self.addNode(val)
self.chain_mp[val][key] = val
if val!=1 : # key in the pre node
del self.chain_mp[val-1][key]
#print(self.chain_mp[val-1])
if self.chain_mp[val-1].isEmpty():
#print('*'*20)
self.delNode(val-1)
def decTo(self,key,val):
if val not in self.chain_mp:
self.addNode(val,dec=True)
# notice that the headnode(0) shouldn't add key
if val!=0: self.chain_mp[val][key] = val
del self.chain_mp[val+1][key]
if self.chain_mp[val+1].isEmpty():
self.delNode(val+1)
class AllOne:
def __init__(self):
"""
Initialize your data structure here.
"""
self.op = {"inc":self.inc,"dec":self.dec,"getMaxKey":self.getMaxKey,"getMinKey":self.getMinKey}
self.mp = {}
self.dll = doubleLinkedList()
def __str__(self):
return str(self.dll)
def __getitem__(self,key):
return self.mp[key]
def __delitem__(self,key):
del self.mp[key]
def __setitem__(self,key,val):
self.mp[key]= val
def __iter__(self):
return iter(self.mp)
def inc(self, key,n=1):
"""
Inserts a new key <Key> with value 1. Or increments an existing key by 1.
:type key: str
:rtype: void
"""
if key in self:
self[key]+=n
else:self[key]=n
for i in range(n): self.dll.incTo(key, self[key])
def dec(self, key,n=1):
"""
Decrements an existing key by 1. If Key's value is 1, remove it from the data structure.
:type key: str
:rtype: void
"""
if key in self.mp:
mn = min( self[key],n)
for i in range(mn): self.dll.decTo(key, self[key]-i-1)
if self[key] == n:
del self[key]
else:
self[key] = self[key]-n
def getMaxKey(self):
"""
Returns one of the keys with maximal value.
:rtype: str
"""
return self.dll.getMax()
def getMinKey(self):
"""
Returns one of the keys with Minimal value.
:rtype: str
"""
return self.dll.getMin()
if __name__ == '__main__':
ops=["inc","inc","inc","inc","inc","dec","dec","getMaxKey","getMinKey"]
data=[["a"],["b"],["b"],["b"],["b"],["b"],["b"],[],[]]
obj = AllOne()
for op,datum in zip(ops,data):
print(obj.op[op](*datum))
print(op,datum)
print(obj)
'''
None
inc ['a']
min:1, max:1
node(0,{})
node(1,{'a': 1})
None
inc ['b']
min:1, max:1
node(0,{})
node(1,{'a': 1, 'b': 1})
None
inc ['b']
min:1, max:2
node(0,{})
node(1,{'a': 1})
node(2,{'b': 2})
None
inc ['b']
min:1, max:3
node(0,{})
node(1,{'a': 1})
node(3,{'b': 3})
None
inc ['b']
min:1, max:4
node(0,{})
node(1,{'a': 1})
node(4,{'b': 4})
None
dec ['b']
min:1, max:3
node(0,{})
node(1,{'a': 1})
node(3,{'b': 3})
None
dec ['b']
min:1, max:2
node(0,{})
node(1,{'a': 1})
node(2,{'b': 2})
b
getMaxKey []
min:1, max:2
node(0,{})
node(1,{'a': 1})
node(2,{'b': 2})
a
getMinKey []
min:1, max:2
node(0,{})
node(1,{'a': 1})
node(2,{'b': 2})
'''

View File

@ -10,144 +10,175 @@
#########################################################################
'''
from collections import Iterable,deque
from collections import Iterable, deque
class vertex:
def __init__(self,mark,firstEdge=None,val=None):
def __init__(self, mark, firstEdge=None, val=None):
self.mark = mark
self.val = val
self.firstEdge = firstEdge
self.isVisited = False
def __str__(self):
return 'V'+str(self.mark)
return 'V' + str(self.mark)
def __repr__(self):
return str(self)
class edge:
def __init__(self,adjVertexs, weight = 1,nextEdge=None):
def __init__(self, adjVertexs, weight=1, nextEdge=None):
'''adjVertexs:tuple(v.mark,u.mark)'''
self.weight = weight
self.adjVertexs = adjVertexs
self.nextEdge = nextEdge
self.isVisted = False
def __add__(self,x):
return self.weight +x
def __radd__(self,x):
return self+x
def __getitem__(self,k):
if k!=0 or k!=1:raise IndexError
def __add__(self, x):
return self.weight + x
def __radd__(self, x):
return self + x
def __getitem__(self, k):
if k != 0 or k != 1: raise IndexError
return self.adjVertexs[k]
def __str__(self):
return '--'+str(self.weight)+'--'
return '--' + str(self.weight) + '--'
def __repr__(self):
return str(self)
@property
def v(self):
return self.adjVertexs[0]
@property
def u(self):
return self.adjVertexs[1]
class graph:
def __init__(self):
def __init__(self):
self.vertexs = {}
self.edges = {}
def __getitem__(self,i):
def __getitem__(self, i):
return self.vertexs[i]
def __setitem__(selfi,x):
self.vertexs[i]= x
def __setitem__(selfi, x):
self.vertexs[i] = x
def __iter__(self):
return iter(self.vertexs)
def __bool__(self):
return len(self.vertexs)!=0
def addVertex(self,vertexs):
'''vertexs is a iterable or just a mark that marks the vertex,whichc can be every imutable type'''
if not isinstance(vertexs,Iterable):vertexs=[vertexs]
for i in vertexs:
if not isinstance(i,vertex) and i not in self.vertexs:self.vertexs[i]= vertex(i)
if isinstance(i,vertex) and i not in self.vertexs:self.vertexs[i.mark]= i
def __getVertex(self,v):
if not isinstance(v,vertex):
def __bool__(self):
return len(self.vertexs) != 0
def addVertex(self, vertexs):
'''vertexs is a iterable or just a mark that marks the vertex,whichc can be every imutable type'''
if not isinstance(vertexs, Iterable): vertexs = [vertexs]
for i in vertexs:
if not isinstance(i, vertex) and i not in self.vertexs:
self.vertexs[i] = vertex(i)
if isinstance(i, vertex) and i not in self.vertexs:
self.vertexs[i.mark] = i
def __getVertex(self, v):
if not isinstance(v, vertex):
if v not in self.vertexs:
self.vertexs[v]=vertex(v)
self.vertexs[v] = vertex(v)
return self.vertexs[v]
return v
def addEdge(self,v,u,weight = 1):
def addEdge(self, v, u, weight=1):
v = self.__getVertex(v)
u = self.__getVertex(u)
arc = self.findEdge(v,u)
if arc!=None:return #examine that if v,u have been already connected
vertexs = (v,u)
newEdge = edge (vertexs,weight)
arc = self.findEdge(v, u)
if arc != None:
return #examine that if v,u have been already connected
vertexs = (v, u)
newEdge = edge(vertexs, weight)
self.edges[vertexs] = newEdge
if v.firstEdge==None:
v.firstEdge=newEdge
if v.firstEdge == None:
v.firstEdge = newEdge
else:
arc=v.firstEdge.nextEdge
v.firstEdge=newEdge
def findEdge(self,v,u):
arc = v.firstEdge.nextEdge
v.firstEdge = newEdge
def findEdge(self, v, u):
v = self.__getVertex(v)
u = self.__getVertex(u)
arc = v.firstEdge
while arc!=None and u not in arc:
while arc != None and u not in arc:
arc = arc.nextEdge
if arc!=None:return arc
if arc != None: return arc
arc = u.firstEdge
while arc!=None and v not in arc:
while arc != None and v not in arc:
arc = arc.nextEdge
return arc
def delEdge(self,v,u):
if not isinstance(v,vertex):v= self.vertexs[v]
if not isinstance(u,vertex):u= self.vertexs[u]
if u in v.firstEdge:
v.firstEdge =v.firstEdge.nextEdge
def delEdge(self, v, u):
if not isinstance(v, vertex): v = self.vertexs[v]
if not isinstance(u, vertex): u = self.vertexs[u]
if u in v.firstEdge:
v.firstEdge = v.firstEdge.nextEdge
else:
arc = v.firstEdge
while arc.nextEdge!=e:
while arc.nextEdge != e:
arc = arc.nextEdge
if arc!=None: arc.nextEdge = arc.nextEdge.nextEdge
if arc != None: arc.nextEdge = arc.nextEdge.nextEdge
else:
if v in u.firstEdge:
u.firstEdge =u.firstEdge.nextEdge
if v in u.firstEdge:
u.firstEdge = u.firstEdge.nextEdge
else:
arc = u.firstEdge
while arc.nextEdge!=e:
while arc.nextEdge != e:
arc = arc.nextEdge
arc.nextEdge = arc.nextEdge.nextEdge
del self.edges[(v,u)]
del self.edges[(v, u)]
def revisit(self):
for i in self.vertexs.values():
i.isVisited = False
for i in self.edges.values():
i.isVisited = False
def __str__(self):
arcs= list(self.edges.keys())
arcs=[str(i[0])+str(self.edges[i])+str(i[1]) for i in arcs]
s= '\n'.join(arcs)
arcs = list(self.edges.keys())
arcs = [str(i[0]) + str(self.edges[i]) + str(i[1]) for i in arcs]
s = '\n'.join(arcs)
return s
def __repr__(self):
return str(self)
def minPath(self,v,u):
if v not in self or u not in self:return -1
v=self.__getVertex(v)
u=self.__getVertex(u)
q=deque([v])
last={i:None for i in self.vertexs.values()}
def minPath(self, v, u):
if v not in self or u not in self: return -1
v = self.__getVertex(v)
u = self.__getVertex(u)
q = deque([v])
last = {i: None for i in self.vertexs.values()}
last[v] = 0
ds={i:1000000 for i in self.vertexs.values()}
ds[v]=0
while len(q)!=0:
ds = {i: 1000000 for i in self.vertexs.values()}
ds[v] = 0
while len(q) != 0:
nd = q.popleft()
nd.isVisited=True
nd.isVisited = True
arc = nd.firstEdge
while arc!=None:
tgt=None
if arc.v==nd:
while arc != None:
tgt = None
if arc.v == nd:
tgt = arc.u
else:tgt = arc.v
tmp=ds[nd]+arc
if ds[tgt] >tmp:
ds[tgt]=tmp
else:
tgt = arc.v
tmp = ds[nd] + arc
if ds[tgt] > tmp:
ds[tgt] = tmp
last[tgt] = nd
if not tgt.isVisited:q.append(tgt)
if not tgt.isVisited: q.append(tgt)
'''
cur = u
while cur !=v:
@ -156,36 +187,39 @@ class graph:
print(str(v))
'''
return ds[u]
def hasCircle(self):
pass
def display(self):
print('vertexs')
for i in self.vertexs:
print(i)
print('edges')
for i in self.edges:
arc=self.edges[i]
print(str(arc.v)+str(arc)+str(arc.u))
if __name__=='__main__':
n=int(input())
while n>0:
cities=int(input())
n-=1
g=graph()
li={}
arc = self.edges[i]
print(str(arc.v) + str(arc) + str(arc.u))
if __name__ == '__main__':
n = int(input())
while n > 0:
cities = int(input())
n -= 1
g = graph()
li = {}
for i in range(cities):
li[input()]=i+1
arc=int(input())
li[input()] = i + 1
arc = int(input())
for j in range(arc):
s=input().split(' ')
g.addEdge(i+1,int(s[0]),int(s[1]))
ct =int(input())
for i in range(ct):
s = input().split(' ')
g.addEdge(i + 1, int(s[0]), int(s[1]))
ct = int(input())
for i in range(ct):
line = input()
line= line .split(' ')
v,u = li[line[0]],li[line[1]]
print(g.minPath(v,u))
line = line.split(' ')
v, u = li[line[0]], li[line[1]]
print(g.minPath(v, u))
g.revisit()
#http://www.spoj.com/submit/SHPATH/id=20525991
'''

View File

@ -1,198 +0,0 @@
''' mbinary
#########################################################################
# File : undirected.py
# Author: mbinary
# Mail: zhuheqin1@gmail.com
# Blog: https://mbinary.xyz
# Github: https://github.com/mbinary
# Created Time: 2018-04-26 10:33
# Description:
#########################################################################
'''
from collections import Iterable,deque
class vertex:
def __init__(self,mark,val=None):
self.mark = mark
self.val = val
self.edges = {}
self.isVisited = False
def __getitem__(self,adjVertexMark):
return self.edges[adjVertexMark]
def __delitem__(self,k):
del self.edges[k]
def __iter__(self):
return iter(self.edges.values())
def __str__(self):
return 'V'+str(self.mark)
def __repr__(self):
return str(self)
class edge:
def __init__(self,adjVertexs, weight = 1):
'''adjVertexs:tuple(v.mark,u.mark)'''
self.weight = weight
self.adjVertexs = adjVertexs
self.isVisted = False
def __add__(self,x):
return self.weight +x
def __radd__(self,x):
return self+x
def __getitem__(self,k):
if k!=0 or k!=1:raise IndexError
return self.adjVertexs[k]
def __str__(self):
return '--'+str(self.weight)+'--'
def __repr__(self):
return str(self)
@property
def v(self):
return self.adjVertexs[0]
@property
def u(self):
return self.adjVertexs[1]
class graph:
def __init__(self):
self.vertexs = {}
self.edges = {}
def __getitem__(self,i):
return self.vertexs[i]
def __setitem__(selfi,x):
self.vertexs[i]= x
def __iter__(self):
return iter(self.vertexs)
def __bool__(self):
return len(self.vertexs)!=0
def addVertex(self,vertexs):
'''vertexs is a iterable or just a mark that marks the vertex,whichc can be every imutable type'''
if not isinstance(vertexs,Iterable):vertexs=[vertexs]
for i in vertexs:
if not isinstance(i,vertex) and i not in self.vertexs:self.vertexs[i]= vertex(i)
if isinstance(i,vertex) and i not in self.vertexs:self.vertexs[i.mark]= i
def __getVertex(self,v):
if not isinstance(v,vertex):
if v not in self.vertexs:
self.vertexs[v]=vertex(v)
return self.vertexs[v]
return v
def addEdge(self,v,u,weight = 1):
v = self.__getVertex(v)
u = self.__getVertex(u)
for arc in v:
if u in arc.adjVertexs:return #examine that if v,u have been already connected
vertexs = (v,u)
newEdge = edge (vertexs,weight)
self.edges[vertexs] = newEdge
v.edges[u] = newEdge
u.edges[v] = newEdge
def delEdge(self,v,u):
if not isinstance(v,vertex):v= self.vertexs[v]
if not isinstance(u,vertex):u= self.vertexs[u]
try:
del v[u]
del u[v]
except:print("error!"+str(v)+','+str(u)+' arent adjacent now')
del self.edges[(v,u)]
def revisit(self):
for i in self.vertexs.values():
i.isVisited = False
for i in self.edges.values():
i.isVisited = False
def __str__(self):
arcs= list(self.edges.keys())
arcs=[str(i[0])+str(self.edges[i])+str(i[1]) for i in arcs]
s= '\n'.join(arcs)
return s
def __repr__(self):
return str(self)
def minPath(self,v,u):
v=self.__getVertex(v)
u=self.__getVertex(u)
q=deque([v])
last={i:None for i in self.vertexs.values()}
last[v] = 0
ds={i:1000000 for i in self.vertexs.values()}
ds[v]=0
while len(q)!=0:
nd = q.popleft()
nd.isVisited=True
for edge in nd:
tgt=None
if edge.v==nd:
tgt = edge.u
else:tgt = edge.v
tmp=ds[nd]+edge
if ds[tgt] >tmp:
ds[tgt]=tmp
last[tgt] = nd
if not tgt.isVisited:q.append(tgt)
'''
cur = u
while cur !=v:
print(str(cur)+'<---',end='')
cur =last[cur]
print(str(v))
'''
return ds[u]
def hasCircle(self):
pass
def display(self):
print('vertexs')
for i in self.vertexs:
print(i)
print('edges')
for i in self.edges:
arc=self.edges[i]
print(str(arc.v)+str(arc)+str(arc.u))
if __name__=='__main__':
n=int(input())
while n>0:
cities=int(input())
n-=1
g=graph()
li={}
for i in range(cities):
li[input()]=i+1
arc=int(input())
for j in range(arc):
s=input().split(' ')
g.addEdge(i+1,int(s[0]),int(s[1]))
ct =int(input())
for i in range(ct):
line = input()
line= line .split(' ')
v,u = li[line[0]],li[line[1]]
print(g.minPath(v,u))
g.revisit()
#http://www.spoj.com/submit/SHPATH/id=20525991
'''
1
4
gdansk
2
2 1
3 3
bydgoszcz
3
1 1
3 1
4 4
torun
3
1 3
2 1
4 1
warszawa
2
2 4
3 1
2
gdansk warszawa
bydgoszcz warszawa
V4<---V3<---V2<---V1
3
V4<---V3<---V2
2
>>>
'''

View File

@ -1,57 +0,0 @@
#coding: utf-8
''' mbinary
#######################################################################
# File : wildcard_matching.py
# Author: mbinary
# Mail: zhuheqin1@gmail.com
# Blog: https://mbinary.xyz
# Github: https://github.com/mbinary
# Created Time: 2018-12-13 22:46
# Description:
wild card '*' matches 0 or any chars, and '?' matches any single char.
#######################################################################
'''
'''
idea
dynamic programming
dp[m+1][n+1]: bool
i:n, j:m
dp[j][i] indicates if s[:i+1] matches p[:j+1]
initial: dp[0][0] = True, dp[0][i],dp[j][0] = False
only if p startswith '*', dp[1][0] = True.
if p[j] = '*': dp[j][i] = dp[j-1][i] or dp[j][i-1]
elif p[j] = '?': dp[j][i] = dp[j-1][i-1]
else : dp[j][i] = dp[j-1][i-1] and s[i] == p[j]
'''
# leetcode: q44 https://leetcode.com/problems/wildcard-matching/description/
def isMatch(self, s, p):
"""
:type s: str
:type p: str pattern str including wildcard
:rtype: bool
"""
n,m = len(s),len(p)
last = [False]*(n+1)
last[0] = True
for j in range(m):
if p[j]=='*':
for i in range(n):
last[i+1] = last[i+1] or last[i]
elif p[j]=='?':
last.pop()
last.insert(0,False)
else:
li = [False]
for i in range(n):
li.append( last[i] and p[j]==s[i])
last = li
return last[-1]

View File

@ -10,98 +10,122 @@
#########################################################################
'''
def quickSort(lst):
'''A optimized version of Hoare partition'''
def partition(a,b):
def partition(a, b):
pivot = lst[a]
while a!=b:
while a<b and lst[b]>pivot: b-=1
if a<b:
while a != b:
while a < b and lst[b] > pivot:
b -= 1
if a < b:
lst[a] = lst[b]
a+=1
while a<b and lst[a]<pivot: a+=1
if a<b:
a += 1
while a < b and lst[a] < pivot:
a += 1
if a < b:
lst[b] = lst[a]
b-=1
b -= 1
lst[a] = pivot
return a
def _sort(a,b):
if a>=b:return
mid = (a+b)//2
def _sort(a, b):
if a >= b: return
mid = (a + b) // 2
# 三数取中值置于第一个作为 pivot
if (lst[a]<lst[mid]) ^ (lst[b]<lst[mid]): lst[a],lst[mid] = lst[mid],lst[a] # lst[mid] 为中值
if (lst[a]<lst[b]) ^ (lst[b]>lst[mid]): lst[a],lst[b] = lst[b],lst[a] # lst[b] 为中值
i = partition(a,b)
_sort(a,i-1)
_sort(i+1,b)
_sort(0,len(lst)-1)
if (lst[a] < lst[mid]) ^ (lst[b] < lst[mid]):
lst[a], lst[mid] = lst[mid], lst[a] # lst[mid] 为中值
if (lst[a] < lst[b]) ^ (lst[b] > lst[mid]):
lst[a], lst[b] = lst[b], lst[a] # lst[b] 为中值
i = partition(a, b)
_sort(a, i - 1)
_sort(i + 1, b)
_sort(0, len(lst) - 1)
return lst
def quickSort2(lst):
'''A version of partition from <Introduction of Algorithm>, a little bit slow'''
def partition(a,b):
pivot = lst[b]
j = a-1
for i in range(a,b):
if lst[i]<=pivot:
j+=1
if i!=j: lst[i], lst[j] = lst[j], lst[i]
lst[j+1],lst[b] = lst[b],lst[j+1]
return j+1
def _sort(a,b):
if a>=b:return
mid = (a+b)//2
# 三数取中值置于第一个作为 pivot
if (lst[a]<lst[mid]) ^ (lst[b]<lst[mid]): lst[b],lst[mid] = lst[mid],lst[b] # lst[mid] 为中值
if (lst[a]>lst[b]) ^ (lst[a]>lst[mid]): lst[a],lst[b] = lst[b],lst[a] # lst[b] 为中值
i = partition(a,b)
_sort(a,i-1)
_sort(i+1,b)
_sort(0,len(lst)-1)
def partition(a, b):
pivot = lst[b]
j = a - 1
for i in range(a, b):
if lst[i] <= pivot:
j += 1
if i != j: lst[i], lst[j] = lst[j], lst[i]
lst[j + 1], lst[b] = lst[b], lst[j + 1]
return j + 1
def _sort(a, b):
if a >= b: return
mid = (a + b) // 2
# 三数取中值置于第一个作为 pivot
if (lst[a] < lst[mid]) ^ (lst[b] < lst[mid]):
lst[b], lst[mid] = lst[mid], lst[b] # lst[mid] 为中值
if (lst[a] > lst[b]) ^ (lst[a] > lst[mid]):
lst[a], lst[b] = lst[b], lst[a] # lst[b] 为中值
i = partition(a, b)
_sort(a, i - 1)
_sort(i + 1, b)
_sort(0, len(lst) - 1)
return lst
def quickSort3(lst):
'''A rear recursive optimization version'''
def partition(a,b):
def partition(a, b):
pivot = lst[b]
j = a-1
for i in range(a,b):
if lst[i]<=pivot:
j+=1
if i!=j: lst[i], lst[j] = lst[j], lst[i]
lst[j+1],lst[b] = lst[b],lst[j+1]
return j+1
def _sort(a,b):
while a<b:
mid = (a+b)//2
j = a - 1
for i in range(a, b):
if lst[i] <= pivot:
j += 1
if i != j: lst[i], lst[j] = lst[j], lst[i]
lst[j + 1], lst[b] = lst[b], lst[j + 1]
return j + 1
def _sort(a, b):
while a < b:
mid = (a + b) // 2
# 三数取中值置于第一个作为 pivot
if (lst[a]<lst[mid]) ^ (lst[b]<lst[mid]): lst[b],lst[mid] = lst[mid],lst[b] # lst[mid] 为中值
if (lst[a]>lst[b]) ^ (lst[a]>lst[mid]): lst[a],lst[b] = lst[b],lst[a] # lst[b] 为中值
i = partition(a,b)
_sort(a,i-1)
a = i+1
_sort(0,len(lst)-1)
if (lst[a] < lst[mid]) ^ (lst[b] < lst[mid]):
lst[b], lst[mid] = lst[mid], lst[b] # lst[mid] 为中值
if (lst[a] > lst[b]) ^ (lst[a] > lst[mid]):
lst[a], lst[b] = lst[b], lst[a] # lst[b] 为中值
i = partition(a, b)
_sort(a, i - 1)
a = i + 1
_sort(0, len(lst) - 1)
return lst
from time import time
def timer(func,lst,n=100):
def timer(func, lst, n=100):
t = time()
for i in range(n):func(lst)
t = time()-t
print('{}: {}s'.format(func.__name__,t))
for i in range(n):
func(lst)
t = time() - t
print('{}: {}s'.format(func.__name__, t))
return t
if __name__ == '__main__':
from random import randint
print('5000 items, repeat 100 times for each')
lst = [randint(0,100) for i in range(5000)]
timer(quickSort,lst.copy())
timer(quickSort2,lst.copy())
timer(quickSort3,lst.copy())
lst = [randint(0, 100) for i in range(5000)]
timer(quickSort, lst.copy())
timer(quickSort2, lst.copy())
timer(quickSort3, lst.copy())
lst = [randint(0,100) for i in range(15)]
lst = [randint(0, 100) for i in range(15)]
print(lst)
print(quickSort(lst.copy()))
print(quickSort2(lst.copy()))
print(quickSort3(lst.copy()))