mirror of
https://github.com/heqin-zhu/algorithm.git
synced 2024-03-22 13:30:46 +08:00
Format codes
This commit is contained in:
parent
985b29ce65
commit
ab86fa483a
10
README.md
10
README.md
|
@ -6,7 +6,7 @@
|
|||
[![repo-size](https://img.shields.io/github/repo-size/mbinary/algorithm.svg)]()
|
||||
[![License](https://img.shields.io/badge/LICENSE-WTFPL-blue.svg)](LICENSE)
|
||||
[![Language](https://img.shields.io/badge/language-python3-orange.svg)]()
|
||||
[![codebeat badge](https://codebeat.co/badges/d52dd17d-a437-4dee-a6ec-cb532e8135bd)](https://codebeat.co/projects/github-com-mbinary-algorithm-master)
|
||||
[![codebeat badge](https://codebeat.co/badges/4ef725b5-405a-4390-a860-a86deefab3f8)](https://codebeat.co/projects/github-com-mbinary-algorithm-master)
|
||||
|
||||
>Notes and codes for learning algorithm and data structures :smiley:
|
||||
|
||||
|
@ -17,12 +17,10 @@ Some pictures and ideas are from `<<Introduction to Algotithm>>`
|
|||
* [.](.)
|
||||
* [LICENSE](./LICENSE)
|
||||
* [README.md](./README.md)
|
||||
* [backtracking](./backtracking)
|
||||
* [dataStructure](./dataStructure)
|
||||
* [LRU](./dataStructure/LRU)
|
||||
* [bTree.py](./dataStructure/bTree.py)
|
||||
* [binaryHeap.py](./dataStructure/binaryHeap.py)
|
||||
* [binaryHeap1.py](./dataStructure/binaryHeap1.py)
|
||||
* [binaryTree.py](./dataStructure/binaryTree.py)
|
||||
* [circularQueue.py](./dataStructure/circularQueue.py)
|
||||
* [graph](./dataStructure/graph)
|
||||
|
@ -32,7 +30,6 @@ Some pictures and ideas are from `<<Introduction to Algotithm>>`
|
|||
* [intervalTree.py](./dataStructure/intervalTree.py)
|
||||
* [leftHeap.py](./dataStructure/leftHeap.py)
|
||||
* [linkedList.py](./dataStructure/linkedList.py)
|
||||
* [loserTree.py](./dataStructure/loserTree.py)
|
||||
* [map.cc](./dataStructure/map.cc)
|
||||
* [polynomial.cpp](./dataStructure/polynomial.cpp)
|
||||
* [polynomial.py](./dataStructure/polynomial.py)
|
||||
|
@ -40,7 +37,7 @@ Some pictures and ideas are from `<<Introduction to Algotithm>>`
|
|||
* [redBlackTree0.py](./dataStructure/redBlackTree0.py)
|
||||
* [splayTree.py](./dataStructure/splayTree.py)
|
||||
* [trie](./dataStructure/trie)
|
||||
* [unionFindSet](./dataStructure/unionFindSet)
|
||||
* [unionFindSet.py](./dataStructure/unionFindSet.py)
|
||||
* [winnerTree.py](./dataStructure/winnerTree.py)
|
||||
* [divideAndConquer](./divideAndConquer)
|
||||
* [min_distance_of_n_points.py](./divideAndConquer/min_distance_of_n_points.py)
|
||||
|
@ -85,8 +82,9 @@ Some pictures and ideas are from `<<Introduction to Algotithm>>`
|
|||
* [PL0-compiler](./parser/PL0-compiler)
|
||||
* [calculator](./parser/calculator)
|
||||
* [declarationParser](./parser/declarationParser)
|
||||
* [poly.c](./poly.c)
|
||||
* [search](./search)
|
||||
* [8Astar.py](./search/8Astar.py)
|
||||
* [Astar.py](./search/Astar.py)
|
||||
* [BFS_knight.hs](./search/BFS_knight.hs)
|
||||
* [binary_search.hs](./search/binary_search.hs)
|
||||
* [bloomFilter.py](./search/bloomFilter.py)
|
||||
|
|
|
@ -10,213 +10,257 @@
|
|||
#########################################################################
|
||||
'''
|
||||
|
||||
|
||||
class node:
|
||||
def __init__(self,keys=None,isLeaf = True,children=None):
|
||||
if keys is None:keys=[]
|
||||
if children is None: children =[]
|
||||
def __init__(self, keys=None, isLeaf=True, children=None):
|
||||
if keys is None:
|
||||
keys = []
|
||||
if children is None:
|
||||
children = []
|
||||
self.keys = keys
|
||||
self.isLeaf = isLeaf
|
||||
self.isLeaf = isLeaf
|
||||
self.children = []
|
||||
def __getitem__(self,i):
|
||||
|
||||
def __getitem__(self, i):
|
||||
return self.keys[i]
|
||||
def __delitem__(self,i):
|
||||
|
||||
def __delitem__(self, i):
|
||||
del self.keys[i]
|
||||
def __setitem__(self,i,k):
|
||||
|
||||
def __setitem__(self, i, k):
|
||||
self.keys[i] = k
|
||||
|
||||
def __len__(self):
|
||||
return len(self.keys)
|
||||
|
||||
def __repr__(self):
|
||||
return str(self.keys)
|
||||
|
||||
def __str__(self):
|
||||
children = ','.join([str(nd.keys) for nd in self.children])
|
||||
return f'keys: {self.keys}\nchildren: {children}\nisLeaf: {self.isLeaf}'
|
||||
def getChd(self,i):
|
||||
|
||||
def getChd(self, i):
|
||||
return self.children[i]
|
||||
def delChd(self,i):
|
||||
|
||||
def delChd(self, i):
|
||||
del self.children[i]
|
||||
def setChd(self,i,chd):
|
||||
|
||||
def setChd(self, i, chd):
|
||||
self.children[i] = chd
|
||||
def getChildren(self,begin=0,end=None):
|
||||
if end is None:return self.children[begin:]
|
||||
|
||||
def getChildren(self, begin=0, end=None):
|
||||
if end is None:
|
||||
return self.children[begin:]
|
||||
return self.children[begin:end]
|
||||
def findKey(self,key):
|
||||
for i,k in enumerate(self.keys):
|
||||
if k>=key:
|
||||
|
||||
def findKey(self, key):
|
||||
for i, k in enumerate(self.keys):
|
||||
if k >= key:
|
||||
return i
|
||||
return len(self)
|
||||
def update(self,keys=None,isLeaf=None,children=None):
|
||||
if keys is not None:self.keys = keys
|
||||
if children is not None:self.children = children
|
||||
if isLeaf is not None: self.isLeaf = isLeaf
|
||||
def insert(self,i,key=None,nd=None):
|
||||
if key is not None:self.keys.insert(i,key)
|
||||
if not self.isLeaf and nd is not None: self.children.insert(i,nd)
|
||||
def isLeafNode(self):return self.isLeaf
|
||||
def split(self,prt,t):
|
||||
|
||||
def update(self, keys=None, isLeaf=None, children=None):
|
||||
if keys is not None:
|
||||
self.keys = keys
|
||||
if children is not None:
|
||||
self.children = children
|
||||
if isLeaf is not None:
|
||||
self.isLeaf = isLeaf
|
||||
|
||||
def insert(self, i, key=None, nd=None):
|
||||
if key is not None:
|
||||
self.keys.insert(i, key)
|
||||
if not self.isLeaf and nd is not None:
|
||||
self.children.insert(i, nd)
|
||||
|
||||
def isLeafNode(self): return self.isLeaf
|
||||
|
||||
def split(self, prt, t):
|
||||
# form new two nodes
|
||||
k = self[t-1]
|
||||
nd1 = node()
|
||||
nd2 = node()
|
||||
nd1.keys,nd2.keys = self[:t-1], self[t:] # note that t is 1 bigger than key index
|
||||
# note that t is 1 bigger than key index
|
||||
nd1.keys, nd2.keys = self[:t-1], self[t:]
|
||||
nd1.isLeaf = nd2.isLeaf = self.isLeaf
|
||||
if not self.isLeaf:
|
||||
if not self.isLeaf:
|
||||
# note that children index is one bigger than key index, and all children included
|
||||
nd1.children, nd2.children = self.children[0:t], self.children[t:]
|
||||
nd1.children, nd2.children = self.children[0:t], self.children[t:]
|
||||
# connect them to parent
|
||||
idx = prt.findKey(k)
|
||||
if prt.children !=[]: prt.children.remove(self) # remove the original node
|
||||
prt.insert(idx,k,nd2)
|
||||
prt.insert(idx,nd = nd1)
|
||||
if prt.children != []:
|
||||
prt.children.remove(self) # remove the original node
|
||||
prt.insert(idx, k, nd2)
|
||||
prt.insert(idx, nd=nd1)
|
||||
return prt
|
||||
|
||||
|
||||
class bTree:
|
||||
def __init__(self,degree=2):
|
||||
def __init__(self, degree=2):
|
||||
self.root = node()
|
||||
self.degree=degree
|
||||
self.degree = degree
|
||||
self.nodeNum = 1
|
||||
self.keyNum = 0
|
||||
def search(self,key,withpath=False):
|
||||
|
||||
def search(self, key, withpath=False):
|
||||
nd = self.root
|
||||
fathers = []
|
||||
while True:
|
||||
i = nd.findKey(key)
|
||||
if i==len(nd): fathers.append((nd,i-1,i))
|
||||
else: fathers.append((nd,i,i))
|
||||
if i<len(nd) and nd[i]==key:
|
||||
if withpath:return nd,i,fathers
|
||||
else:return nd,i
|
||||
if nd.isLeafNode():
|
||||
if withpath:return None,None,None
|
||||
else:return None,None
|
||||
if i == len(nd):
|
||||
fathers.append((nd, i-1, i))
|
||||
else:
|
||||
fathers.append((nd, i, i))
|
||||
if i < len(nd) and nd[i] == key:
|
||||
if withpath:
|
||||
return nd, i, fathers
|
||||
else:
|
||||
return nd, i
|
||||
if nd.isLeafNode():
|
||||
if withpath:
|
||||
return None, None, None
|
||||
else:
|
||||
return None, None
|
||||
nd = nd.getChd(i)
|
||||
def insert(self,key):
|
||||
if len(self.root)== self.degree*2-1:
|
||||
self.root = self.root.split(node(isLeaf=False),self.degree)
|
||||
self.nodeNum +=2
|
||||
|
||||
def insert(self, key):
|
||||
if len(self.root) == self.degree*2-1:
|
||||
self.root = self.root.split(node(isLeaf=False), self.degree)
|
||||
self.nodeNum += 2
|
||||
nd = self.root
|
||||
while True:
|
||||
idx = nd.findKey(key)
|
||||
if idx<len(nd) and nd[idx] == key:return
|
||||
if idx < len(nd) and nd[idx] == key:
|
||||
return
|
||||
if nd.isLeafNode():
|
||||
nd.insert(idx,key)
|
||||
self.keyNum+=1
|
||||
nd.insert(idx, key)
|
||||
self.keyNum += 1
|
||||
return
|
||||
else:
|
||||
chd = nd.getChd(idx)
|
||||
if len(chd)== self.degree*2-1: #ensure its keys won't excess when its chd split and u
|
||||
nd = chd.split(nd,self.degree)
|
||||
self.nodeNum +=1
|
||||
# ensure its keys won't excess when its chd split and u
|
||||
if len(chd) == self.degree*2-1:
|
||||
nd = chd.split(nd, self.degree)
|
||||
self.nodeNum += 1
|
||||
else:
|
||||
nd = chd
|
||||
def delete(self,key):#to do
|
||||
|
||||
def delete(self, key): # to do
|
||||
'''search the key, delete it , and form down to up to rebalance it '''
|
||||
nd,idx ,fathers= self.search(key,withpath=True)
|
||||
if nd is None : return
|
||||
nd, idx, fathers = self.search(key, withpath=True)
|
||||
if nd is None:
|
||||
return
|
||||
del nd[idx]
|
||||
self.keyNum-=1
|
||||
self.keyNum -= 1
|
||||
if not nd.isLeafNode():
|
||||
chd = nd.getChd(idx) # find the predecessor key
|
||||
while not chd.isLeafNode():
|
||||
fathers.append((chd,len(chd)-1,len(chd)))
|
||||
chd = nd.getChd(idx) # find the predecessor key
|
||||
while not chd.isLeafNode():
|
||||
fathers.append((chd, len(chd)-1, len(chd)))
|
||||
chd = chd.getChd(-1)
|
||||
fathers.append((chd,len(chd)-1,len(chd)))
|
||||
nd.insert(idx,chd[-1])
|
||||
fathers.append((chd, len(chd)-1, len(chd)))
|
||||
nd.insert(idx, chd[-1])
|
||||
del chd[-1]
|
||||
if len(fathers)>1:self.rebalance(fathers)
|
||||
def rebalance(self,fathers):
|
||||
nd,keyIdx,chdIdx = fathers.pop()
|
||||
while len(nd)<self.degree-1: # rebalance tree from down to up
|
||||
prt,keyIdx,chdIdx = fathers[-1]
|
||||
lbro = [] if chdIdx==0 else prt.getChd(chdIdx-1)
|
||||
rbro = [] if chdIdx==len(prt) else prt.getChd(chdIdx+1)
|
||||
if len(lbro)<self.degree and len(rbro)<self.degree: # merge two deficient nodes
|
||||
beforeNode,afterNode = None,None
|
||||
if lbro ==[]:
|
||||
if len(fathers) > 1:
|
||||
self.rebalance(fathers)
|
||||
|
||||
def rebalance(self, fathers):
|
||||
nd, keyIdx, chdIdx = fathers.pop()
|
||||
while len(nd) < self.degree-1: # rebalance tree from down to up
|
||||
prt, keyIdx, chdIdx = fathers[-1]
|
||||
lbro = [] if chdIdx == 0 else prt.getChd(chdIdx-1)
|
||||
rbro = [] if chdIdx == len(prt) else prt.getChd(chdIdx+1)
|
||||
if len(lbro) < self.degree and len(rbro) < self.degree: # merge two deficient nodes
|
||||
beforeNode, afterNode = None, None
|
||||
if lbro == []:
|
||||
keyIdx = chdIdx
|
||||
beforeNode,afterNode = nd,rbro
|
||||
beforeNode, afterNode = nd, rbro
|
||||
else:
|
||||
beforeNode,afterNode = lbro,nd
|
||||
keyIdx = chdIdx-1 # important, when choosing
|
||||
beforeNode, afterNode = lbro, nd
|
||||
keyIdx = chdIdx-1 # important, when choosing
|
||||
keys = beforeNode[:]+[prt[keyIdx]]+afterNode[:]
|
||||
children = beforeNode.getChildren() + afterNode.getChildren()
|
||||
isLeaf = beforeNode.isLeafNode()
|
||||
prt.delChd(keyIdx+1)
|
||||
del prt[keyIdx]
|
||||
nd.update(keys,isLeaf,children)
|
||||
prt.children[keyIdx]=nd
|
||||
self.nodeNum -=1
|
||||
elif len(lbro)>=self.degree: # rotate when only one sibling is deficient
|
||||
nd.update(keys, isLeaf, children)
|
||||
prt.children[keyIdx] = nd
|
||||
self.nodeNum -= 1
|
||||
elif len(lbro) >= self.degree: # rotate when only one sibling is deficient
|
||||
keyIdx = chdIdx-1
|
||||
nd.insert(0,prt[keyIdx]) # rotate keys
|
||||
prt[keyIdx] = lbro[-1]
|
||||
nd.insert(0, prt[keyIdx]) # rotate keys
|
||||
prt[keyIdx] = lbro[-1]
|
||||
del lbro[-1]
|
||||
if not nd.isLeafNode(): # if not leaf, move children
|
||||
nd.insert(0,nd=lbro.getChd(-1))
|
||||
nd.insert(0, nd=lbro.getChd(-1))
|
||||
lbro.delChd(-1)
|
||||
else:
|
||||
keyIdx = chdIdx
|
||||
nd.insert(len(nd),prt[keyIdx]) # rotate keys
|
||||
prt[keyIdx] = rbro[0]
|
||||
nd.insert(len(nd), prt[keyIdx]) # rotate keys
|
||||
prt[keyIdx] = rbro[0]
|
||||
del rbro[0]
|
||||
if not nd.isLeafNode(): # if not leaf, move children
|
||||
#note that insert(-1,ele) will make the ele be the last second one
|
||||
nd.insert(len(nd),nd=rbro.getChd(0))
|
||||
# note that insert(-1,ele) will make the ele be the last second one
|
||||
nd.insert(len(nd), nd=rbro.getChd(0))
|
||||
rbro.delChd(0)
|
||||
if len(fathers)==1:
|
||||
if len(self.root)==0:
|
||||
if len(fathers) == 1:
|
||||
if len(self.root) == 0:
|
||||
self.root = nd
|
||||
self.nodeNum -=1
|
||||
self.nodeNum -= 1
|
||||
break
|
||||
nd,i,j = fathers.pop()
|
||||
nd, i, j = fathers.pop()
|
||||
|
||||
def __str__(self):
|
||||
head= '\n'+'-'*30+'B Tree'+'-'*30
|
||||
tail= '-'*30+'the end'+'-'*30+'\n'
|
||||
lst = [[head],[f'node num: {self.nodeNum}, key num: {self.keyNum}']]
|
||||
head = '\n'+'-'*30+'B Tree'+'-'*30
|
||||
tail = '-'*30+'the end'+'-'*30+'\n'
|
||||
lst = [[head], [f'node num: {self.nodeNum}, key num: {self.keyNum}']]
|
||||
cur = []
|
||||
ndNum =0
|
||||
ndTotal= 1
|
||||
ndNum = 0
|
||||
ndTotal = 1
|
||||
que = [self.root]
|
||||
while que!=[]:
|
||||
while que != []:
|
||||
nd = que.pop(0)
|
||||
cur.append(repr(nd))
|
||||
ndNum+=1
|
||||
que+=nd.getChildren()
|
||||
if ndNum==ndTotal:
|
||||
ndNum += 1
|
||||
que += nd.getChildren()
|
||||
if ndNum == ndTotal:
|
||||
lst.append(cur)
|
||||
cur = []
|
||||
ndNum = 0
|
||||
ndTotal =len(que)
|
||||
ndTotal = len(que)
|
||||
lst.append([tail])
|
||||
lst = [','.join(li) for li in lst]
|
||||
return '\n'.join(lst)
|
||||
def __iter__(self,nd = None):
|
||||
if nd is None: nd = self.root
|
||||
|
||||
def __iter__(self, nd=None):
|
||||
if nd is None:
|
||||
nd = self.root
|
||||
que = [nd]
|
||||
while que !=[]:
|
||||
while que != []:
|
||||
nd = que.pop(0)
|
||||
yield nd
|
||||
if nd.isLeafNode():continue
|
||||
if nd.isLeafNode():
|
||||
continue
|
||||
for i in range(len(nd)+1):
|
||||
que.append(nd.getChd(i))
|
||||
|
||||
|
||||
if __name__ =='__main__':
|
||||
if __name__ == '__main__':
|
||||
bt = bTree()
|
||||
from random import shuffle,sample
|
||||
from random import shuffle, sample
|
||||
n = 20
|
||||
lst = [i for i in range(n)]
|
||||
shuffle(lst)
|
||||
test= sample(lst,len(lst)//4)
|
||||
test = sample(lst, len(lst)//4)
|
||||
print(f'building b-tree with {lst}')
|
||||
for i in lst:
|
||||
bt.insert(i)
|
||||
#print(f'inserting {i})
|
||||
#print(bt)
|
||||
# print(f'inserting {i})
|
||||
# print(bt)
|
||||
print(bt)
|
||||
print(f'serching {test}')
|
||||
for i in test:
|
||||
nd,idx = bt.search(i)
|
||||
nd, idx = bt.search(i)
|
||||
print(f'node: {repr(nd)}[{idx}]== {i}')
|
||||
for i in test:
|
||||
print(f'deleting {i}')
|
||||
|
|
|
@ -11,106 +11,137 @@
|
|||
'''
|
||||
|
||||
|
||||
from collections import Iterable
|
||||
from collections import Iterable
|
||||
|
||||
|
||||
class node:
|
||||
def __init__(self,val,freq=1):
|
||||
self.val=val
|
||||
def __init__(self, val, freq=1):
|
||||
self.val = val
|
||||
self.freq = freq
|
||||
def __eq__(self,a):
|
||||
return self.val == a.val
|
||||
def __lt__(self,a):
|
||||
return self.val<a.val
|
||||
def __le__(self,a):
|
||||
return self.val<=a.val
|
||||
def __gt__(self,a):
|
||||
return self.val>a.val
|
||||
def __ge__(self,a):
|
||||
return self.val>=a.val
|
||||
def __ne__(self,a):
|
||||
|
||||
def __eq__(self, a):
|
||||
return self.val == a.val
|
||||
|
||||
def __lt__(self, a):
|
||||
return self.val < a.val
|
||||
|
||||
def __le__(self, a):
|
||||
return self.val <= a.val
|
||||
|
||||
def __gt__(self, a):
|
||||
return self.val > a.val
|
||||
|
||||
def __ge__(self, a):
|
||||
return self.val >= a.val
|
||||
|
||||
def __ne__(self, a):
|
||||
return not self == a
|
||||
|
||||
|
||||
class binaryHeap:
|
||||
def __init__(self,s=None,sortByFrequency = False,reverse=False):
|
||||
self.sortByFrequency=sortByFrequency
|
||||
def __init__(self, s=None, sortByFrequency=False, reverse=False):
|
||||
self.sortByFrequency = sortByFrequency
|
||||
self.reverse = reverse
|
||||
self.data = [node(0)] # make index begin with 1
|
||||
if s==None:return
|
||||
if not isinstance(s,Iterable):s = [s]
|
||||
if s == None:
|
||||
return
|
||||
if not isinstance(s, Iterable):
|
||||
s = [s]
|
||||
for i in s:
|
||||
self.insert(i)
|
||||
|
||||
def __bool__(self):
|
||||
return len(self)!=1
|
||||
def _cmp(self,a,b):
|
||||
return len(self) != 1
|
||||
|
||||
def _cmp(self, a, b):
|
||||
if self.sortByFrequency:
|
||||
if self.reverse:return a.freq>b.freq
|
||||
else:return a.freq<b.freq
|
||||
if self.reverse:
|
||||
return a.freq > b.freq
|
||||
else:
|
||||
return a.freq < b.freq
|
||||
else:
|
||||
if self.reverse:return a>b
|
||||
else:return a<b
|
||||
def insert(self,k):
|
||||
if not isinstance(k,node): k = node(k)
|
||||
if self.reverse:
|
||||
return a > b
|
||||
else:
|
||||
return a < b
|
||||
|
||||
def insert(self, k):
|
||||
if not isinstance(k, node):
|
||||
k = node(k)
|
||||
for j in range(self.data[0].val):
|
||||
i = self.data[j+1]
|
||||
if i==k:
|
||||
i.freq+=1
|
||||
if i == k:
|
||||
i.freq += 1
|
||||
if self.sortByFrequency:
|
||||
idx = self.percolateDown(j+1)
|
||||
self.percolateUp(idx)
|
||||
return
|
||||
return
|
||||
self.data.append(k)
|
||||
self.data[0].val += 1
|
||||
self.percolateUp()
|
||||
def percolateUp(self,n=None):
|
||||
if n ==None:n=self.data[0].val
|
||||
|
||||
def percolateUp(self, n=None):
|
||||
if n == None:
|
||||
n = self.data[0].val
|
||||
tmp = self.data[n]
|
||||
while n!=1 and self._cmp(tmp,self.data[n//2]):
|
||||
while n != 1 and self._cmp(tmp, self.data[n//2]):
|
||||
self.data[n] = self.data[n//2]
|
||||
n = n//2
|
||||
self.data[n] = tmp
|
||||
|
||||
def deleteTop(self):
|
||||
tmp = self.data[1]
|
||||
i = self.percolateDown(1)
|
||||
self.data[i] = self.data[-1]
|
||||
self.data[0].val-= 1
|
||||
self.data[0].val -= 1
|
||||
del self.data[-1]
|
||||
return tmp
|
||||
def percolateDown(self,i):
|
||||
|
||||
def percolateDown(self, i):
|
||||
tmp = self.data[i]
|
||||
while self.data[0].val>=2*i+1:
|
||||
if self._cmp(self.data[i*2],self.data[2*i+1]):
|
||||
self.data[i] = self.data[2*i]
|
||||
i = 2*i
|
||||
else:
|
||||
self.data[i] = self.data[2*i+1]
|
||||
i = 2*i+1
|
||||
while self.data[0].val >= 2*i+1:
|
||||
if self._cmp(self.data[i*2], self.data[2*i+1]):
|
||||
self.data[i] = self.data[2*i]
|
||||
i = 2*i
|
||||
else:
|
||||
self.data[i] = self.data[2*i+1]
|
||||
i = 2*i+1
|
||||
self.data[i] = tmp
|
||||
return i
|
||||
|
||||
def __len__(self):
|
||||
return self.data[0].val
|
||||
def Nth(self,n=1):
|
||||
|
||||
def Nth(self, n=1):
|
||||
tmp = []
|
||||
for i in range(n):
|
||||
tmp.append(self.deleteTop())
|
||||
for i in tmp:
|
||||
self.insert(i)
|
||||
return tmp[-1]
|
||||
|
||||
def display(self):
|
||||
val =self.data[0].val+1
|
||||
val = self.data[0].val+1
|
||||
if self.sortByFrequency:
|
||||
info='heapSort by Frequency:'
|
||||
else:info = 'heapSort by Value:'
|
||||
info = 'heapSort by Frequency:'
|
||||
else:
|
||||
info = 'heapSort by Value:'
|
||||
if self.reverse:
|
||||
info +=' From big to small'
|
||||
else:info +=' From small to big'
|
||||
info += ' From big to small'
|
||||
else:
|
||||
info += ' From small to big'
|
||||
print('*'*15)
|
||||
print(info)
|
||||
print('total items:%d\nval\tfreq'%(val-1))
|
||||
print('total items:%d\nval\tfreq' % (val-1))
|
||||
fmt = '{}\t{}'
|
||||
for i in range(1,val):
|
||||
print(fmt.format(self.data[i].val,self.data[i].freq))
|
||||
for i in range(1, val):
|
||||
print(fmt.format(self.data[i].val, self.data[i].freq))
|
||||
print('*'*15)
|
||||
|
||||
|
||||
class Test:
|
||||
def topKFrequent(self, words, k):
|
||||
hp = binaryHeap(sortByFrequency = True,reverse=True)
|
||||
hp = binaryHeap(sortByFrequency=True, reverse=True)
|
||||
for i in words:
|
||||
hp.insert(i)
|
||||
hp.display()
|
||||
|
@ -124,15 +155,19 @@ class Test:
|
|||
mp[top.freq] = [top.val]
|
||||
for i in mp:
|
||||
mp[i].sort()
|
||||
key = sorted(mp.keys(),reverse = True)
|
||||
key = sorted(mp.keys(), reverse=True)
|
||||
rst = []
|
||||
count = 0
|
||||
for i in key:
|
||||
for i in key:
|
||||
for j in mp[i]:
|
||||
rst.append(j)
|
||||
count+=1
|
||||
if count == k:return rst
|
||||
count += 1
|
||||
if count == k:
|
||||
return rst
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
s=["plpaboutit","jnoqzdute","sfvkdqf","mjc","nkpllqzjzp","foqqenbey","ssnanizsav","nkpllqzjzp","sfvkdqf","isnjmy","pnqsz","hhqpvvt","fvvdtpnzx","jkqonvenhx","cyxwlef","hhqpvvt","fvvdtpnzx","plpaboutit","sfvkdqf","mjc","fvvdtpnzx","bwumsj","foqqenbey","isnjmy","nkpllqzjzp","hhqpvvt","foqqenbey","fvvdtpnzx","bwumsj","hhqpvvt","fvvdtpnzx","jkqonvenhx","jnoqzdute","foqqenbey","jnoqzdute","foqqenbey","hhqpvvt","ssnanizsav","mjc","foqqenbey","bwumsj","ssnanizsav","fvvdtpnzx","nkpllqzjzp","jkqonvenhx","hhqpvvt","mjc","isnjmy","bwumsj","pnqsz","hhqpvvt","nkpllqzjzp","jnoqzdute","pnqsz","nkpllqzjzp","jnoqzdute","foqqenbey","nkpllqzjzp","hhqpvvt","fvvdtpnzx","plpaboutit","jnoqzdute","sfvkdqf","fvvdtpnzx","jkqonvenhx","jnoqzdute","nkpllqzjzp","jnoqzdute","fvvdtpnzx","jkqonvenhx","hhqpvvt","isnjmy","jkqonvenhx","ssnanizsav","jnoqzdute","jkqonvenhx","fvvdtpnzx","hhqpvvt","bwumsj","nkpllqzjzp","bwumsj","jkqonvenhx","jnoqzdute","pnqsz","foqqenbey","sfvkdqf","sfvkdqf"]
|
||||
s = ["plpaboutit", "jnoqzdute", "sfvkdqf", "mjc", "nkpllqzjzp", "foqqenbey", "ssnanizsav", "nkpllqzjzp", "sfvkdqf", "isnjmy", "pnqsz", "hhqpvvt", "fvvdtpnzx", "jkqonvenhx", "cyxwlef", "hhqpvvt", "fvvdtpnzx", "plpaboutit", "sfvkdqf", "mjc", "fvvdtpnzx", "bwumsj", "foqqenbey", "isnjmy", "nkpllqzjzp", "hhqpvvt", "foqqenbey", "fvvdtpnzx", "bwumsj", "hhqpvvt", "fvvdtpnzx", "jkqonvenhx", "jnoqzdute", "foqqenbey", "jnoqzdute", "foqqenbey", "hhqpvvt", "ssnanizsav", "mjc", "foqqenbey", "bwumsj", "ssnanizsav", "fvvdtpnzx", "nkpllqzjzp",
|
||||
"jkqonvenhx", "hhqpvvt", "mjc", "isnjmy", "bwumsj", "pnqsz", "hhqpvvt", "nkpllqzjzp", "jnoqzdute", "pnqsz", "nkpllqzjzp", "jnoqzdute", "foqqenbey", "nkpllqzjzp", "hhqpvvt", "fvvdtpnzx", "plpaboutit", "jnoqzdute", "sfvkdqf", "fvvdtpnzx", "jkqonvenhx", "jnoqzdute", "nkpllqzjzp", "jnoqzdute", "fvvdtpnzx", "jkqonvenhx", "hhqpvvt", "isnjmy", "jkqonvenhx", "ssnanizsav", "jnoqzdute", "jkqonvenhx", "fvvdtpnzx", "hhqpvvt", "bwumsj", "nkpllqzjzp", "bwumsj", "jkqonvenhx", "jnoqzdute", "pnqsz", "foqqenbey", "sfvkdqf", "sfvkdqf"]
|
||||
test = Test()
|
||||
print(test.topKFrequent(s,5))
|
||||
print(test.topKFrequent(s, 5))
|
||||
|
|
|
@ -12,61 +12,86 @@
|
|||
|
||||
from functools import total_ordering
|
||||
|
||||
|
||||
@total_ordering
|
||||
class node:
|
||||
def __init__(self,val,left=None,right=None,freq = 1):
|
||||
self.val=val
|
||||
self.left=left
|
||||
self.right=right
|
||||
def __init__(self, val, left=None, right=None, freq=1):
|
||||
self.val = val
|
||||
self.left = left
|
||||
self.right = right
|
||||
self.freq = freq
|
||||
def __lt__(self,nd):
|
||||
return self.val<nd.val
|
||||
def __eq__(self,nd):
|
||||
return self.val==nd.val
|
||||
|
||||
def __lt__(self, nd):
|
||||
return self.val < nd.val
|
||||
|
||||
def __eq__(self, nd):
|
||||
return self.val == nd.val
|
||||
|
||||
def __repr__(self):
|
||||
return 'node({})'.format(self.val)
|
||||
|
||||
|
||||
|
||||
class binaryTree:
|
||||
def __init__(self):
|
||||
self.root=None
|
||||
def add(self,val):
|
||||
def _add(nd,newNode):
|
||||
if nd<newNode:
|
||||
if nd.right is None:nd.right = newNode
|
||||
else:_add(nd.right,newNode)
|
||||
elif nd>newNode:
|
||||
if nd.left is None:nd.left = newNode
|
||||
else : _add(nd.left,newNode)
|
||||
else:nd.freq +=1
|
||||
_add(self.root,node(val))
|
||||
def find(self,val):
|
||||
prt= self._findPrt(self.root,node(val),None)
|
||||
if prt.left and prt.left.val==val:
|
||||
self.root = None
|
||||
|
||||
def add(self, val):
|
||||
def _add(nd, newNode):
|
||||
if nd < newNode:
|
||||
if nd.right is None:
|
||||
nd.right = newNode
|
||||
else:
|
||||
_add(nd.right, newNode)
|
||||
elif nd > newNode:
|
||||
if nd.left is None:
|
||||
nd.left = newNode
|
||||
else:
|
||||
_add(nd.left, newNode)
|
||||
else:
|
||||
nd.freq += 1
|
||||
_add(self.root, node(val))
|
||||
|
||||
def find(self, val):
|
||||
prt = self._findPrt(self.root, node(val), None)
|
||||
if prt.left and prt.left.val == val:
|
||||
return prt.left
|
||||
elif prt.right and prt.right.val==val:return prt.right
|
||||
else :return None
|
||||
def _findPrt(self,nd,tgt,prt):
|
||||
if nd==tgt or nd is None:return prt
|
||||
elif nd<tgt:return self._findPrt(nd.right,tgt,nd)
|
||||
else:return self._findPrt(nd.left,tgt,nd)
|
||||
def delete(self,val):
|
||||
prt= self._findPrt(self.root,node(val),None)
|
||||
if prt.left and prt.left.val==val:
|
||||
l=prt.left
|
||||
if l.left is None:prt.left = l.right
|
||||
elif l.right is None : prt.left = l.left
|
||||
elif prt.right and prt.right.val == val:
|
||||
return prt.right
|
||||
else:
|
||||
return None
|
||||
|
||||
def _findPrt(self, nd, tgt, prt):
|
||||
if nd == tgt or nd is None:
|
||||
return prt
|
||||
elif nd < tgt:
|
||||
return self._findPrt(nd.right, tgt, nd)
|
||||
else:
|
||||
return self._findPrt(nd.left, tgt, nd)
|
||||
|
||||
def delete(self, val):
|
||||
prt = self._findPrt(self.root, node(val), None)
|
||||
if prt.left and prt.left.val == val:
|
||||
l = prt.left
|
||||
if l.left is None:
|
||||
prt.left = l.right
|
||||
elif l.right is None:
|
||||
prt.left = l.left
|
||||
else:
|
||||
nd = l.left
|
||||
while nd.right is not None:nd = nd.right
|
||||
while nd.right is not None:
|
||||
nd = nd.right
|
||||
nd.right = l.right
|
||||
prt.left = l.left
|
||||
elif prt.right and prt.right.val==val:
|
||||
r=prt.right
|
||||
if r.right is None:prt.right = r.right
|
||||
elif r.right is None : prt.right = r.left
|
||||
elif prt.right and prt.right.val == val:
|
||||
r = prt.right
|
||||
if r.right is None:
|
||||
prt.right = r.right
|
||||
elif r.right is None:
|
||||
prt.right = r.left
|
||||
else:
|
||||
nd = r.left
|
||||
while nd.right is not None:nd = nd.right
|
||||
while nd.right is not None:
|
||||
nd = nd.right
|
||||
nd.right = r.right
|
||||
prt.left = r.left
|
||||
|
||||
|
@ -77,7 +102,9 @@ class binaryTree:
|
|||
_p(nd.left)
|
||||
_p(nd.right)
|
||||
_p(self.root)
|
||||
if __name__=="__main__":
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
t = binaryTree()
|
||||
for i in range(10):
|
||||
t.add((i-4)**2)
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
# Description:
|
||||
#########################################################################
|
||||
'''
|
||||
|
||||
|
||||
class MyCircularQueue:
|
||||
|
||||
def __init__(self, k):
|
||||
|
@ -29,8 +31,9 @@ class MyCircularQueue:
|
|||
if self.isFull():
|
||||
return False
|
||||
self.data[self.rear] = value
|
||||
self.rear = (self.rear+1)%self.size
|
||||
self.rear = (self.rear+1) % self.size
|
||||
return True
|
||||
|
||||
def deQueue(self):
|
||||
"""
|
||||
Delete an element from the circular queue. Return true if the operation is successful.
|
||||
|
@ -38,9 +41,9 @@ class MyCircularQueue:
|
|||
"""
|
||||
if self.isEmpty():
|
||||
return False
|
||||
self.head = (self.head+1)%self.size
|
||||
self.head = (self.head+1) % self.size
|
||||
return True
|
||||
|
||||
|
||||
def Front(self):
|
||||
"""
|
||||
Get the front item from the queue.
|
||||
|
@ -49,7 +52,6 @@ class MyCircularQueue:
|
|||
if self.isEmpty():
|
||||
return -1
|
||||
return self.data[self.head]
|
||||
|
||||
|
||||
def Rear(self):
|
||||
"""
|
||||
|
@ -58,23 +60,21 @@ class MyCircularQueue:
|
|||
"""
|
||||
if self.isEmpty():
|
||||
return -1
|
||||
return self.data[(self.rear-1)%self.size]
|
||||
return self.data[(self.rear-1) % self.size]
|
||||
|
||||
def isEmpty(self):
|
||||
"""
|
||||
Checks whether the circular queue is empty or not.
|
||||
:rtype: bool
|
||||
"""
|
||||
return self.head ==self.rear
|
||||
|
||||
return self.head == self.rear
|
||||
|
||||
def isFull(self):
|
||||
"""
|
||||
Checks whether the circular queue is full or not.
|
||||
:rtype: bool
|
||||
"""
|
||||
return (self.head - self.rear)%self.size ==1
|
||||
|
||||
return (self.head - self.rear) % self.size == 1
|
||||
|
||||
|
||||
# Your MyCircularQueue object will be instantiated and called as such:
|
||||
|
|
|
@ -10,18 +10,23 @@
|
|||
#########################################################################
|
||||
'''
|
||||
|
||||
|
||||
class item:
|
||||
def __init__(self,key,val,nextItem=None):
|
||||
def __init__(self, key, val, nextItem=None):
|
||||
self.key = key
|
||||
self.val = val
|
||||
self.next = nextItem
|
||||
def to(self,it):
|
||||
|
||||
def to(self, it):
|
||||
self.next = it
|
||||
def __eq__(self,it):
|
||||
|
||||
def __eq__(self, it):
|
||||
'''using keyword <in> '''
|
||||
return self.key == it.key
|
||||
|
||||
def __bool__(self):
|
||||
return self.key is not None
|
||||
|
||||
def __str__(self):
|
||||
li = []
|
||||
nd = self
|
||||
|
@ -29,27 +34,33 @@ class item:
|
|||
li.append(f'({nd.key}:{nd.val})')
|
||||
nd = nd.next
|
||||
return ' -> '.join(li)
|
||||
|
||||
def __repr__(self):
|
||||
return f'item({self.key},{self.val})'
|
||||
|
||||
|
||||
class hashTable:
|
||||
def __init__(self,size=100):
|
||||
def __init__(self, size=100):
|
||||
self.size = size
|
||||
self.slots=[item(None,None) for i in range(self.size)]
|
||||
def __setitem__(self,key,val):
|
||||
self.slots = [item(None, None) for i in range(self.size)]
|
||||
|
||||
def __setitem__(self, key, val):
|
||||
nd = self.slots[self.myhash(key)]
|
||||
while nd.next:
|
||||
if nd.key ==key:
|
||||
if nd.val!=val: nd.val=val
|
||||
if nd.key == key:
|
||||
if nd.val != val:
|
||||
nd.val = val
|
||||
return
|
||||
nd = nd.next
|
||||
nd.next = item(key,val)
|
||||
nd = nd.next
|
||||
nd.next = item(key, val)
|
||||
|
||||
def myhash(self,key):
|
||||
if isinstance(key,str):
|
||||
def myhash(self, key):
|
||||
if isinstance(key, str):
|
||||
key = sum(ord(i) for i in key)
|
||||
if not isinstance(key,int):
|
||||
if not isinstance(key, int):
|
||||
key = hash(key)
|
||||
return key % self.size
|
||||
|
||||
def __iter__(self):
|
||||
'''when using keyword <in>, such as ' if key in dic',
|
||||
the dic's __iter__ method will be called,(if hasn't, calls __getitem__
|
||||
|
@ -57,18 +68,20 @@ class hashTable:
|
|||
'''
|
||||
for nd in self.slots:
|
||||
nd = nd.next
|
||||
while nd :
|
||||
while nd:
|
||||
yield nd.key
|
||||
nd = nd.next
|
||||
def __getitem__(self,key):
|
||||
nd =self.slots[ self.myhash(key)].next
|
||||
|
||||
def __getitem__(self, key):
|
||||
nd = self.slots[self.myhash(key)].next
|
||||
while nd:
|
||||
if nd.key==key:
|
||||
if nd.key == key:
|
||||
return nd.val
|
||||
nd = nd.next
|
||||
raise Exception(f'[KeyError]: {self.__class__.__name__} has no key {key}')
|
||||
raise Exception(
|
||||
f'[KeyError]: {self.__class__.__name__} has no key {key}')
|
||||
|
||||
def __delitem__(self,key):
|
||||
def __delitem__(self, key):
|
||||
'''note that None item and item(None,None) differ with each other,
|
||||
which means you should take care of them and correctly cop with None item
|
||||
especially when deleting items
|
||||
|
@ -77,31 +90,34 @@ class hashTable:
|
|||
nd = self.slots[n].next
|
||||
if nd.key == key:
|
||||
if nd.next is None:
|
||||
self.slots[n] = item(None,None) # be careful
|
||||
else:self.slots[n] = nd.next
|
||||
self.slots[n] = item(None, None) # be careful
|
||||
else:
|
||||
self.slots[n] = nd.next
|
||||
return
|
||||
while nd:
|
||||
if nd.next is None: break # necessary
|
||||
if nd.next.key ==key:
|
||||
if nd.next is None:
|
||||
break # necessary
|
||||
if nd.next.key == key:
|
||||
nd.next = nd.next.next
|
||||
nd = nd.next
|
||||
|
||||
def __str__(self):
|
||||
li = ['\n\n'+'-'*5+'hashTable'+'-'*5]
|
||||
for i,nd in enumerate(self.slots):
|
||||
for i, nd in enumerate(self.slots):
|
||||
li.append(f'{i}: '+str(nd.next))
|
||||
return '\n'.join(li)
|
||||
|
||||
|
||||
if __name__ =='__main__':
|
||||
|
||||
if __name__ == '__main__':
|
||||
from random import randint
|
||||
dic = hashTable(16)
|
||||
n = 100
|
||||
li = [1,2,5,40,324,123,6,22,18,34,50]
|
||||
li = [1, 2, 5, 40, 324, 123, 6, 22, 18, 34, 50]
|
||||
print(f'build hashTable using {li}')
|
||||
for i in li:
|
||||
dic[i] = '$'+str(i)
|
||||
print(dic)
|
||||
for i in [1,34,45,123]:
|
||||
for i in [1, 34, 45, 123]:
|
||||
if i in dic:
|
||||
print(f'{i} in dic, deleting it')
|
||||
del dic[i]
|
||||
|
|
|
@ -28,348 +28,437 @@ using namespace std;
|
|||
|
||||
void cat(string s)
|
||||
{
|
||||
FILE* f=fopen(s.c_str(),"rb");
|
||||
cout<<"file content"<<endl;
|
||||
while(!feof(f)){
|
||||
cout<<fgetc(f);
|
||||
FILE* f = fopen(s.c_str(), "rb");
|
||||
cout << "file content" << endl;
|
||||
|
||||
while (!feof(f)) {
|
||||
cout << fgetc(f);
|
||||
}
|
||||
cout<<endl;
|
||||
|
||||
cout << endl;
|
||||
}
|
||||
string uniFileName(string file)
|
||||
{
|
||||
FILE * check = fopen(file.c_str(),"rb");
|
||||
if(check){
|
||||
FILE * check = fopen(file.c_str(), "rb");
|
||||
|
||||
if (check) {
|
||||
char c;
|
||||
cout<<"the file "<<file<<" already exists! continue? [Y/n]:"<<flush;
|
||||
c=cin.get();
|
||||
if(c=='n')exit(0);
|
||||
int p,q;
|
||||
p= file.find('(');
|
||||
q=file.rfind('.');
|
||||
if(q==string::npos)q=file.size();
|
||||
if(p==string::npos)p=q;
|
||||
string name=file.substr(0,p),suffix=file.substr(q,file.size());
|
||||
int n=0;
|
||||
while(true){
|
||||
cout << "the file " << file << " already exists! continue? [Y/n]:" << flush;
|
||||
c = cin.get();
|
||||
|
||||
if (c == 'n')exit(0);
|
||||
|
||||
int p, q;
|
||||
p = file.find('(');
|
||||
q = file.rfind('.');
|
||||
|
||||
if (q == string::npos)q = file.size();
|
||||
|
||||
if (p == string::npos)p = q;
|
||||
|
||||
string name = file.substr(0, p), suffix = file.substr(q, file.size());
|
||||
int n = 0;
|
||||
|
||||
while (true) {
|
||||
char s[3];
|
||||
n+=1;
|
||||
snprintf(s,3,"%d",n);
|
||||
file=(name+"("+s+")"+suffix);
|
||||
FILE* f=fopen(file.c_str(),"rb");
|
||||
if(!f)break;
|
||||
n += 1;
|
||||
snprintf(s, 3, "%d", n);
|
||||
file = (name + "(" + s + ")" + suffix);
|
||||
FILE* f = fopen(file.c_str(), "rb");
|
||||
|
||||
if (!f)break;
|
||||
else fclose(f);
|
||||
}
|
||||
}
|
||||
|
||||
return file;
|
||||
}
|
||||
template<class t1, class t2>
|
||||
void mapprint(map<t1,t2> &f)
|
||||
void mapprint(map<t1, t2> &f)
|
||||
{
|
||||
for(class map<t1,t2>::iterator i = f.begin();i!=f.end();++i)
|
||||
cout<<i->first<<") : "<<i->second<<endl;
|
||||
for (class map<t1, t2>::iterator i = f.begin(); i != f.end(); ++i)
|
||||
cout << i->first << ") : " << i->second << endl;
|
||||
}
|
||||
template<typename ky,typename wt>
|
||||
template<typename ky, typename wt>
|
||||
class node
|
||||
{
|
||||
public:
|
||||
public:
|
||||
ky key;
|
||||
wt val;
|
||||
bool visited;
|
||||
node * left,*right;
|
||||
node(const node &a){val = a.val;key= a.key;visited = a.visited;left= a.left;right=a.right;}
|
||||
node(ky k=0,wt v=0):key(k),val(v),visited(false),left(NULL),right(NULL){};
|
||||
bool operator<(const node<ky,wt> & a)const{return val>a.val;};
|
||||
node * left, *right;
|
||||
node(const node &a)
|
||||
{
|
||||
val = a.val;
|
||||
key = a.key;
|
||||
visited = a.visited;
|
||||
left = a.left;
|
||||
right = a.right;
|
||||
}
|
||||
node(ky k = 0, wt v = 0): key(k), val(v), visited(false), left(NULL), right(NULL) {};
|
||||
bool operator<(const node<ky, wt> & a)const
|
||||
{
|
||||
return val > a.val;
|
||||
};
|
||||
};
|
||||
template<typename ky,typename wt>
|
||||
template<typename ky, typename wt>
|
||||
class huffman
|
||||
{
|
||||
private:
|
||||
node<ky,wt> root;
|
||||
node<ky, wt> root;
|
||||
string res;
|
||||
public:
|
||||
long total(){return root.val;}
|
||||
map<ky,string> encode_map;
|
||||
map<string,ky> decode_map;
|
||||
huffman(map<ky,wt>& mp);
|
||||
long total()
|
||||
{
|
||||
return root.val;
|
||||
}
|
||||
map<ky, string> encode_map;
|
||||
map<string, ky> decode_map;
|
||||
huffman(map<ky, wt>& mp);
|
||||
void display();
|
||||
string encode(string,long &);
|
||||
string decode(string,long&);
|
||||
void preOrder(node<ky,wt>*,string);
|
||||
string encode(string, long &);
|
||||
string decode(string, long&);
|
||||
void preOrder(node<ky, wt>*, string);
|
||||
};
|
||||
template<typename ky,typename wt>
|
||||
huffman<ky,wt>::huffman(map<ky,wt>& mp)
|
||||
template<typename ky, typename wt>
|
||||
huffman<ky, wt>::huffman(map<ky, wt>& mp)
|
||||
{
|
||||
if(mp.empty()){
|
||||
cout<<"Error! No data!"<<endl;
|
||||
root=NULL;
|
||||
if (mp.empty()) {
|
||||
cout << "Error! No data!" << endl;
|
||||
root = NULL;
|
||||
return ;
|
||||
}
|
||||
priority_queue<node<ky,wt> > hp;
|
||||
for(typename map<ky,wt>::iterator i=mp.begin();i!=mp.end();++i){
|
||||
hp.push( node<ky,wt>(i->first,i->second));
|
||||
|
||||
priority_queue<node<ky, wt> > hp;
|
||||
|
||||
for (typename map<ky, wt>::iterator i = mp.begin(); i != mp.end(); ++i) {
|
||||
hp.push(node<ky, wt>(i->first, i->second));
|
||||
}
|
||||
int n =hp.size();
|
||||
if(n==1){
|
||||
|
||||
int n = hp.size();
|
||||
|
||||
if (n == 1) {
|
||||
root = hp.top();
|
||||
return;
|
||||
}
|
||||
while(--n>=1){
|
||||
node<ky,wt> *a = new node<ky,wt>(hp.top());
|
||||
|
||||
while (--n >= 1) {
|
||||
node<ky, wt> *a = new node<ky, wt>(hp.top());
|
||||
hp.pop();
|
||||
node<ky,wt> *b = new node<ky,wt>(hp.top());
|
||||
node<ky, wt> *b = new node<ky, wt>(hp.top());
|
||||
hp.pop();
|
||||
node<ky,wt> * tmp = new node<ky,wt>(0,a->val+b->val);
|
||||
tmp->left = a,tmp->right = b;
|
||||
node<ky, wt> * tmp = new node<ky, wt>(0, a->val + b->val);
|
||||
tmp->left = a, tmp->right = b;
|
||||
hp.push(*tmp);
|
||||
}
|
||||
|
||||
root = hp.top();
|
||||
preOrder(&root,string());
|
||||
preOrder(&root, string());
|
||||
}
|
||||
template<typename ky,typename wt>
|
||||
void huffman<ky,wt>::preOrder(node<ky, wt>* nd,string s)
|
||||
template<typename ky, typename wt>
|
||||
void huffman<ky, wt>::preOrder(node<ky, wt>* nd, string s)
|
||||
{
|
||||
if(nd->left == NULL){
|
||||
encode_map[nd->key] =s;
|
||||
if (nd->left == NULL) {
|
||||
encode_map[nd->key] = s;
|
||||
decode_map[s] = nd->key;
|
||||
delete nd;
|
||||
return ;
|
||||
}
|
||||
preOrder(nd->left,s+'0');
|
||||
preOrder(nd->right,s+'1');
|
||||
|
||||
preOrder(nd->left, s + '0');
|
||||
preOrder(nd->right, s + '1');
|
||||
delete nd;
|
||||
}
|
||||
template<typename ky,typename wt>
|
||||
string huffman<ky,wt>::decode(string zipfile_name,long &charNum)
|
||||
template<typename ky, typename wt>
|
||||
string huffman<ky, wt>::decode(string zipfile_name, long &charNum)
|
||||
{
|
||||
string uniFileName(string);
|
||||
FILE * src = fopen(zipfile_name.c_str(),"rb");
|
||||
FILE * src = fopen(zipfile_name.c_str(), "rb");
|
||||
char file_name[nameLength];
|
||||
fgets(file_name,nameLength,src);
|
||||
int ct=-1;
|
||||
while(file_name[++ct]!='\n');
|
||||
fgets(file_name, nameLength, src);
|
||||
int ct = -1;
|
||||
|
||||
while (file_name[++ct] != '\n');
|
||||
|
||||
int pos = zipfile_name.find('.');
|
||||
if(pos==string::npos)pos=zipfile_name.size();
|
||||
string name(zipfile_name.substr(0,pos)) ,suffix(file_name,file_name+ct),file(name+suffix);
|
||||
file=uniFileName(file);
|
||||
cout<<"extracting compressed file :"<<zipfile_name<<endl;
|
||||
FILE * f = fopen(file.c_str(),"wb");
|
||||
|
||||
if (pos == string::npos)pos = zipfile_name.size();
|
||||
|
||||
string name(zipfile_name.substr(0, pos)), suffix(file_name, file_name + ct), file(name + suffix);
|
||||
file = uniFileName(file);
|
||||
cout << "extracting compressed file :" << zipfile_name << endl;
|
||||
FILE * f = fopen(file.c_str(), "wb");
|
||||
char t[numDigit];
|
||||
fgets(t,numDigit,src);
|
||||
int sz=atoi(t);
|
||||
fgets(t, numDigit, src);
|
||||
int sz = atoi(t);
|
||||
char code[sz];
|
||||
fread(code,sz,1,src);
|
||||
int idx=0;
|
||||
for(int i =0;i<sz;++i ){
|
||||
if(code[i]==' '){
|
||||
decode_map[string(code+idx,code+i)]=code[++i];
|
||||
idx=i+1;
|
||||
fread(code, sz, 1, src);
|
||||
int idx = 0;
|
||||
|
||||
for (int i = 0; i < sz; ++i) {
|
||||
if (code[i] == ' ') {
|
||||
decode_map[string(code + idx, code + i)] = code[++i];
|
||||
idx = i + 1;
|
||||
}
|
||||
}
|
||||
for(int i=0;i<starNum;++i)cout<<"@";
|
||||
cout<<endl;
|
||||
|
||||
for (int i = 0; i < starNum; ++i)cout << "@";
|
||||
|
||||
cout << endl;
|
||||
char c;
|
||||
long cur=charNum,gap=charNum/starNum;
|
||||
while(cur){
|
||||
c=fgetc(src);
|
||||
if(!((--cur)%gap))cout<<"@"<<flush;
|
||||
for(int i =0;i<8;++i){
|
||||
if(c&(1<<i))res.append(1,'1');
|
||||
else res.append(1,'0');
|
||||
if(decode_map.count(res)!=0){
|
||||
fputc(decode_map[res],f);
|
||||
long cur = charNum, gap = charNum / starNum;
|
||||
|
||||
while (cur) {
|
||||
c = fgetc(src);
|
||||
|
||||
if (!((--cur) % gap))cout << "@" << flush;
|
||||
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
if (c & (1 << i))res.append(1, '1');
|
||||
else res.append(1, '0');
|
||||
|
||||
if (decode_map.count(res) != 0) {
|
||||
fputc(decode_map[res], f);
|
||||
res.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
cout<<endl;
|
||||
c=fgetc(src);
|
||||
int dgt=fgetc(src);
|
||||
cout<<feof(f);
|
||||
if((int)dgt!=-1 ){
|
||||
for(int i =0;i<dgt;++i){
|
||||
if(c&(1<<i))res.append(1,'1');
|
||||
else res.append(1,'0');
|
||||
if(decode_map.count(res)!=0){
|
||||
fputc(decode_map[res],f);
|
||||
|
||||
cout << endl;
|
||||
c = fgetc(src);
|
||||
int dgt = fgetc(src);
|
||||
cout << feof(f);
|
||||
|
||||
if ((int)dgt != -1) {
|
||||
for (int i = 0; i < dgt; ++i) {
|
||||
if (c & (1 << i))res.append(1, '1');
|
||||
else res.append(1, '0');
|
||||
|
||||
if (decode_map.count(res) != 0) {
|
||||
fputc(decode_map[res], f);
|
||||
res.clear();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose(src);
|
||||
fclose(f);
|
||||
cout<<"get "<<file <<" successfully"<<endl;
|
||||
cout << "get " << file << " successfully" << endl;
|
||||
return file;
|
||||
}
|
||||
template<typename ky,typename wt>
|
||||
string huffman<ky,wt>::encode(string file_name,long &charNum)
|
||||
template<typename ky, typename wt>
|
||||
string huffman<ky, wt>::encode(string file_name, long &charNum)
|
||||
{
|
||||
charNum=0;
|
||||
charNum = 0;
|
||||
string uniFileName(string);
|
||||
int pos =file_name.rfind('.');
|
||||
if(pos==string::npos)pos=file_name.size();
|
||||
string zipfile = file_name.substr(0,pos)+string(".zzip");
|
||||
int pos = file_name.rfind('.');
|
||||
|
||||
if (pos == string::npos)pos = file_name.size();
|
||||
|
||||
string zipfile = file_name.substr(0, pos) + string(".zzip");
|
||||
zipfile = uniFileName(zipfile);
|
||||
cout<<"generating zip file :"<<zipfile<<endl;
|
||||
FILE * dst = fopen(zipfile.c_str(),"wb");
|
||||
FILE * f = fopen(file_name.c_str(),"rb");
|
||||
fputs(file_name.substr(pos).c_str(),dst);
|
||||
fputc('\n',dst);
|
||||
cout << "generating zip file :" << zipfile << endl;
|
||||
FILE * dst = fopen(zipfile.c_str(), "wb");
|
||||
FILE * f = fopen(file_name.c_str(), "rb");
|
||||
fputs(file_name.substr(pos).c_str(), dst);
|
||||
fputc('\n', dst);
|
||||
string data;
|
||||
for(class map<string,ky>::iterator i=decode_map.begin();i!=decode_map.end() ;++i ){
|
||||
|
||||
for (class map<string, ky>::iterator i = decode_map.begin(); i != decode_map.end() ; ++i) {
|
||||
data.append((i->first));
|
||||
data.append(" ");
|
||||
data+=(i->second);
|
||||
data += (i->second);
|
||||
}
|
||||
|
||||
int data_size = data.size(); // calculate the size of the code_data
|
||||
char sz[numDigit];
|
||||
snprintf(sz,numDigit,"%d",data_size);
|
||||
int ct=0;
|
||||
for(;sz[ct];++ct)fputc(sz[ct],dst);
|
||||
fputc('\n',dst);
|
||||
fwrite(data.c_str(),data_size,1,dst);
|
||||
int sum=0,digit=0,num;
|
||||
snprintf(sz, numDigit, "%d", data_size);
|
||||
int ct = 0;
|
||||
|
||||
for (; sz[ct]; ++ct)fputc(sz[ct], dst);
|
||||
|
||||
fputc('\n', dst);
|
||||
fwrite(data.c_str(), data_size, 1, dst);
|
||||
int sum = 0, digit = 0, num;
|
||||
string code8;
|
||||
for(int i=0;i<starNum;++i)cout<<"@";
|
||||
cout<<endl;
|
||||
long gap=root.val/starNum,cur=0;
|
||||
while(!feof(f)){
|
||||
code8=encode_map[fgetc(f)];
|
||||
if(!((++cur)%gap))cout<<"@";
|
||||
for(int i=0;i<code8.size();++i){
|
||||
if(code8[i]=='1')sum += 1<<(digit); //mistake if(tmp[j])
|
||||
|
||||
for (int i = 0; i < starNum; ++i)cout << "@";
|
||||
|
||||
cout << endl;
|
||||
long gap = root.val / starNum, cur = 0;
|
||||
|
||||
while (!feof(f)) {
|
||||
code8 = encode_map[fgetc(f)];
|
||||
|
||||
if (!((++cur) % gap))cout << "@";
|
||||
|
||||
for (int i = 0; i < code8.size(); ++i) {
|
||||
if (code8[i] == '1')sum += 1 << (digit); //mistake if(tmp[j])
|
||||
|
||||
++digit;
|
||||
if(digit==8){
|
||||
|
||||
if (digit == 8) {
|
||||
++charNum;
|
||||
fputc(sum,dst);
|
||||
digit=sum=0;
|
||||
fputc(sum, dst);
|
||||
digit = sum = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
cout<<endl;
|
||||
if(digit!=0){ //mark
|
||||
fputc(sum,dst);
|
||||
fputc(digit,dst);
|
||||
|
||||
cout << endl;
|
||||
|
||||
if (digit != 0) { //mark
|
||||
fputc(sum, dst);
|
||||
fputc(digit, dst);
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
fclose(dst);
|
||||
cout<<"compress "<<file_name <<" successfully"<<endl;
|
||||
cout << "compress " << file_name << " successfully" << endl;
|
||||
return zipfile;
|
||||
}
|
||||
template<typename ky,typename wt>
|
||||
void huffman<ky,wt>::display()
|
||||
template<typename ky, typename wt>
|
||||
void huffman<ky, wt>::display()
|
||||
{
|
||||
cout<<"the encoding map,huffman codes are as bellow:"<<endl;
|
||||
for (typename map<ky,string>::iterator i=encode_map.begin();i!=encode_map.end() ;++i )
|
||||
cout<<i->first<<"("<<(int)i->first<<"):"<<i->second<<endl;
|
||||
cout << "the encoding map,huffman codes are as bellow:" << endl;
|
||||
|
||||
for (typename map<ky, string>::iterator i = encode_map.begin(); i != encode_map.end() ; ++i)
|
||||
cout << i->first << "(" << (int)i->first << "):" << i->second << endl;
|
||||
}
|
||||
bool handle_one(string file_name,vector<long> &origin,vector<long> &compressed)
|
||||
bool handle_one(string file_name, vector<long> &origin, vector<long> &compressed)
|
||||
{
|
||||
int name_length = file_name.size();
|
||||
FILE *src=fopen(file_name.c_str(),"rb");
|
||||
cout<<"opening "<<file_name<<"..."<<endl;
|
||||
if(!src){
|
||||
cout<<"Path Error! Opening "<<file_name<<" Failed"<<endl;
|
||||
FILE *src = fopen(file_name.c_str(), "rb");
|
||||
cout << "opening " << file_name << "..." << endl;
|
||||
|
||||
if (!src) {
|
||||
cout << "Path Error! Opening " << file_name << " Failed" << endl;
|
||||
origin.push_back(0);
|
||||
compressed.push_back(0);
|
||||
return false;
|
||||
}
|
||||
|
||||
char cur;
|
||||
map<char,long> mp;
|
||||
while(!feof(src)){
|
||||
fread(&cur,sizeof(char),1,src);
|
||||
if(mp.count(cur)){
|
||||
mp[cur]+=1;
|
||||
}
|
||||
else mp[cur]=1;
|
||||
map<char, long> mp;
|
||||
|
||||
while (!feof(src)) {
|
||||
fread(&cur, sizeof(char), 1, src);
|
||||
|
||||
if (mp.count(cur)) {
|
||||
mp[cur] += 1;
|
||||
} else mp[cur] = 1;
|
||||
}
|
||||
|
||||
fclose(src);
|
||||
huffman<char,long> hf(mp);
|
||||
huffman<char, long> hf(mp);
|
||||
long sz;
|
||||
string s(hf.encode(file_name,sz));
|
||||
origin.push_back(hf.total()),compressed.push_back(sz);
|
||||
cout<<"\ncontinue to uncompress? [Y/n]"<<endl;
|
||||
char c=cin.get();
|
||||
if(c=='n')return true;
|
||||
hf.decode(s,sz);
|
||||
string s(hf.encode(file_name, sz));
|
||||
origin.push_back(hf.total()), compressed.push_back(sz);
|
||||
cout << "\ncontinue to uncompress? [Y/n]" << endl;
|
||||
char c = cin.get();
|
||||
|
||||
if (c == 'n')return true;
|
||||
|
||||
hf.decode(s, sz);
|
||||
return true;
|
||||
}
|
||||
bool isSep(char c)
|
||||
{
|
||||
return c==' '||c=='\n'||c=='\t'||c==',';
|
||||
return c == ' ' || c == '\n' || c == '\t' || c == ',';
|
||||
}
|
||||
void splitToVec(char * s,vector<string>& v)
|
||||
void splitToVec(char * s, vector<string>& v)
|
||||
{
|
||||
int i=0,last=0;
|
||||
for(;s[i];++i){
|
||||
if(isSep(s[i])){
|
||||
v.push_back(string(s+last,s+i));
|
||||
while(s[++i]&&isSep(s[i]));
|
||||
last=i;
|
||||
int i = 0, last = 0;
|
||||
|
||||
for (; s[i]; ++i) {
|
||||
if (isSep(s[i])) {
|
||||
v.push_back(string(s + last, s + i));
|
||||
|
||||
while (s[++i] && isSep(s[i]));
|
||||
|
||||
last = i;
|
||||
}
|
||||
}
|
||||
if(s[last])v.push_back(string(s+last,s+i));
|
||||
|
||||
if (s[last])v.push_back(string(s + last, s + i));
|
||||
}
|
||||
bool lenStr(string &a,string &b)
|
||||
bool lenStr(string &a, string &b)
|
||||
{
|
||||
return a.size()<b.size();
|
||||
return a.size() < b.size();
|
||||
}
|
||||
void go(vector<string> & names)
|
||||
{
|
||||
vector<long> originSize,compressedSize;
|
||||
vector<long> originSize, compressedSize;
|
||||
vector<int> deltaTime;
|
||||
double last;
|
||||
vector<bool> indicator;
|
||||
bool bl;
|
||||
for(vector<string>::iterator i=names.begin();i!=names.end();++i){
|
||||
|
||||
for (vector<string>::iterator i = names.begin(); i != names.end(); ++i) {
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv,NULL);
|
||||
last=tv.tv_sec;
|
||||
bl=handle_one(*i,originSize,compressedSize);
|
||||
gettimeofday(&tv, NULL);
|
||||
last = tv.tv_sec;
|
||||
bl = handle_one(*i, originSize, compressedSize);
|
||||
indicator.push_back(bl);
|
||||
gettimeofday(&tv,NULL);
|
||||
deltaTime.push_back(tv.tv_sec-last);
|
||||
gettimeofday(&tv, NULL);
|
||||
deltaTime.push_back(tv.tv_sec - last);
|
||||
}
|
||||
cout<<"\nDealt file number "<<originSize.size()<<fixed<<setprecision(2)<<endl;
|
||||
vector<string>::iterator p=max_element(names.begin(),names.end(),lenStr);
|
||||
int len = p->size()+2;
|
||||
for(int i =0;i<names.size();++i){
|
||||
if(! indicator[i]){continue;}
|
||||
cout<<names[i]<<string(len-names[i].size(),' ');
|
||||
cout<<deltaTime[i]<<"s "<<compressedSize[i]/1024.0<<"KB/"<<originSize[i]/1024.0<<"KB :";
|
||||
cout<<compressedSize[i]*100.0/originSize[i]<<"%"<<endl;
|
||||
|
||||
cout << "\nDealt file number " << originSize.size() << fixed << setprecision(2) << endl;
|
||||
vector<string>::iterator p = max_element(names.begin(), names.end(), lenStr);
|
||||
int len = p->size() + 2;
|
||||
|
||||
for (int i = 0; i < names.size(); ++i) {
|
||||
if (! indicator[i]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
cout << names[i] << string(len - names[i].size(), ' ');
|
||||
cout << deltaTime[i] << "s " << compressedSize[i] / 1024.0 << "KB/" << originSize[i] / 1024.0 << "KB :";
|
||||
cout << compressedSize[i] * 100.0 / originSize[i] << "%" << endl;
|
||||
}
|
||||
cout<<endl;
|
||||
|
||||
cout << endl;
|
||||
system("pause");
|
||||
}
|
||||
int main(int argv,char ** argc)
|
||||
int main(int argv, char ** argc)
|
||||
{
|
||||
char cwd[50];
|
||||
cout<<getcwd(cwd,50)<<endl;
|
||||
cout << getcwd(cwd, 50) << endl;
|
||||
vector<string> names;
|
||||
string file;
|
||||
if(argv>1){
|
||||
for(int i=1;i<argv;++i){
|
||||
string file;
|
||||
|
||||
if (argv > 1) {
|
||||
for (int i = 1; i < argv; ++i) {
|
||||
names.push_back(argc[i]);
|
||||
}
|
||||
|
||||
go(names);
|
||||
names.clear();
|
||||
}
|
||||
|
||||
char mk;
|
||||
while(1){
|
||||
|
||||
while (1) {
|
||||
char s[201];
|
||||
cout<<"Input file names separated by space "<<endl;
|
||||
if(cin.peek()=='\n')names.push_back(file);
|
||||
cout << "Input file names separated by space " << endl;
|
||||
|
||||
if (cin.peek() == '\n')names.push_back(file);
|
||||
else {
|
||||
cin.getline(s,200);
|
||||
splitToVec(s,names);
|
||||
cin.getline(s, 200);
|
||||
splitToVec(s, names);
|
||||
}
|
||||
cout<<endl;
|
||||
|
||||
cout << endl;
|
||||
go(names);
|
||||
cout<<"Continue? [Y/n]:"<<flush;
|
||||
mk= cin.get();
|
||||
if(mk=='n')break;
|
||||
cout << "Continue? [Y/n]:" << flush;
|
||||
mk = cin.get();
|
||||
|
||||
if (mk == 'n')break;
|
||||
|
||||
names.clear();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -13,11 +13,12 @@
|
|||
#######################################################################
|
||||
'''
|
||||
|
||||
|
||||
class RandomizedCollection:
|
||||
def __init__(self):
|
||||
|
||||
self.vals=[]
|
||||
self.index={}
|
||||
self.vals = []
|
||||
self.index = {}
|
||||
|
||||
def insert(self, val: int) -> bool:
|
||||
self.vals.append(val)
|
||||
|
@ -27,32 +28,35 @@ class RandomizedCollection:
|
|||
else:
|
||||
self.index[val] = {len(self.vals)-1}
|
||||
return True
|
||||
|
||||
def removeAll(self, val: int) -> bool:
|
||||
if val not in self.index:
|
||||
return False
|
||||
begin = end = len(self.vals)-len(self.index[val])
|
||||
for idx in self.index.pop(val):
|
||||
if idx<begin:
|
||||
while self.vals[end]==val:
|
||||
end+=1
|
||||
self.vals[idx]=self.vals[end]
|
||||
for idx in self.index.pop(val):
|
||||
if idx < begin:
|
||||
while self.vals[end] == val:
|
||||
end += 1
|
||||
self.vals[idx] = self.vals[end]
|
||||
self.index[self.vals[idx]].remove(end)
|
||||
self.index[self.vals[idx]].add(idx)
|
||||
self.vals = self.vals[:begin]
|
||||
return True
|
||||
def remove(self,val):
|
||||
|
||||
def remove(self, val):
|
||||
if val not in self.index:
|
||||
return False
|
||||
last = len(self.vals)-1
|
||||
idx = self.index[val].pop()
|
||||
if len(self.index[val])==0:
|
||||
if len(self.index[val]) == 0:
|
||||
del self.index[val]
|
||||
if idx!=last:
|
||||
if idx != last:
|
||||
self.vals[idx] = self.vals[last]
|
||||
self.index[self.vals[idx]].remove(last)
|
||||
self.index[self.vals[idx]].add(idx)
|
||||
self.vals.pop()
|
||||
return True
|
||||
|
||||
def getRandom(self) -> int:
|
||||
if self.vals:
|
||||
return self.vals[random.randint(0,len(self.vals)-1)]
|
||||
return self.vals[random.randint(0, len(self.vals)-1)]
|
||||
|
|
|
@ -9,60 +9,80 @@
|
|||
# Description:
|
||||
#########################################################################
|
||||
'''
|
||||
from random import randint, shuffle
|
||||
from redBlackTree import redBlackTree
|
||||
|
||||
from functools import total_ordering
|
||||
|
||||
|
||||
@total_ordering
|
||||
class node:
|
||||
def __init__(self,low,high,left=None,right=None,isBlack=False):
|
||||
self.val = low # self.val is the low
|
||||
def __init__(self, low, high, left=None, right=None, isBlack=False):
|
||||
self.val = low # self.val is the low
|
||||
self.high = high
|
||||
self.max = high
|
||||
self.left = left
|
||||
self.right = right
|
||||
self.parent=None
|
||||
self.parent = None
|
||||
self.isBlack = isBlack
|
||||
def __lt__(self,nd):
|
||||
|
||||
def __lt__(self, nd):
|
||||
return self.val < nd.val
|
||||
def __eq__(self,nd):
|
||||
|
||||
def __eq__(self, nd):
|
||||
return nd is not None and self.val == nd.val
|
||||
def setChild(self,nd,isLeft = True):
|
||||
if isLeft: self.left = nd
|
||||
else: self.right = nd
|
||||
if nd is not None: nd.parent = self
|
||||
def getChild(self,isLeft):
|
||||
if isLeft: return self.left
|
||||
else: return self.right
|
||||
|
||||
def setChild(self, nd, isLeft=True):
|
||||
if isLeft:
|
||||
self.left = nd
|
||||
else:
|
||||
self.right = nd
|
||||
if nd is not None:
|
||||
nd.parent = self
|
||||
|
||||
def getChild(self, isLeft):
|
||||
if isLeft:
|
||||
return self.left
|
||||
else:
|
||||
return self.right
|
||||
|
||||
def __bool__(self):
|
||||
return self.val is not None
|
||||
|
||||
def __str__(self):
|
||||
color = 'B' if self.isBlack else 'R'
|
||||
return f'{color}[{self.val},{self.high}]-{self.max}'
|
||||
|
||||
def __repr__(self):
|
||||
return f'intervalNode({self.val},{self.high},{self.max},isBlack={self.isBlack})'
|
||||
def overlap(self,low,high):
|
||||
return self.val<=high and self.high>=low
|
||||
|
||||
def overlap(self, low, high):
|
||||
return self.val <= high and self.high >= low
|
||||
|
||||
def setMax(self):
|
||||
l = 0 if self.left is None else self.left.max
|
||||
r = 0 if self.right is None else self.right.max
|
||||
self.max = max(self.high, l, r)
|
||||
return self.max
|
||||
|
||||
|
||||
class intervalTree(redBlackTree):
|
||||
def search(self,low,high):
|
||||
def search(self, low, high):
|
||||
nd = self.root
|
||||
while nd is not None and not nd.overlap(low,high):
|
||||
if nd.left is not None and nd.left.max>=low:
|
||||
while nd is not None and not nd.overlap(low, high):
|
||||
if nd.left is not None and nd.left.max >= low:
|
||||
nd = nd.left
|
||||
else:nd = nd.right
|
||||
else:
|
||||
nd = nd.right
|
||||
return nd
|
||||
def insert(self,nd):
|
||||
super(intervalTree,self).insert(nd)
|
||||
|
||||
def insert(self, nd):
|
||||
super(intervalTree, self).insert(nd)
|
||||
while nd is not None:
|
||||
nd.setMax()
|
||||
nd = nd.parent
|
||||
def delete(self,val):
|
||||
|
||||
def delete(self, val):
|
||||
nd = self.find(val)
|
||||
if nd is not None:
|
||||
nd.max = 0
|
||||
|
@ -70,56 +90,61 @@ class intervalTree(redBlackTree):
|
|||
while tmp is not None:
|
||||
tmp.setMax()
|
||||
tmp = tmp.parent
|
||||
super(intervalTree,self).delete(val)
|
||||
def rotate(self,prt,chd):
|
||||
super(intervalTree, self).delete(val)
|
||||
|
||||
def rotate(self, prt, chd):
|
||||
'''rotate prt, and return new prt, namyly the original chd'''
|
||||
super(intervalTree,self).rotate(prt,chd)
|
||||
super(intervalTree, self).rotate(prt, chd)
|
||||
prt.setMax()
|
||||
chd.setMax()
|
||||
def copyNode(self,src,des):
|
||||
|
||||
def copyNode(self, src, des):
|
||||
des.val = src.val
|
||||
des.high = src.high
|
||||
des.setMax()
|
||||
|
||||
|
||||
|
||||
from random import randint, shuffle
|
||||
def genNum(n =10,upper=10):
|
||||
nums ={}
|
||||
def genNum(n=10, upper=10):
|
||||
nums = {}
|
||||
for i in range(n):
|
||||
while 1:
|
||||
d = randint(0,100)
|
||||
d = randint(0, 100)
|
||||
if d not in nums:
|
||||
nums[d] = (d,randint(d,d+upper))
|
||||
nums[d] = (d, randint(d, d+upper))
|
||||
break
|
||||
return nums.values()
|
||||
|
||||
def buildTree(n=10,nums=None,visitor=None):
|
||||
|
||||
def buildTree(n=10, nums=None, visitor=None):
|
||||
#if nums is None or nums ==[]: nums = genNum(n)
|
||||
tree = intervalTree()
|
||||
print(f'build a red-black tree using {nums}')
|
||||
for i in nums:
|
||||
tree.insert(node(*i))
|
||||
if visitor:
|
||||
visitor(tree,i)
|
||||
return tree,nums
|
||||
visitor(tree, i)
|
||||
return tree, nums
|
||||
|
||||
|
||||
def testInsert(nums=None):
|
||||
def visitor(t,val):
|
||||
def visitor(t, val):
|
||||
print('inserting', val)
|
||||
print(t)
|
||||
tree,nums = buildTree(visitor = visitor,nums=nums)
|
||||
print('-'*5+ 'in-order visit' + '-'*5)
|
||||
for i,j in enumerate(tree.sort()):
|
||||
tree, nums = buildTree(visitor=visitor, nums=nums)
|
||||
print('-'*5 + 'in-order visit' + '-'*5)
|
||||
for i, j in enumerate(tree.sort()):
|
||||
print(f'{i+1}: {j}')
|
||||
return tree
|
||||
|
||||
|
||||
def testSuc(nums=None):
|
||||
tree,nums = buildTree(nums=nums)
|
||||
tree, nums = buildTree(nums=nums)
|
||||
for i in tree.sort():
|
||||
print(f'{i}\'s suc is {tree.getSuccessor(i)}')
|
||||
|
||||
|
||||
def testDelete(nums=None):
|
||||
tree,nums = buildTree(nums = nums)
|
||||
tree, nums = buildTree(nums=nums)
|
||||
print(tree)
|
||||
for i in nums:
|
||||
print(f'deleting {i}')
|
||||
|
@ -127,14 +152,16 @@ def testDelete(nums=None):
|
|||
print(tree)
|
||||
return tree
|
||||
|
||||
if __name__=='__main__':
|
||||
lst = [(0,3),(5,8),(6,10),(26,26),(25,30),(8,9),(19,20),(15,23),(16,21),(17,19)]
|
||||
|
||||
if __name__ == '__main__':
|
||||
lst = [(0, 3), (5, 8), (6, 10), (26, 26), (25, 30),
|
||||
(8, 9), (19, 20), (15, 23), (16, 21), (17, 19)]
|
||||
#lst = None
|
||||
#testSuc(lst)
|
||||
# testSuc(lst)
|
||||
tree = testInsert(lst)
|
||||
#tree,_= buildTree(lst)
|
||||
while 1:
|
||||
a =int( input('low:'))
|
||||
b =int( input('high:'))
|
||||
res = tree.search(a,b)
|
||||
a = int(input('low:'))
|
||||
b = int(input('high:'))
|
||||
res = tree.search(a, b)
|
||||
print(res)
|
||||
|
|
|
@ -11,108 +11,137 @@
|
|||
'''
|
||||
|
||||
from functools import total_ordering
|
||||
@total_ordering
|
||||
|
||||
|
||||
@total_ordering
|
||||
class node:
|
||||
def __init__(self,val,freq=1,s=1,left=None,right=None):
|
||||
self.val=val
|
||||
self.freq=freq
|
||||
self.s=s
|
||||
def __init__(self, val, freq=1, s=1, left=None, right=None):
|
||||
self.val = val
|
||||
self.freq = freq
|
||||
self.s = s
|
||||
if left is None or right is None:
|
||||
self.left = left if left is not None else right
|
||||
self.right =None
|
||||
self.right = None
|
||||
else:
|
||||
if left.s<right.s:
|
||||
left,right =right, left
|
||||
self.left=left
|
||||
self.right=right
|
||||
self.s+=self.right.s
|
||||
def __eq__(self,nd):
|
||||
return self.val==nd.val
|
||||
def __lt__(self,nd):
|
||||
return self.val<nd.val
|
||||
if left.s < right.s:
|
||||
left, right = right, left
|
||||
self.left = left
|
||||
self.right = right
|
||||
self.s += self.right.s
|
||||
|
||||
def __eq__(self, nd):
|
||||
return self.val == nd.val
|
||||
|
||||
def __lt__(self, nd):
|
||||
return self.val < nd.val
|
||||
|
||||
def __repr__(self):
|
||||
return 'node(val=%d,freq=%d,s=%d)'%(self.val,self.freq,self.s)
|
||||
return 'node(val=%d,freq=%d,s=%d)' % (self.val, self.freq, self.s)
|
||||
|
||||
|
||||
class leftHeap:
|
||||
def __init__(self,root=None):
|
||||
self.root=root
|
||||
def __init__(self, root=None):
|
||||
self.root = root
|
||||
|
||||
def __bool__(self):
|
||||
return self.root is not None
|
||||
|
||||
@staticmethod
|
||||
def _merge(root,t): #-> int
|
||||
if root is None:return t
|
||||
if t is None:return root
|
||||
if root<t:
|
||||
root,t=t,root
|
||||
root.right = leftHeap._merge(root.right,t)
|
||||
def _merge(root, t): # -> int
|
||||
if root is None:
|
||||
return t
|
||||
if t is None:
|
||||
return root
|
||||
if root < t:
|
||||
root, t = t, root
|
||||
root.right = leftHeap._merge(root.right, t)
|
||||
if root.left is None or root.right is None:
|
||||
root.s=1
|
||||
root.s = 1
|
||||
if root.left is None:
|
||||
root.left,root.right = root.right,None
|
||||
root.left, root.right = root.right, None
|
||||
else:
|
||||
if root.left.s<root.right.s:
|
||||
root.left,root.right = root.right,root.left
|
||||
if root.left.s < root.right.s:
|
||||
root.left, root.right = root.right, root.left
|
||||
root.s = root.right.s+1
|
||||
return root
|
||||
def insert(self,nd):
|
||||
if not isinstance(nd,node):nd = node(nd)
|
||||
|
||||
def insert(self, nd):
|
||||
if not isinstance(nd, node):
|
||||
nd = node(nd)
|
||||
if self.root is None:
|
||||
self.root=nd
|
||||
self.root = nd
|
||||
return
|
||||
if self.root==nd:
|
||||
self.root.freq+=1
|
||||
if self.root == nd:
|
||||
self.root.freq += 1
|
||||
return
|
||||
prt =self. _findPrt(self.root,nd,None)
|
||||
prt = self. _findPrt(self.root, nd, None)
|
||||
if prt is None:
|
||||
self.root=leftHeap._merge(self.root,nd)
|
||||
else :
|
||||
if prt.left==nd:
|
||||
prt.left.freq+=1
|
||||
else:prt.right.freq+=1
|
||||
def remove(self,nd):
|
||||
if not isinstance(nd,node):nd = node(nd)
|
||||
if self.root==nd:
|
||||
self.root=leftHeap._merge(self.root.left,self.root.right)
|
||||
self.root = leftHeap._merge(self.root, nd)
|
||||
else:
|
||||
prt = self._findPrt(self.root,nd,None)
|
||||
if prt.left == nd:
|
||||
prt.left.freq += 1
|
||||
else:
|
||||
prt.right.freq += 1
|
||||
|
||||
def remove(self, nd):
|
||||
if not isinstance(nd, node):
|
||||
nd = node(nd)
|
||||
if self.root == nd:
|
||||
self.root = leftHeap._merge(self.root.left, self.root.right)
|
||||
else:
|
||||
prt = self._findPrt(self.root, nd, None)
|
||||
if prt is not None:
|
||||
if prt.left==nd:
|
||||
prt.left=leftHeap._merge(prt.left.left,prt.left.right)
|
||||
if prt.left == nd:
|
||||
prt.left = leftHeap._merge(prt.left.left, prt.left.right)
|
||||
else:
|
||||
prt.right=leftHeap._merge(prt.right.left,prt.right.right)
|
||||
def find(self,nd):
|
||||
if not isinstance(nd,node):nd = node(nd)
|
||||
prt = self._findPrt(self.root,nd,self.root)
|
||||
if prt is None or prt==nd:return prt
|
||||
elif prt.left==nd:return prt.left
|
||||
else:return prt.right
|
||||
def _findPrt(self,root,nd,parent):
|
||||
if not isinstance(nd,node):nd = node(nd)
|
||||
if root is None or root<nd:return None
|
||||
if root==nd:return parent
|
||||
l=self._findPrt(root.left,nd,root)
|
||||
return l if l is not None else self._findPrt(root.right,nd,root)
|
||||
prt.right = leftHeap._merge(
|
||||
prt.right.left, prt.right.right)
|
||||
|
||||
def find(self, nd):
|
||||
if not isinstance(nd, node):
|
||||
nd = node(nd)
|
||||
prt = self._findPrt(self.root, nd, self.root)
|
||||
if prt is None or prt == nd:
|
||||
return prt
|
||||
elif prt.left == nd:
|
||||
return prt.left
|
||||
else:
|
||||
return prt.right
|
||||
|
||||
def _findPrt(self, root, nd, parent):
|
||||
if not isinstance(nd, node):
|
||||
nd = node(nd)
|
||||
if root is None or root < nd:
|
||||
return None
|
||||
if root == nd:
|
||||
return parent
|
||||
l = self._findPrt(root.left, nd, root)
|
||||
return l if l is not None else self._findPrt(root.right, nd, root)
|
||||
|
||||
def getTop(self):
|
||||
return self.root
|
||||
|
||||
def pop(self):
|
||||
nd = self.root
|
||||
self.remove(self.root.val)
|
||||
return nd
|
||||
|
||||
def levelTraverse(self):
|
||||
li = [(self.root,0)]
|
||||
cur=0
|
||||
li = [(self.root, 0)]
|
||||
cur = 0
|
||||
while li:
|
||||
nd,lv = li.pop(0)
|
||||
if cur<lv:
|
||||
cur=lv
|
||||
nd, lv = li.pop(0)
|
||||
if cur < lv:
|
||||
cur = lv
|
||||
print()
|
||||
print(nd,end=' ')
|
||||
else:print(nd,end=' ')
|
||||
if nd.left is not None:li.append((nd.left,lv+1))
|
||||
if nd.right is not None:li.append((nd.right,lv+1))
|
||||
|
||||
|
||||
print(nd, end=' ')
|
||||
else:
|
||||
print(nd, end=' ')
|
||||
if nd.left is not None:
|
||||
li.append((nd.left, lv+1))
|
||||
if nd.right is not None:
|
||||
li.append((nd.right, lv+1))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
lh = leftHeap()
|
||||
|
@ -123,7 +152,8 @@ if __name__ == '__main__':
|
|||
print()
|
||||
for i in data:
|
||||
print(lh.getTop())
|
||||
if lh.find(i) is not None:lh.remove(i)
|
||||
if lh.find(i) is not None:
|
||||
lh.remove(i)
|
||||
'''
|
||||
data = [(i-10)**2 for i in range(20)]
|
||||
node(100,freq=1,s=3)
|
||||
|
|
|
@ -9,17 +9,21 @@
|
|||
# Description:
|
||||
#########################################################################
|
||||
'''
|
||||
|
||||
|
||||
class node:
|
||||
def __init__(self,val,follow=None):
|
||||
def __init__(self, val, follow=None):
|
||||
self.val = val
|
||||
self.follow = follow
|
||||
|
||||
|
||||
class MyLinkedList:
|
||||
|
||||
def __init__(self):
|
||||
"""
|
||||
Initialize your data structure here.
|
||||
"""
|
||||
|
||||
|
||||
self.tail = self.head = node(None)
|
||||
|
||||
def get(self, index):
|
||||
|
@ -31,7 +35,8 @@ class MyLinkedList:
|
|||
nd = self.head
|
||||
for i in range(index+1):
|
||||
nd = nd.follow
|
||||
if nd is None:return -1
|
||||
if nd is None:
|
||||
return -1
|
||||
return nd.val
|
||||
|
||||
def addAtHead(self, val):
|
||||
|
@ -40,9 +45,11 @@ class MyLinkedList:
|
|||
:type val: int
|
||||
:rtype: void
|
||||
"""
|
||||
nd = node(val,self.head.follow)
|
||||
nd = node(val, self.head.follow)
|
||||
self.head .follow = nd
|
||||
if self.tail.val is None:self.tail = nd
|
||||
if self.tail.val is None:
|
||||
self.tail = nd
|
||||
|
||||
def addAtTail(self, val):
|
||||
"""
|
||||
Append a node of value val to the last element of the linked list.
|
||||
|
@ -51,7 +58,6 @@ class MyLinkedList:
|
|||
"""
|
||||
self.tail.follow = node(val)
|
||||
self.tail = self.tail.follow
|
||||
|
||||
|
||||
def addAtIndex(self, index, val):
|
||||
"""
|
||||
|
@ -65,11 +71,10 @@ class MyLinkedList:
|
|||
nd = nd.follow
|
||||
if nd is None:
|
||||
return
|
||||
new = node(val,nd.follow)
|
||||
new = node(val, nd.follow)
|
||||
nd.follow = new
|
||||
if self.tail == nd:
|
||||
self.tail = new
|
||||
|
||||
|
||||
def deleteAtIndex(self, index):
|
||||
"""
|
||||
|
@ -80,10 +85,12 @@ class MyLinkedList:
|
|||
nd = self.head
|
||||
for i in range(index):
|
||||
nd = nd.follow
|
||||
if nd is None:return
|
||||
if self.tail == nd.follow:self.tail = nd
|
||||
if nd.follow:nd.follow = nd.follow.follow
|
||||
|
||||
if nd is None:
|
||||
return
|
||||
if self.tail == nd.follow:
|
||||
self.tail = nd
|
||||
if nd.follow:
|
||||
nd.follow = nd.follow.follow
|
||||
|
||||
|
||||
# Your MyLinkedList object will be instantiated and called as such:
|
||||
|
|
|
@ -13,138 +13,158 @@
|
|||
#include<stdio.h>
|
||||
bool isZero(float a)
|
||||
{
|
||||
return a<0.00001&&-a<0.00001;
|
||||
return a < 0.00001 && -a < 0.00001;
|
||||
}
|
||||
template<class,class> class map;
|
||||
//notice that if you declare a class template,declare the class first like this.
|
||||
template<class t1,class t2>
|
||||
template<class, class> class map;
|
||||
//notice that if you declare a class template,declare the class first like this.
|
||||
template<class t1, class t2>
|
||||
class pair
|
||||
{
|
||||
friend class map<t1,t2>;
|
||||
pair<t1,t2> *next;
|
||||
public:
|
||||
friend class map<t1, t2>;
|
||||
pair<t1, t2> *next;
|
||||
public:
|
||||
t1 first;
|
||||
t2 second;
|
||||
|
||||
};
|
||||
template<class t1,class t2>
|
||||
template<class t1, class t2>
|
||||
class map
|
||||
{
|
||||
int n;
|
||||
pair<t1,t2> head;
|
||||
pair<t1, t2> head;
|
||||
int cur;
|
||||
pair<t1,t2> *last_visit;
|
||||
public:
|
||||
pair<t1, t2> *last_visit;
|
||||
public:
|
||||
map();
|
||||
~map();
|
||||
bool has(t1);
|
||||
void erase(t1);
|
||||
t2& operator[](t1);
|
||||
pair<t1,t2> &locate(int index = -1);
|
||||
pair<t1, t2> &locate(int index = -1);
|
||||
int size();
|
||||
};
|
||||
template<class t1,class t2>
|
||||
map<t1,t2>::map(){
|
||||
n=0;
|
||||
cur=-1;
|
||||
last_visit= &head;
|
||||
head.next=NULL;
|
||||
template<class t1, class t2>
|
||||
map<t1, t2>::map()
|
||||
{
|
||||
n = 0;
|
||||
cur = -1;
|
||||
last_visit = &head;
|
||||
head.next = NULL;
|
||||
head.first = head.second = 0;
|
||||
}
|
||||
template<class t1,class t2>
|
||||
map<t1,t2>::~map()
|
||||
template<class t1, class t2>
|
||||
map<t1, t2>::~map()
|
||||
{
|
||||
pair<t1,t2> *p,*q=&head;
|
||||
while(q!=NULL){
|
||||
p=q->next;
|
||||
pair<t1, t2> *p, *q = &head;
|
||||
|
||||
while (q != NULL) {
|
||||
p = q->next;
|
||||
delete q;
|
||||
q=p;
|
||||
q = p;
|
||||
}
|
||||
}
|
||||
template<class t1,class t2>
|
||||
bool map<t1,t2>::has(t1 key)
|
||||
template<class t1, class t2>
|
||||
bool map<t1, t2>::has(t1 key)
|
||||
{
|
||||
pair<t1,t2> *p = head.next;
|
||||
for(int i = 0;i<n&&p->first<=key;++i){
|
||||
if(isZero(p->first-key)) return 1;
|
||||
p=p->next;
|
||||
pair<t1, t2> *p = head.next;
|
||||
|
||||
for (int i = 0; i < n && p->first <= key; ++i) {
|
||||
if (isZero(p->first - key)) return 1;
|
||||
|
||||
p = p->next;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
template<class t1,class t2>
|
||||
pair<t1,t2>& map<t1,t2>::locate(int index)
|
||||
template<class t1, class t2>
|
||||
pair<t1, t2>& map<t1, t2>::locate(int index)
|
||||
{
|
||||
if(index>=n||index<0){
|
||||
if (index >= n || index < 0) {
|
||||
printf("the index is out of range\n");
|
||||
return head;
|
||||
}
|
||||
if(cur>index){
|
||||
|
||||
if (cur > index) {
|
||||
last_visit = &head;
|
||||
cur = -1;
|
||||
}
|
||||
while(cur<index){
|
||||
|
||||
while (cur < index) {
|
||||
last_visit = last_visit->next;
|
||||
++cur;
|
||||
}
|
||||
|
||||
return *last_visit;
|
||||
}
|
||||
template<class t1,class t2>
|
||||
int map<t1,t2>::size()
|
||||
template<class t1, class t2>
|
||||
int map<t1, t2>::size()
|
||||
{
|
||||
return n;
|
||||
}
|
||||
template<class t1,class t2>
|
||||
t2& map<t1,t2>::operator[](t1 key)
|
||||
template<class t1, class t2>
|
||||
t2& map<t1, t2>::operator[](t1 key)
|
||||
{
|
||||
pair<t1,t2> * p=&head;
|
||||
while(p->next!=NULL){
|
||||
if(isZero(p->next->first-key)) return p->next->second;
|
||||
else if(p->next->first>key){break;}
|
||||
p=p->next;
|
||||
pair<t1, t2> * p = &head;
|
||||
|
||||
while (p->next != NULL) {
|
||||
if (isZero(p->next->first - key)) return p->next->second;
|
||||
else if (p->next->first > key) {
|
||||
break;
|
||||
}
|
||||
|
||||
p = p->next;
|
||||
}
|
||||
cur=-1;
|
||||
last_visit= &head;
|
||||
pair<t1,t2> *tmp = new pair<t1,t2>;
|
||||
|
||||
cur = -1;
|
||||
last_visit = &head;
|
||||
pair<t1, t2> *tmp = new pair<t1, t2>;
|
||||
tmp ->next = p->next;
|
||||
tmp->first = key;
|
||||
p->next = tmp;
|
||||
++n;
|
||||
return tmp->second;
|
||||
}
|
||||
template<class t1,class t2>
|
||||
void map<t1,t2>::erase(t1 key)
|
||||
template<class t1, class t2>
|
||||
void map<t1, t2>::erase(t1 key)
|
||||
{
|
||||
pair<t1,t2> *p = &head;
|
||||
while(p->next!=NULL){
|
||||
if(isZero(p->next->first-key)){
|
||||
pair<t1,t2> *q = p->next;
|
||||
pair<t1, t2> *p = &head;
|
||||
|
||||
while (p->next != NULL) {
|
||||
if (isZero(p->next->first - key)) {
|
||||
pair<t1, t2> *q = p->next;
|
||||
p->next = p->next->next;
|
||||
delete q;
|
||||
--n;
|
||||
break;
|
||||
}
|
||||
p=p->next;
|
||||
|
||||
p = p->next;
|
||||
}
|
||||
cur=-1;
|
||||
last_visit= &head;
|
||||
|
||||
cur = -1;
|
||||
last_visit = &head;
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
map<double,float> b;
|
||||
for(int i = 0;i<40;++i){
|
||||
map<double, float> b;
|
||||
|
||||
for (int i = 0; i < 40; ++i) {
|
||||
b[i] = i;
|
||||
if(i%3){
|
||||
|
||||
if (i % 3) {
|
||||
b[i] = 1;
|
||||
}
|
||||
if(i%2){
|
||||
|
||||
if (i % 2) {
|
||||
b.erase(i);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < b.size(); ++i) {
|
||||
printf("item %d %g:%g\n", i, b.locate(i).first, b.locate(i).second);
|
||||
}
|
||||
for(int i = 0;i<b.size();++i){
|
||||
printf("item %d %g:%g\n",i,b.locate(i).first,b.locate(i).second);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
#########################################################################
|
||||
*/
|
||||
|
||||
#include<cstdlib>
|
||||
#include<cstdlib>
|
||||
#include<cstdio>
|
||||
#include<cstring>
|
||||
#include<cmath>
|
||||
|
@ -19,16 +19,17 @@
|
|||
using namespace std;
|
||||
|
||||
#if defined(__linux__)
|
||||
#define LINUX true
|
||||
#define LINUX true
|
||||
#elif defined(_WIN32)
|
||||
#define LINUX false
|
||||
#define LINUX false
|
||||
#endif
|
||||
|
||||
|
||||
bool isZero(double a)
|
||||
{
|
||||
if((a<0.00001)&&-a<0.00001)
|
||||
if ((a < 0.00001) && -a < 0.00001)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
class node
|
||||
|
@ -42,9 +43,9 @@ class polynomial
|
|||
int SIZE;
|
||||
int n;
|
||||
node* p;
|
||||
public:
|
||||
polynomial(int sz=50);
|
||||
polynomial(const polynomial & );
|
||||
public:
|
||||
polynomial(int sz = 50);
|
||||
polynomial(const polynomial &);
|
||||
~polynomial();
|
||||
double cal(double);
|
||||
void getData();
|
||||
|
@ -54,10 +55,10 @@ class polynomial
|
|||
polynomial operator-(const polynomial &);
|
||||
polynomial operator*(const polynomial &);
|
||||
};
|
||||
polynomial::polynomial(int sz):n(0),SIZE(sz)
|
||||
polynomial::polynomial(int sz): n(0), SIZE(sz)
|
||||
{
|
||||
p = (node*) new node[SIZE];
|
||||
memset(p,0,sizeof(p));
|
||||
memset(p, 0, sizeof(p));
|
||||
}
|
||||
polynomial::~polynomial()
|
||||
{
|
||||
|
@ -65,18 +66,21 @@ polynomial::~polynomial()
|
|||
}
|
||||
double polynomial::cal(double x)
|
||||
{
|
||||
double rst=0;
|
||||
for(int i =0;i<n;++i){
|
||||
rst += pow(x,p[i].index)*p[i].coefficient;
|
||||
double rst = 0;
|
||||
|
||||
for (int i = 0; i < n; ++i) {
|
||||
rst += pow(x, p[i].index) * p[i].coefficient;
|
||||
}
|
||||
|
||||
return rst;
|
||||
}
|
||||
polynomial::polynomial(const polynomial &a)
|
||||
{
|
||||
p = (node*) new node[50];
|
||||
memset(p,0,sizeof(p));
|
||||
memset(p, 0, sizeof(p));
|
||||
n = a.n;
|
||||
for(int i = 0;i<a.n;++i){
|
||||
|
||||
for (int i = 0; i < a.n; ++i) {
|
||||
p[i].index = a.p[i].index;
|
||||
p[i].coefficient = a.p[i].coefficient;
|
||||
}
|
||||
|
@ -84,59 +88,72 @@ polynomial::polynomial(const polynomial &a)
|
|||
polynomial polynomial::operator=(const polynomial& a)
|
||||
{
|
||||
n = a.n;
|
||||
for(int i = 0;i<a.n;++i){
|
||||
|
||||
for (int i = 0; i < a.n; ++i) {
|
||||
p[i].index = a.p[i].index;
|
||||
p[i].coefficient = a.p[i].coefficient;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
void polynomial::display()
|
||||
{
|
||||
node * tmp = p;
|
||||
if(n == 0){
|
||||
|
||||
if (n == 0) {
|
||||
printf("0\n");
|
||||
return;
|
||||
}
|
||||
// char *fmt = ("x"); printf(fmt,...);
|
||||
for(int i = n-1;i>=0;--i){
|
||||
|
||||
// char *fmt = ("x"); printf(fmt,...);
|
||||
for (int i = n - 1; i >= 0; --i) {
|
||||
double t = tmp[i].coefficient;
|
||||
double idx = tmp[i].index;
|
||||
if(isZero(idx)){
|
||||
printf("%+g",t);
|
||||
|
||||
if (isZero(idx)) {
|
||||
printf("%+g", t);
|
||||
continue;
|
||||
}
|
||||
if(isZero(t-1)) printf("+");
|
||||
else if(isZero(t+1))printf("-");
|
||||
else printf("%+g",t);
|
||||
|
||||
if (isZero(t - 1)) printf("+");
|
||||
else if (isZero(t + 1))printf("-");
|
||||
else printf("%+g", t);
|
||||
|
||||
printf("x");
|
||||
if(!isZero(idx-1)) printf("^%g",idx);
|
||||
|
||||
if (!isZero(idx - 1)) printf("^%g", idx);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
void polynomial::getData()
|
||||
{
|
||||
printf("Please input data . \n");
|
||||
printf("For every item,Coefficient first .Use space to separate,EOF to end\n");
|
||||
map<double,double> mp;
|
||||
map<double, double> mp;
|
||||
double idx;
|
||||
double coef;
|
||||
while(scanf("%lf%lf",&coef,&idx)!=EOF){
|
||||
if(isZero(coef)) continue;
|
||||
if(mp.count(idx) == 0){
|
||||
|
||||
while (scanf("%lf%lf", &coef, &idx) != EOF) {
|
||||
if (isZero(coef)) continue;
|
||||
|
||||
if (mp.count(idx) == 0) {
|
||||
mp[idx] = coef;
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
mp[idx] += coef;
|
||||
if(isZero(mp[idx])){
|
||||
|
||||
if (isZero(mp[idx])) {
|
||||
mp.erase(idx);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(mp.size()>SIZE){
|
||||
SIZE *=2;
|
||||
p = (node*)realloc(p,sizeof(node)*SIZE) ;
|
||||
|
||||
if (mp.size() > SIZE) {
|
||||
SIZE *= 2;
|
||||
p = (node*)realloc(p, sizeof(node) * SIZE) ;
|
||||
}
|
||||
for(map<double,double>::iterator it = mp.begin();it!=mp.end();++it){
|
||||
|
||||
for (map<double, double>::iterator it = mp.begin(); it != mp.end(); ++it) {
|
||||
p[n].index = it->first;
|
||||
p[n++].coefficient = it->second;
|
||||
}
|
||||
|
@ -144,48 +161,52 @@ void polynomial::getData()
|
|||
polynomial polynomial::operator+(const polynomial & a)
|
||||
{
|
||||
polynomial rst ;
|
||||
int p1 = 0,p2 = 0,p3 = 0;
|
||||
int p1 = 0, p2 = 0, p3 = 0;
|
||||
double exp1 = p[p1].index;
|
||||
double exp2 = a.p[p2].index;
|
||||
while(p1<n && p2<a.n){
|
||||
while(p1<n &&exp1<exp2){
|
||||
rst.p[p3].index = exp1;
|
||||
rst.p[p3].coefficient = p[p1].coefficient;
|
||||
++p1,++p3;
|
||||
exp1 = p[p1].index;;
|
||||
|
||||
while (p1 < n && p2 < a.n) {
|
||||
while (p1 < n && exp1 < exp2) {
|
||||
rst.p[p3].index = exp1;
|
||||
rst.p[p3].coefficient = p[p1].coefficient;
|
||||
++p1, ++p3;
|
||||
exp1 = p[p1].index;;
|
||||
}
|
||||
while(p2<a.n &&exp1>exp2){
|
||||
rst.p[p3].index = exp2;
|
||||
rst.p[p3].coefficient = a.p[p2].coefficient;
|
||||
++p2,++p3;
|
||||
exp2 = a.p[p2].index;;
|
||||
|
||||
while (p2 < a.n && exp1 > exp2) {
|
||||
rst.p[p3].index = exp2;
|
||||
rst.p[p3].coefficient = a.p[p2].coefficient;
|
||||
++p2, ++p3;
|
||||
exp2 = a.p[p2].index;;
|
||||
}
|
||||
if(isZero(exp1-exp2)){
|
||||
double tmp= p[p1].coefficient + a.p[p2].coefficient;
|
||||
if(isZero(tmp)){
|
||||
++p1,++p2;
|
||||
}
|
||||
else{
|
||||
|
||||
if (isZero(exp1 - exp2)) {
|
||||
double tmp = p[p1].coefficient + a.p[p2].coefficient;
|
||||
|
||||
if (isZero(tmp)) {
|
||||
++p1, ++p2;
|
||||
} else {
|
||||
rst.p[p3].index = p[p1].index;
|
||||
rst.p[p3].coefficient = tmp;
|
||||
++p1,++p2,++p3;
|
||||
++p1, ++p2, ++p3;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(p1 == n){
|
||||
while(p2<a.n){
|
||||
|
||||
if (p1 == n) {
|
||||
while (p2 < a.n) {
|
||||
rst.p[p3].index = a.p[p2].index;
|
||||
rst.p[p3].coefficient = a.p[p2].coefficient;
|
||||
++p2,++p3;
|
||||
++p2, ++p3;
|
||||
}
|
||||
}
|
||||
else{
|
||||
while(p1<n){
|
||||
} else {
|
||||
while (p1 < n) {
|
||||
rst.p[p3].index = p[p1].index;
|
||||
rst.p[p3].coefficient = p[p1].coefficient;
|
||||
++p1,++p3;
|
||||
++p1, ++p3;
|
||||
}
|
||||
}
|
||||
|
||||
rst.n = p3;
|
||||
return rst;
|
||||
}
|
||||
|
@ -193,40 +214,50 @@ polynomial polynomial::operator-(const polynomial & a)
|
|||
{
|
||||
polynomial rst(a) ;
|
||||
int i = 0;
|
||||
while(i<rst.n){
|
||||
|
||||
while (i < rst.n) {
|
||||
rst.p[i].coefficient = -rst.p[i].coefficient;
|
||||
++i;
|
||||
}
|
||||
|
||||
return (*this + rst);
|
||||
}
|
||||
polynomial polynomial::operator*(const polynomial & a)
|
||||
{
|
||||
map<double,double> mp;
|
||||
for(int i = 0;i<n;++i){
|
||||
map<double, double> mp;
|
||||
|
||||
for (int i = 0; i < n; ++i) {
|
||||
double idx = p[i].index;
|
||||
double coef = p[i].coefficient;
|
||||
for(int j = 0;j<a.n;++j){
|
||||
double index = idx+a.p[j].index;
|
||||
if(mp.count(index)==0){
|
||||
mp[index] = coef*a.p[j].coefficient;
|
||||
}
|
||||
else{
|
||||
mp[index] += coef*a.p[j].coefficient;
|
||||
if(isZero(mp[index])){
|
||||
|
||||
for (int j = 0; j < a.n; ++j) {
|
||||
double index = idx + a.p[j].index;
|
||||
|
||||
if (mp.count(index) == 0) {
|
||||
mp[index] = coef * a.p[j].coefficient;
|
||||
} else {
|
||||
mp[index] += coef * a.p[j].coefficient;
|
||||
|
||||
if (isZero(mp[index])) {
|
||||
mp.erase(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
int sz =50;
|
||||
while(mp.size()>sz){
|
||||
sz *=2;
|
||||
|
||||
int sz = 50;
|
||||
|
||||
while (mp.size() > sz) {
|
||||
sz *= 2;
|
||||
}
|
||||
|
||||
polynomial rst(sz);
|
||||
for(map<double,double>::iterator it = mp.begin();it!=mp.end();++it){
|
||||
|
||||
for (map<double, double>::iterator it = mp.begin(); it != mp.end(); ++it) {
|
||||
rst.p[rst.n].index = it->first;
|
||||
rst.p[rst.n++].coefficient = it->second;
|
||||
}
|
||||
|
||||
return rst;
|
||||
}
|
||||
int num = 0;
|
||||
|
@ -250,94 +281,94 @@ void menu()
|
|||
void loop()
|
||||
{
|
||||
int op;
|
||||
while(scanf("%d",&op)!=EOF){
|
||||
if(op == 0){
|
||||
pl[num].getData();
|
||||
++num;
|
||||
printf("You've created polynomial %d:\n",num);
|
||||
pl[num-1].display();
|
||||
|
||||
while (scanf("%d", &op) != EOF) {
|
||||
if (op == 0) {
|
||||
pl[num].getData();
|
||||
++num;
|
||||
printf("You've created polynomial %d:\n", num);
|
||||
pl[num - 1].display();
|
||||
} else if (op == 1 || op == 2 || op == 3) {
|
||||
if (num < 2) {
|
||||
printf("Oops! you've got less two polynomial\nPlease choose another operation\n");
|
||||
continue;
|
||||
}
|
||||
else if(op==1||op==2||op==3){
|
||||
if(num<2){
|
||||
printf("Oops! you've got less two polynomial\nPlease choose another operation\n");
|
||||
continue;
|
||||
}
|
||||
printf("input two nums of the two polynomial to be operated.eg: 1 2\n");
|
||||
int t1=100,t2=100;
|
||||
while(1){
|
||||
scanf("%d%d",&t1,&t2);
|
||||
if(t1>num||t2>num||t1<0||t2<0){
|
||||
printf("wrong num ,please input again\n");
|
||||
}
|
||||
else break;
|
||||
}
|
||||
printf("the rst is:\n");
|
||||
t1 -=1,t2-=1;
|
||||
if(op == 1){
|
||||
(pl[t1]+pl[t2]).display();
|
||||
}
|
||||
else if(op == 2){
|
||||
(pl[t1]-pl[t2]).display();
|
||||
}
|
||||
else (pl[t1]*pl[t2]).display();
|
||||
|
||||
printf("input two nums of the two polynomial to be operated.eg: 1 2\n");
|
||||
int t1 = 100, t2 = 100;
|
||||
|
||||
while (1) {
|
||||
scanf("%d%d", &t1, &t2);
|
||||
|
||||
if (t1 > num || t2 > num || t1 < 0 || t2 < 0) {
|
||||
printf("wrong num ,please input again\n");
|
||||
} else break;
|
||||
}
|
||||
else if(op == 4){
|
||||
printf("input a polynomial's num to display it\n");
|
||||
int tmp;
|
||||
scanf("%d",&tmp);
|
||||
if(tmp>num){
|
||||
printf("wrong num");
|
||||
}
|
||||
else{
|
||||
printf("info of polynomial %d\n",tmp);
|
||||
pl[tmp-1].display();
|
||||
}
|
||||
|
||||
printf("the rst is:\n");
|
||||
t1 -= 1, t2 -= 1;
|
||||
|
||||
if (op == 1) {
|
||||
(pl[t1] + pl[t2]).display();
|
||||
} else if (op == 2) {
|
||||
(pl[t1] - pl[t2]).display();
|
||||
} else (pl[t1]*pl[t2]).display();
|
||||
} else if (op == 4) {
|
||||
printf("input a polynomial's num to display it\n");
|
||||
int tmp;
|
||||
scanf("%d", &tmp);
|
||||
|
||||
if (tmp > num) {
|
||||
printf("wrong num");
|
||||
} else {
|
||||
printf("info of polynomial %d\n", tmp);
|
||||
pl[tmp - 1].display();
|
||||
}
|
||||
else if(op == 9){
|
||||
for(int i = 0;i<num;++i){
|
||||
printf("polynomial %d : ",i+1);
|
||||
pl[i].display();
|
||||
}
|
||||
} else if (op == 9) {
|
||||
for (int i = 0; i < num; ++i) {
|
||||
printf("polynomial %d : ", i + 1);
|
||||
pl[i].display();
|
||||
}
|
||||
else if(op == 5){
|
||||
menu();
|
||||
} else if (op == 5) {
|
||||
menu();
|
||||
} else if (op == 6) {
|
||||
if (LINUX) system("clear");
|
||||
else system("cls");
|
||||
|
||||
menu();
|
||||
} else if (op == 10) {
|
||||
double x;
|
||||
int t;
|
||||
printf("choose a polynomial\n");
|
||||
scanf("%d", &t);
|
||||
|
||||
if (t > num || t < 0) {
|
||||
printf("wrong num\n");
|
||||
} else {
|
||||
printf("input a value\n");
|
||||
scanf("%lf", &x);
|
||||
pl[t - 1].display();
|
||||
printf("%g\n", pl[t - 1].cal(x));
|
||||
}
|
||||
else if(op == 6){
|
||||
if(LINUX) system("clear");
|
||||
else system("cls");
|
||||
menu();
|
||||
} else if (op == 8) {
|
||||
if (num == 0) {
|
||||
printf("you have'nt any polynomial tp copy\n");
|
||||
continue;
|
||||
}
|
||||
else if(op == 10){
|
||||
double x;
|
||||
int t;
|
||||
printf("choose a polynomial\n");
|
||||
scanf("%d",&t);
|
||||
if(t>num||t<0){
|
||||
printf("wrong num\n");
|
||||
}
|
||||
else {
|
||||
printf("input a value\n");
|
||||
scanf("%lf",&x);
|
||||
pl[t-1].display();
|
||||
printf("%g\n",pl[t-1].cal(x));
|
||||
}
|
||||
|
||||
int n = num + 1;
|
||||
|
||||
while (n > num) {
|
||||
printf("input the number of an existing polynomial you want to copy\n");
|
||||
scanf("%d", &n);
|
||||
}
|
||||
else if(op == 8){
|
||||
if(num == 0){
|
||||
printf("you have'nt any polynomial tp copy\n");
|
||||
continue;
|
||||
}
|
||||
int n = num+1;
|
||||
while(n>num){
|
||||
printf("input the number of an existing polynomial you want to copy\n");
|
||||
scanf("%d",&n);
|
||||
}
|
||||
(pl[num] = pl[n-1]);
|
||||
printf("You've copyed this polynomial:\n");
|
||||
pl[num++].display();
|
||||
}
|
||||
else exit(0);
|
||||
printf("select an operation\n");
|
||||
|
||||
(pl[num] = pl[n - 1]);
|
||||
printf("You've copyed this polynomial:\n");
|
||||
pl[num++].display();
|
||||
} else exit(0);
|
||||
|
||||
printf("select an operation\n");
|
||||
}
|
||||
}
|
||||
int main(void)
|
||||
|
|
|
@ -11,61 +11,71 @@
|
|||
'''
|
||||
|
||||
#!/bin/python3
|
||||
# notice that creating a class's initialization won't conflict with __call__ method
|
||||
# notice that creating a class's initialization won't conflict with __call__ method
|
||||
# because the former call class ,and the latter call instance
|
||||
|
||||
# to be implemented
|
||||
|
||||
|
||||
class polynomial:
|
||||
pls= []
|
||||
pls = []
|
||||
n = 0
|
||||
|
||||
def dictize(pl):
|
||||
if isinstance(pl,int) or isinstance(pl,float):
|
||||
pl = {0:pl}
|
||||
if isinstance(pl,polynomial):
|
||||
if isinstance(pl, int) or isinstance(pl, float):
|
||||
pl = {0: pl}
|
||||
if isinstance(pl, polynomial):
|
||||
pl = pl.polynomial.copy()
|
||||
return pl
|
||||
|
||||
def isZero(n):
|
||||
return abs(n)<0.000001
|
||||
def __init__(self,s='0 0'):
|
||||
return abs(n) < 0.000001
|
||||
|
||||
def __init__(self, s='0 0'):
|
||||
polynomial.pls.append(self)
|
||||
polynomial.n +=1
|
||||
if isinstance(s,polynomial):
|
||||
self.polynomial=s.polynomial.copy()
|
||||
# don't write like this .**self.polynomial = s.polynomial**,it's ref
|
||||
polynomial.n += 1
|
||||
if isinstance(s, polynomial):
|
||||
self.polynomial = s.polynomial.copy()
|
||||
# don't write like this .**self.polynomial = s.polynomial**,it's ref
|
||||
return
|
||||
elif isinstance(s,dict):
|
||||
elif isinstance(s, dict):
|
||||
self.polynomial = s.copy()
|
||||
return
|
||||
s= s.replace(',',' ')
|
||||
s= s.replace('x',' ')
|
||||
s= s.replace('x^',' ')
|
||||
s = s.replace(':',' ')
|
||||
s = s.replace('\n',' ')
|
||||
s = s.replace(',', ' ')
|
||||
s = s.replace('x', ' ')
|
||||
s = s.replace('x^', ' ')
|
||||
s = s.replace(':', ' ')
|
||||
s = s.replace('\n', ' ')
|
||||
s = s.split(' ')
|
||||
num = len(s)
|
||||
i = 0
|
||||
print(s)
|
||||
self.polynomial = dict()
|
||||
li = [float(i) for i in s]
|
||||
while i<num:
|
||||
while i < num:
|
||||
if not polynomial.isZero(li[i]):
|
||||
index = li[i+1]
|
||||
if index in self.polynomial.keys():
|
||||
self.polynomial[index] += li[i]
|
||||
else:self.polynomial[index] = li[i]
|
||||
i+=2
|
||||
else:
|
||||
self.polynomial[index] = li[i]
|
||||
i += 2
|
||||
if not self.polynomial:
|
||||
self.polynomial = {0:0}
|
||||
self.polynomial = {0: 0}
|
||||
|
||||
def __iter__(self):
|
||||
return iter(list(self.polynomial.keys()))
|
||||
def __getitem__(self,key):
|
||||
|
||||
def __getitem__(self, key):
|
||||
return self.polynomial[key]
|
||||
def __setitem__(self,key,val):
|
||||
|
||||
def __setitem__(self, key, val):
|
||||
self.polynomial[key] = val
|
||||
def __delitem__(self,k):
|
||||
|
||||
def __delitem__(self, k):
|
||||
del self.polynomial[k]
|
||||
def __add__(self,pl):
|
||||
|
||||
def __add__(self, pl):
|
||||
pl = polynomial.dictize(pl)
|
||||
rst = self.polynomial.copy()
|
||||
for i in pl:
|
||||
|
@ -76,7 +86,8 @@ class polynomial:
|
|||
if polynomial.isZero(rst[i]):
|
||||
del rst[i]
|
||||
return polynomial(rst)
|
||||
def __iadd__(self,pl):
|
||||
|
||||
def __iadd__(self, pl):
|
||||
pl = polynomial.dictize(pl)
|
||||
for i in pl:
|
||||
if i not in self:
|
||||
|
@ -86,72 +97,90 @@ class polynomial:
|
|||
if polynomial.isZero(self[i]):
|
||||
del self[i]
|
||||
return self
|
||||
def __sub__(self,pl):
|
||||
|
||||
def __sub__(self, pl):
|
||||
pl = polynomial.dictize(pl)
|
||||
tmp = {i:-j for i,j in pl.items()}
|
||||
tmp = {i: -j for i, j in pl.items()}
|
||||
return self + tmp
|
||||
def __mul__(self,pl):
|
||||
|
||||
def __mul__(self, pl):
|
||||
pl = polynomial.dictize(pl)
|
||||
dic = dict()
|
||||
for i in pl:
|
||||
for j in self:
|
||||
index= i+j
|
||||
index = i+j
|
||||
if index in dic:
|
||||
dic[index] += pl[i]*self[j]
|
||||
else:dic[index] = pl[i]*self[j]
|
||||
return polynomial({i:j for i,j in dic.items() if not polynomial.isZero(j)})
|
||||
def __imul__(self,pl):
|
||||
else:
|
||||
dic[index] = pl[i]*self[j]
|
||||
return polynomial({i: j for i, j in dic.items() if not polynomial.isZero(j)})
|
||||
|
||||
def __imul__(self, pl):
|
||||
self = self*pl
|
||||
return self
|
||||
def __pow__(self,n):
|
||||
rst = polynomial({0:1})
|
||||
|
||||
def __pow__(self, n):
|
||||
rst = polynomial({0: 1})
|
||||
for i in range(n):
|
||||
rst*=self.polynomial
|
||||
rst *= self.polynomial
|
||||
return rst
|
||||
|
||||
def __repr__(self):
|
||||
return self.__str__()
|
||||
|
||||
def __str__(self):
|
||||
output = ''
|
||||
if self.polynomial:
|
||||
key = sorted(self.polynomial.keys(),reverse = True)
|
||||
key = sorted(self.polynomial.keys(), reverse=True)
|
||||
num = len(key)
|
||||
for j,i in enumerate(key):
|
||||
for j, i in enumerate(key):
|
||||
if polynomial.isZero(i):
|
||||
output +='%+g'%self[i]
|
||||
output += '%+g' % self[i]
|
||||
continue
|
||||
if not polynomial.isZero(self[i]-1):
|
||||
if not polynomial.isZero(self[i]+1):
|
||||
output +="%+g"%self[i]
|
||||
else:output +='-'
|
||||
else:output +='+'
|
||||
if not polynomial.isZero(i): output +='x'
|
||||
if not polynomial.isZero(i-1):output +='^%g'%i
|
||||
|
||||
output += "%+g" % self[i]
|
||||
else:
|
||||
output += '-'
|
||||
else:
|
||||
output += '+'
|
||||
if not polynomial.isZero(i):
|
||||
output += 'x'
|
||||
if not polynomial.isZero(i-1):
|
||||
output += '^%g' % i
|
||||
|
||||
if output[0] == '+':
|
||||
return output[1:]
|
||||
return output
|
||||
def iterPolynomial(self,s):
|
||||
rst = polynomial({0:0})
|
||||
|
||||
def iterPolynomial(self, s):
|
||||
rst = polynomial({0: 0})
|
||||
for i in self:
|
||||
rst += s**int(i)*self[i]
|
||||
return rst
|
||||
def __call__(self,s):
|
||||
if isinstance(s,polynomial):
|
||||
return self.iterPolynomial(s)
|
||||
|
||||
def __call__(self, s):
|
||||
if isinstance(s, polynomial):
|
||||
return self.iterPolynomial(s)
|
||||
sum = 0
|
||||
for i in self:
|
||||
sum += self[i] * s**i
|
||||
return sum
|
||||
def __xor__(self,n):
|
||||
|
||||
def __xor__(self, n):
|
||||
tmp = polynomial(self)
|
||||
for i in range(n):
|
||||
self = self.iterPolynomial(tmp)
|
||||
return self
|
||||
|
||||
def save(self):
|
||||
polynomial.pls.append(self)
|
||||
polynomial.n +=1
|
||||
def delPlynomial(self,n):
|
||||
polynomial.n += 1
|
||||
|
||||
def delPlynomial(self, n):
|
||||
return polynomial.pls.pop(n-1)
|
||||
|
||||
|
||||
def menu():
|
||||
print('polynomial operations')
|
||||
print('1.create')
|
||||
|
@ -166,5 +195,6 @@ def menu():
|
|||
print('10.menu')
|
||||
print('11.exit')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
pass
|
||||
|
|
|
@ -12,36 +12,50 @@
|
|||
from functools import total_ordering
|
||||
from random import randint, shuffle
|
||||
|
||||
|
||||
@total_ordering
|
||||
class node:
|
||||
def __init__(self,val,left=None,right=None,isBlack=False):
|
||||
self.val =val
|
||||
def __init__(self, val, left=None, right=None, isBlack=False):
|
||||
self.val = val
|
||||
self.left = left
|
||||
self.right = right
|
||||
self.parent= None
|
||||
self.isBlack = isBlack
|
||||
def __lt__(self,nd):
|
||||
return self.val < nd.val
|
||||
def __eq__(self,nd):
|
||||
return nd is not None and self.val == nd.val
|
||||
def setChild(self,nd,isLeft):
|
||||
if isLeft: self.left = nd
|
||||
else: self.right = nd
|
||||
if nd is not None: nd.parent = self
|
||||
self.parent = None
|
||||
self.isBlack = isBlack
|
||||
|
||||
def __lt__(self, nd):
|
||||
return self.val < nd.val
|
||||
|
||||
def __eq__(self, nd):
|
||||
return nd is not None and self.val == nd.val
|
||||
|
||||
def setChild(self, nd, isLeft):
|
||||
if isLeft:
|
||||
self.left = nd
|
||||
else:
|
||||
self.right = nd
|
||||
if nd is not None:
|
||||
nd.parent = self
|
||||
|
||||
def getChild(self, isLeft):
|
||||
if isLeft:
|
||||
return self.left
|
||||
else:
|
||||
return self.right
|
||||
|
||||
def getChild(self,isLeft):
|
||||
if isLeft: return self.left
|
||||
else: return self.right
|
||||
def __bool__(self):
|
||||
return self.val is not None
|
||||
|
||||
def __str__(self):
|
||||
color = 'B' if self.isBlack else 'R'
|
||||
val = '-' if self.parent==None else self.parent.val
|
||||
val = '-' if self.parent == None else self.parent.val
|
||||
return f'{color}-{self.val}'
|
||||
|
||||
def __repr__(self):
|
||||
return f'node({self.val},isBlack={self.isBlack})'
|
||||
|
||||
|
||||
class redBlackTree:
|
||||
def __init__(self,unique=False):
|
||||
def __init__(self, unique=False):
|
||||
'''if unique is True, all node'vals are unique, else there may be equal vals'''
|
||||
self.root = None
|
||||
self.unique = unique
|
||||
|
@ -49,23 +63,29 @@ class redBlackTree:
|
|||
@staticmethod
|
||||
def checkBlack(nd):
|
||||
return nd is None or nd.isBlack
|
||||
|
||||
@staticmethod
|
||||
def setBlack(nd,isBlack):
|
||||
def setBlack(nd, isBlack):
|
||||
if nd is not None:
|
||||
if isBlack is None or isBlack:
|
||||
nd.isBlack = True
|
||||
else:nd.isBlack = False
|
||||
def setRoot(self,nd):
|
||||
if nd is not None: nd.parent=None
|
||||
self.root= nd
|
||||
def find(self,val):
|
||||
else:
|
||||
nd.isBlack = False
|
||||
|
||||
def setRoot(self, nd):
|
||||
if nd is not None:
|
||||
nd.parent = None
|
||||
self.root = nd
|
||||
|
||||
def find(self, val):
|
||||
nd = self.root
|
||||
while nd:
|
||||
if nd.val ==val:
|
||||
if nd.val == val:
|
||||
return nd
|
||||
else:
|
||||
nd = nd.getChild(nd.val>val)
|
||||
def getSuccessor(self,nd):
|
||||
nd = nd.getChild(nd.val > val)
|
||||
|
||||
def getSuccessor(self, nd):
|
||||
if nd:
|
||||
if nd.right:
|
||||
nd = nd.right
|
||||
|
@ -76,18 +96,20 @@ class redBlackTree:
|
|||
while nd.parent is not None and nd.parent.right is nd:
|
||||
nd = nd.parent
|
||||
return None if nd is self.root else nd.parent
|
||||
def rotate(self,prt,chd):
|
||||
'''rotate prt with the center of chd'''
|
||||
|
||||
def rotate(self, prt, chd):
|
||||
'''rotate prt with the center of chd'''
|
||||
if self.root is prt:
|
||||
self.setRoot(chd)
|
||||
else:
|
||||
prt.parent.setChild(chd, prt.parent.left is prt)
|
||||
isLeftChd = prt.left is chd
|
||||
prt.setChild(chd.getChild(not isLeftChd), isLeftChd)
|
||||
chd.setChild(prt,not isLeftChd)
|
||||
chd.setChild(prt, not isLeftChd)
|
||||
|
||||
def insert(self,nd):
|
||||
if nd.isBlack: nd.isBlack = False
|
||||
def insert(self, nd):
|
||||
if nd.isBlack:
|
||||
nd.isBlack = False
|
||||
|
||||
if self.root is None:
|
||||
self.setRoot(nd)
|
||||
|
@ -95,16 +117,18 @@ class redBlackTree:
|
|||
else:
|
||||
parent = self.root
|
||||
while parent:
|
||||
if parent == nd : return None
|
||||
if parent == nd:
|
||||
return None
|
||||
isLeft = parent > nd
|
||||
chd = parent.getChild(isLeft)
|
||||
chd = parent.getChild(isLeft)
|
||||
if chd is None:
|
||||
parent.setChild(nd,isLeft)
|
||||
parent.setChild(nd, isLeft)
|
||||
break
|
||||
else:
|
||||
parent = chd
|
||||
self.fixUpInsert(parent,nd)
|
||||
def fixUpInsert(self,parent,nd):
|
||||
self.fixUpInsert(parent, nd)
|
||||
|
||||
def fixUpInsert(self, parent, nd):
|
||||
''' adjust color and level, there are two red nodes: the new one and its parent'''
|
||||
while not self.checkBlack(parent):
|
||||
grand = parent.parent
|
||||
|
@ -125,8 +149,8 @@ class redBlackTree:
|
|||
# grand grand
|
||||
# parent or parent
|
||||
# nd nd
|
||||
self.rotate(parent,nd) #parent rotate
|
||||
nd,parent = parent,nd
|
||||
self.rotate(parent, nd) # parent rotate
|
||||
nd, parent = parent, nd
|
||||
# case 3 (case 2.2) the new node is inserted in left-left or right-right form
|
||||
# grand grand
|
||||
# parent or parent
|
||||
|
@ -134,25 +158,29 @@ class redBlackTree:
|
|||
|
||||
self.setBlack(grand, False)
|
||||
self.setBlack(parent, True)
|
||||
self.rotate(grand,parent)
|
||||
self.setBlack(self.root,True)
|
||||
self.rotate(grand, parent)
|
||||
self.setBlack(self.root, True)
|
||||
|
||||
def copyNode(self,src,des):
|
||||
def copyNode(self, src, des):
|
||||
'''when deleting a node which has two kids,
|
||||
copy its succesor's data to his position
|
||||
data exclude left, right , isBlack
|
||||
'''
|
||||
des.val = src.val
|
||||
def delete(self,val):
|
||||
|
||||
def delete(self, val):
|
||||
'''delete node in a binary search tree'''
|
||||
if isinstance(val,node): val = val.val
|
||||
if isinstance(val, node):
|
||||
val = val.val
|
||||
nd = self.find(val)
|
||||
if nd is None: return
|
||||
if nd is None:
|
||||
return
|
||||
self._delete(nd)
|
||||
def _delete(self,nd):
|
||||
|
||||
def _delete(self, nd):
|
||||
y = None
|
||||
if nd.left and nd.right:
|
||||
y= self.getSuccessor(nd)
|
||||
y = self.getSuccessor(nd)
|
||||
else:
|
||||
y = nd
|
||||
py = y.parent
|
||||
|
@ -160,58 +188,60 @@ class redBlackTree:
|
|||
if py is None:
|
||||
self.setRoot(x)
|
||||
else:
|
||||
py.setChild(x,py.left is y)
|
||||
py.setChild(x, py.left is y)
|
||||
if y != nd:
|
||||
self.copyNode(y,nd)
|
||||
if self.checkBlack(y): self.fixUpDel(py,x)
|
||||
|
||||
def fixUpDel(self,prt,chd):
|
||||
self.copyNode(y, nd)
|
||||
if self.checkBlack(y):
|
||||
self.fixUpDel(py, x)
|
||||
|
||||
def fixUpDel(self, prt, chd):
|
||||
''' adjust colors and rotate '''
|
||||
while self.root != chd and self.checkBlack(chd):
|
||||
isLeft =prt.left is chd
|
||||
isLeft = prt.left is chd
|
||||
brother = prt.getChild(not isLeft)
|
||||
# brother is black
|
||||
lb = self.checkBlack(brother.getChild(isLeft))
|
||||
rb = self.checkBlack(brother.getChild(not isLeft))
|
||||
if not self.checkBlack(brother):
|
||||
if not self.checkBlack(brother):
|
||||
# case 1: brother is red. converted to case 2,3,4
|
||||
|
||||
self.setBlack(prt,False)
|
||||
self.setBlack(brother,True)
|
||||
self.rotate(prt,brother)
|
||||
self.setBlack(prt, False)
|
||||
self.setBlack(brother, True)
|
||||
self.rotate(prt, brother)
|
||||
|
||||
elif lb and rb:
|
||||
# case 2: brother is black and two kids are black.
|
||||
elif lb and rb:
|
||||
# case 2: brother is black and two kids are black.
|
||||
# conveted to the begin case
|
||||
self.setBlack(brother,False)
|
||||
self.setBlack(brother, False)
|
||||
chd = prt
|
||||
prt= chd.parent
|
||||
prt = chd.parent
|
||||
else:
|
||||
if rb:
|
||||
if rb:
|
||||
# case 3: brother is black and left kid is red and right child is black
|
||||
# rotate bro to make g w wl wr in one line
|
||||
# uncle's son is nephew, and niece for uncle's daughter
|
||||
nephew = brother.getChild(isLeft)
|
||||
self.setBlack(nephew,True)
|
||||
self.setBlack(brother,False)
|
||||
self.setBlack(nephew, True)
|
||||
self.setBlack(brother, False)
|
||||
|
||||
# brother (not isLeft) rotate
|
||||
self.rotate(brother,nephew)
|
||||
self.rotate(brother, nephew)
|
||||
brother = nephew
|
||||
|
||||
# case 4: brother is black and right child is red
|
||||
brother.isBlack = prt.isBlack
|
||||
self.setBlack(prt,True)
|
||||
self.setBlack(brother.getChild(not isLeft),True)
|
||||
self.setBlack(prt, True)
|
||||
self.setBlack(brother.getChild(not isLeft), True)
|
||||
|
||||
self.rotate(prt,brother)
|
||||
self.rotate(prt, brother)
|
||||
chd = self.root
|
||||
self.setBlack(chd,True)
|
||||
self.setBlack(chd, True)
|
||||
|
||||
def sort(self,reverse = False):
|
||||
def sort(self, reverse=False):
|
||||
''' return a generator of sorted data'''
|
||||
def inOrder(root):
|
||||
if root is None:return
|
||||
if root is None:
|
||||
return
|
||||
if reverse:
|
||||
yield from inOrder(root.right)
|
||||
else:
|
||||
|
@ -225,8 +255,10 @@ class redBlackTree:
|
|||
|
||||
def display(self):
|
||||
def getHeight(nd):
|
||||
if nd is None:return 0
|
||||
return max(getHeight(nd.left),getHeight(nd.right)) +1
|
||||
if nd is None:
|
||||
return 0
|
||||
return max(getHeight(nd.left), getHeight(nd.right)) + 1
|
||||
|
||||
def levelVisit(root):
|
||||
from collections import deque
|
||||
lst = deque([root])
|
||||
|
@ -234,24 +266,26 @@ class redBlackTree:
|
|||
h = getHeight(root)
|
||||
ct = lv = 0
|
||||
while 1:
|
||||
ct+=1
|
||||
ct += 1
|
||||
nd = lst.popleft()
|
||||
if ct >= 2**lv:
|
||||
lv+=1
|
||||
if lv>h:break
|
||||
lv += 1
|
||||
if lv > h:
|
||||
break
|
||||
level.append([])
|
||||
level[-1].append(str(nd))
|
||||
if nd is not None:
|
||||
lst += [nd.left,nd.right]
|
||||
lst += [nd.left, nd.right]
|
||||
else:
|
||||
lst +=[None,None]
|
||||
lst += [None, None]
|
||||
return level
|
||||
|
||||
def addBlank(lines):
|
||||
width = 1+len(str(self.root))
|
||||
sep = ' '*width
|
||||
n = len(lines)
|
||||
for i,oneline in enumerate(lines):
|
||||
k = 2**(n-i) -1
|
||||
for i, oneline in enumerate(lines):
|
||||
k = 2**(n-i) - 1
|
||||
new = [sep*((k-1)//2)]
|
||||
for s in oneline:
|
||||
new.append(s.ljust(width))
|
||||
|
@ -262,59 +296,67 @@ class redBlackTree:
|
|||
lines = levelVisit(self.root)
|
||||
lines = addBlank(lines)
|
||||
li = [''.join(line) for line in lines]
|
||||
length = 10 if li==[] else max(len(i) for i in li)//2
|
||||
begin ='\n'+ 'red-black-tree'.rjust(length+14,'-') + '-'*(length)
|
||||
length = 10 if li == [] else max(len(i) for i in li)//2
|
||||
begin = '\n' + 'red-black-tree'.rjust(length+14, '-') + '-'*(length)
|
||||
end = '-'*(length*2+14)+'\n'
|
||||
return '\n'.join([begin,*li,end])
|
||||
return '\n'.join([begin, *li, end])
|
||||
|
||||
def __str__(self):
|
||||
return self.display()
|
||||
|
||||
|
||||
def genNum(n =10):
|
||||
nums =[]
|
||||
def genNum(n=10):
|
||||
nums = []
|
||||
for i in range(n):
|
||||
while 1:
|
||||
d = randint(0,100)
|
||||
d = randint(0, 100)
|
||||
if d not in nums:
|
||||
nums.append(d)
|
||||
break
|
||||
return nums
|
||||
|
||||
def buildTree(n=10,nums=None,visitor=None):
|
||||
if nums is None or nums ==[]: nums = genNum(n)
|
||||
|
||||
def buildTree(n=10, nums=None, visitor=None):
|
||||
if nums is None or nums == []:
|
||||
nums = genNum(n)
|
||||
rbtree = redBlackTree()
|
||||
print(f'build a red-black tree using {nums}')
|
||||
for i in nums:
|
||||
rbtree.insert(node(i))
|
||||
print(rbtree)
|
||||
if visitor:
|
||||
visitor(rbtree,i)
|
||||
return rbtree,nums
|
||||
visitor(rbtree, i)
|
||||
return rbtree, nums
|
||||
|
||||
|
||||
def testInsert(nums=None):
|
||||
def visitor(t,val):
|
||||
def visitor(t, val):
|
||||
print('inserting', val)
|
||||
print(t)
|
||||
rbtree,nums = buildTree(visitor = visitor,nums=nums)
|
||||
print('-'*5+ 'in-order visit' + '-'*5)
|
||||
for i,j in enumerate(rbtree.sort()):
|
||||
rbtree, nums = buildTree(visitor=visitor, nums=nums)
|
||||
print('-'*5 + 'in-order visit' + '-'*5)
|
||||
for i, j in enumerate(rbtree.sort()):
|
||||
print(f'{i+1}: {j}')
|
||||
|
||||
|
||||
def testSuc(nums=None):
|
||||
rbtree,nums = buildTree(nums=nums)
|
||||
rbtree, nums = buildTree(nums=nums)
|
||||
for i in rbtree.sort():
|
||||
print(f'{i}\'s suc is {rbtree.getSuccessor(i)}')
|
||||
|
||||
|
||||
def testDelete(nums=None):
|
||||
rbtree,nums = buildTree(nums = nums)
|
||||
rbtree, nums = buildTree(nums=nums)
|
||||
print(rbtree)
|
||||
for i in sorted(nums):
|
||||
print(f'deleting {i}')
|
||||
rbtree.delete(i)
|
||||
print(rbtree)
|
||||
|
||||
if __name__=='__main__':
|
||||
lst =[45, 30, 64, 36, 95, 38, 76, 34, 50, 1]
|
||||
lst = [0,3,5,6,26,25,8,19,15,16,17]
|
||||
#testSuc(lst)
|
||||
#testInsert(lst)
|
||||
|
||||
if __name__ == '__main__':
|
||||
lst = [45, 30, 64, 36, 95, 38, 76, 34, 50, 1]
|
||||
lst = [0, 3, 5, 6, 26, 25, 8, 19, 15, 16, 17]
|
||||
# testSuc(lst)
|
||||
# testInsert(lst)
|
||||
testDelete()
|
||||
|
|
|
@ -10,148 +10,190 @@
|
|||
#########################################################################
|
||||
'''
|
||||
|
||||
from collections import deque,Iterable
|
||||
from collections import deque, Iterable
|
||||
# use isinstance(obj,Iterable) to judge if an obj is iterable
|
||||
|
||||
|
||||
class node:
|
||||
def __init__(self,val = None,left=None,right=None,parent=None):
|
||||
def __init__(self, val=None, left=None, right=None, parent=None):
|
||||
self.val = val
|
||||
if val :self.freq = 1
|
||||
else :self.freq = 0
|
||||
if val:
|
||||
self.freq = 1
|
||||
else:
|
||||
self.freq = 0
|
||||
self.left = left
|
||||
self.right = right
|
||||
self.parent = parent
|
||||
def getChild(self,s=0):
|
||||
if isinstance(s,int):s =[s]
|
||||
self.parent = parent
|
||||
|
||||
def getChild(self, s=0):
|
||||
if isinstance(s, int):
|
||||
s = [s]
|
||||
last = self
|
||||
for i in s:
|
||||
if not last:return None
|
||||
if i == 0: last = last.left
|
||||
else:last = last.right
|
||||
if not last:
|
||||
return None
|
||||
if i == 0:
|
||||
last = last.left
|
||||
else:
|
||||
last = last.right
|
||||
return last
|
||||
def setChild(self,child,s=0):
|
||||
if isinstance(s,Iterable):
|
||||
|
||||
def setChild(self, child, s=0):
|
||||
if isinstance(s, Iterable):
|
||||
i = s[0]
|
||||
del s[0]
|
||||
if i == 0:self.left.setChild(child,s)
|
||||
else:self.right.setChild(child,s)
|
||||
elif s:self.right = child
|
||||
else:self.left = child
|
||||
if i == 0:
|
||||
self.left.setChild(child, s)
|
||||
else:
|
||||
self.right.setChild(child, s)
|
||||
elif s:
|
||||
self.right = child
|
||||
else:
|
||||
self.left = child
|
||||
|
||||
|
||||
class splayTree:
|
||||
def __init__(self,s=[]):
|
||||
def __init__(self, s=[]):
|
||||
s = list(s)
|
||||
self.root = None
|
||||
s = sorted(s,reverse = True)
|
||||
s = sorted(s, reverse=True)
|
||||
for i in s:
|
||||
self.insert(self.root,i)
|
||||
def insert(self,k):
|
||||
if not self.root :self.root = node(k)
|
||||
else:self._insert(self.root,k)
|
||||
def _insert(self,root,k):
|
||||
if root.val == k :
|
||||
root.freq +=1
|
||||
elif root.val<k:
|
||||
self.insert(self.root, i)
|
||||
|
||||
def insert(self, k):
|
||||
if not self.root:
|
||||
self.root = node(k)
|
||||
else:
|
||||
self._insert(self.root, k)
|
||||
|
||||
def _insert(self, root, k):
|
||||
if root.val == k:
|
||||
root.freq += 1
|
||||
elif root.val < k:
|
||||
if not root.right:
|
||||
root.right = node(k)
|
||||
root.right.parent = root
|
||||
else:self._insert(root.right,k)
|
||||
else:
|
||||
self._insert(root.right, k)
|
||||
else:
|
||||
if not root.left:
|
||||
root.left = node(k)
|
||||
root.left.parent = root
|
||||
else:self._insert(root.left,k)
|
||||
def _zigzagRotate(self,i,j,root,parent,grand):
|
||||
parent.setChild(root.getChild(i),j)
|
||||
root.setChild(parent,i)
|
||||
grand.setChild(root.getChild(j),i)
|
||||
root.setChild(grand,j)
|
||||
if root.parent:root.parent = grand.parent
|
||||
else:
|
||||
self._insert(root.left, k)
|
||||
|
||||
def _zigzagRotate(self, i, j, root, parent, grand):
|
||||
parent.setChild(root.getChild(i), j)
|
||||
root.setChild(parent, i)
|
||||
grand.setChild(root.getChild(j), i)
|
||||
root.setChild(grand, j)
|
||||
if root.parent:
|
||||
root.parent = grand.parent
|
||||
parent.parent = root
|
||||
grand.parent = root
|
||||
def _lineRotate(self,i,root,parent,grand):
|
||||
grand.setChild(parent.getChild(i^1),i)
|
||||
parent.setChild(grand,i^1)
|
||||
parent.setChild(root.getChild(i^1),i)
|
||||
root.setChild(parent,i^1)
|
||||
if root.parent:root.parent = grand.parent
|
||||
parent.parent = root
|
||||
|
||||
def _lineRotate(self, i, root, parent, grand):
|
||||
grand.setChild(parent.getChild(i ^ 1), i)
|
||||
parent.setChild(grand, i ^ 1)
|
||||
parent.setChild(root.getChild(i ^ 1), i)
|
||||
root.setChild(parent, i ^ 1)
|
||||
if root.parent:
|
||||
root.parent = grand.parent
|
||||
parent.parent = root
|
||||
grand.parent = parent
|
||||
def _rotate(self,root):
|
||||
if root == self.root:return
|
||||
|
||||
def _rotate(self, root):
|
||||
if root == self.root:
|
||||
return
|
||||
if root.parent == self.root:
|
||||
for i in range(2):
|
||||
if root.parent.getChild(i) == root:
|
||||
root.parent.parent = root
|
||||
root.parent.setChild(root.getChild(i^1),i)
|
||||
root.parent.setChild(root.getChild(i ^ 1), i)
|
||||
root.parent = None
|
||||
root.setChild(self.root,i^1)
|
||||
root.setChild(self.root, i ^ 1)
|
||||
self.root = root
|
||||
else:
|
||||
grand = root.parent.parent
|
||||
parent = root.parent
|
||||
if grand == self.root:
|
||||
self.root = root
|
||||
root.parent = None
|
||||
self.root = root
|
||||
root.parent = None
|
||||
else:
|
||||
for i in range(2):
|
||||
if grand.parent.getChild(i) == grand:
|
||||
grand.parent.setChild(root,i)
|
||||
if grand.parent.getChild(i) == grand:
|
||||
grand.parent.setChild(root, i)
|
||||
for i in range(2):
|
||||
for j in range(2):
|
||||
if i!=j and grand.getChild([i,j]) == root:
|
||||
self._zigzagRotate(i,j,root,parent,grand)
|
||||
elif i==j and grand.getChild([i,i]) == root:
|
||||
self._lineRotate(i,root,parent,grand)
|
||||
if i != j and grand.getChild([i, j]) == root:
|
||||
self._zigzagRotate(i, j, root, parent, grand)
|
||||
elif i == j and grand.getChild([i, i]) == root:
|
||||
self._lineRotate(i, root, parent, grand)
|
||||
self._rotate(root)
|
||||
def _find(self,root,k):
|
||||
if not root:return 0
|
||||
|
||||
def _find(self, root, k):
|
||||
if not root:
|
||||
return 0
|
||||
if root.val > k:
|
||||
return self._find(root.left,k)
|
||||
elif root.val<k:
|
||||
return self._find(root.right,k)
|
||||
return self._find(root.left, k)
|
||||
elif root.val < k:
|
||||
return self._find(root.right, k)
|
||||
else:
|
||||
self._rotate(root)
|
||||
return root.freq
|
||||
def _maxmin(self,root,i=0):
|
||||
if not root:return None
|
||||
|
||||
def _maxmin(self, root, i=0):
|
||||
if not root:
|
||||
return None
|
||||
if root.getChild(i):
|
||||
return self._maxmin(root.getChild(i))
|
||||
return root
|
||||
|
||||
def Max(self):
|
||||
return self._maxmin(self.root,1)
|
||||
return self._maxmin(self.root, 1)
|
||||
|
||||
def Min(self):
|
||||
return self._maxmin(self.root,0)
|
||||
def remove(self,k):
|
||||
return self._maxmin(self.root, 0)
|
||||
|
||||
def remove(self, k):
|
||||
tmp = self.find(k)
|
||||
if not tmp:raise ValueError
|
||||
if not tmp:
|
||||
raise ValueError
|
||||
else:
|
||||
if self.root.left:
|
||||
r = self.root.right
|
||||
self.root = self.root.left
|
||||
self.root.parent = None
|
||||
Max = self.Max()
|
||||
Max.right= r
|
||||
Max.right = r
|
||||
if r:
|
||||
r.parent = Max
|
||||
else:
|
||||
self.root = self.root.right
|
||||
def find(self,k):
|
||||
return self._find(self.root,k)
|
||||
|
||||
def find(self, k):
|
||||
return self._find(self.root, k)
|
||||
|
||||
def levelTraverse(self):
|
||||
q = deque()
|
||||
q.append((self.root,0))
|
||||
q.append((self.root, 0))
|
||||
rst = []
|
||||
while q:
|
||||
tmp,n= q.popleft()
|
||||
tmp, n = q.popleft()
|
||||
rst.append(tmp)
|
||||
if tmp.left:q.append((tmp.left,n+1))
|
||||
if tmp.right:q.append((tmp.right,n+1))
|
||||
if tmp.left:
|
||||
q.append((tmp.left, n+1))
|
||||
if tmp.right:
|
||||
q.append((tmp.right, n+1))
|
||||
return rst
|
||||
|
||||
def display(self):
|
||||
data = self.levelTraverse()
|
||||
for i in data:
|
||||
print (i.val,end=' ')
|
||||
print(i.val, end=' ')
|
||||
print('')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
a = splayTree()
|
||||
a.insert(5)
|
||||
|
@ -165,7 +207,7 @@ if __name__ == '__main__':
|
|||
print('initial:5,1,4,2,7,8,2')
|
||||
a.display()
|
||||
tmp = a.find(2)
|
||||
print("after find(2):%d"%tmp)
|
||||
print("after find(2):%d" % tmp)
|
||||
a.display()
|
||||
print("remove(4)")
|
||||
a.remove(4)
|
||||
|
|
12
dataStructure/unionFindSet.py
Normal file
12
dataStructure/unionFindSet.py
Normal file
|
@ -0,0 +1,12 @@
|
|||
class unionFindSet:
|
||||
def __init__(self, S):
|
||||
self.S = {i: i for i in S}
|
||||
|
||||
def find(self, x):
|
||||
if x != self.S[x]:
|
||||
self.S[x] = self.find(self.S[x])
|
||||
return self.S[x]
|
||||
|
||||
def union(self, a, b, key=lambda x: x):
|
||||
x, y = sorted((self.find(a), self.find(b)), key=key)
|
||||
self.S[a] = self.S[b] = self.S[y] = x
|
|
@ -1,99 +0,0 @@
|
|||
#coding: utf-8
|
||||
''' mbinary
|
||||
#######################################################################
|
||||
# File : accountsMerge.py
|
||||
# Author: mbinary
|
||||
# Mail: zhuheqin1@gmail.com
|
||||
# Blog: https://mbinary.xyz
|
||||
# Github: https://github.com/mbinary
|
||||
# Created Time: 2018-12-18 17:07
|
||||
# Description:
|
||||
给定一个列表 accounts,每个元素 accounts[i] 是一个字符串列表,其中第一个元素 accounts[i][0] 是 名称 (name),其余元素是 emails 表示该帐户的邮箱地址。
|
||||
|
||||
现在,我们想合并这些帐户。如果两个帐户都有一些共同的邮件地址,则两个帐户必定属于同一个人。请注意,即使两个帐户具有相同的名称,它们也可能属于不同的人,因为人们可能具有相同的名称。一个人最初可以拥有任意数量的帐户,但其所有帐户都具有相同的名称。
|
||||
|
||||
合并帐户后,按以下格式返回帐户:每个帐户的第一个元素是名称,其余元素是按顺序排列的邮箱地址。accounts 本身可以以任意顺序返回。
|
||||
|
||||
例子 1:
|
||||
|
||||
Input:
|
||||
accounts = [["John", "johnsmith@mail.com", "john00@mail.com"], ["John", "johnnybravo@mail.com"], ["John", "johnsmith@mail.com", "john_newyork@mail.com"], ["Mary", "mary@mail.com"]]
|
||||
Output: [["John", 'john00@mail.com', 'john_newyork@mail.com', 'johnsmith@mail.com'], ["John", "johnnybravo@mail.com"], ["Mary", "mary@mail.com"]]
|
||||
Explanation:
|
||||
第一个和第三个 John 是同一个人,因为他们有共同的电子邮件 "johnsmith@mail.com"。
|
||||
第二个 John 和 Mary 是不同的人,因为他们的电子邮件地址没有被其他帐户使用。
|
||||
#######################################################################
|
||||
'''
|
||||
|
||||
class Solution(object):
|
||||
def accountsMerge(self, accounts):
|
||||
"""
|
||||
:type accounts: List[List[str]]
|
||||
:rtype: List[List[str]]
|
||||
"""
|
||||
mailDic = {}
|
||||
for ct,i in enumerate(accounts):
|
||||
for j in i[1:]:
|
||||
mailDic[j] = (ct,i[0])
|
||||
mails = {mail:idx for idx,mail in enumerate(mailDic.keys())}
|
||||
mailNum = len(mails)
|
||||
self.findSet = [i for i in range(mailNum)]
|
||||
for li in accounts:
|
||||
n = len(li)
|
||||
for i in range(1,n-1):
|
||||
for j in range(i+1,n):
|
||||
self.union(mails[li[i]],mails[li[j]])
|
||||
dic = {}
|
||||
mails = {j:i for i,j in mails.items()}
|
||||
for i in range(mailNum):
|
||||
mail = mails[i]
|
||||
n = mailDic[mails[self.find(i)]][0]
|
||||
if n in dic:
|
||||
dic[n].append(mail)
|
||||
else:
|
||||
dic[n] = [mail]
|
||||
nameId = {i[0]:i[1] for i in mailDic.values()}
|
||||
return [[nameId[i]]+sorted(mail) for i,mail in dic.items()]
|
||||
def find(self,i):
|
||||
if self.findSet[i]!=i:
|
||||
n = self.find(self.findSet[i])
|
||||
self.findSet[i] = n
|
||||
return self.findSet[i]
|
||||
def union(self,i,j):
|
||||
if i!=j:
|
||||
n = self.find(i)
|
||||
if n!=self.find(j):
|
||||
self.findSet[n] = self.findSet[j]
|
||||
|
||||
class Solution2:
|
||||
'''并查映射'''
|
||||
def accountsMerge(self, accounts):
|
||||
"""
|
||||
:type accounts: List[List[str]]
|
||||
:rtype: List[List[str]]
|
||||
"""
|
||||
mailDic = {j:ct for ct,i in enumerate(accounts) for j in i[1:]}
|
||||
self.findSet = {i:i for i in mailDic}
|
||||
for li in accounts:
|
||||
n = len(li)
|
||||
for i in range(1,n-1):
|
||||
for j in range(i+1,n):
|
||||
self.union(li[i],li[j])
|
||||
dic = {}
|
||||
for mail in self.findSet:
|
||||
n = mailDic[self.find(mail)]
|
||||
if n in dic:
|
||||
dic[n].append(mail)
|
||||
else:
|
||||
dic[n] = [mail]
|
||||
return [[accounts[i][0]]+sorted(mail) for i,mail in dic.items()]
|
||||
def find(self,i):
|
||||
if self.findSet[i]!=i:
|
||||
n = self.find(self.findSet[i])
|
||||
self.findSet[i] = n
|
||||
return self.findSet[i]
|
||||
def union(self,i,j):
|
||||
if i!=j:
|
||||
n = self.find(i)
|
||||
if n!=self.find(j):
|
||||
self.findSet[n] = self.findSet[j]
|
|
@ -1,42 +0,0 @@
|
|||
#coding: utf-8
|
||||
''' mbinary
|
||||
#######################################################################
|
||||
# File : unionFind.py
|
||||
# Author: mbinary
|
||||
# Mail: zhuheqin1@gmail.com
|
||||
# Blog: https://mbinary.xyz
|
||||
# Github: https://github.com/mbinary
|
||||
# Created Time: 2018-12-18 14:53
|
||||
# Description:
|
||||
班上有 N 名学生。其中有些人是朋友,有些则不是。他们的友谊具有是传递性。如果已知 A 是 B 的朋友,B 是 C 的朋友,那么我们可以认为 A 也是 C 的朋友。所谓的朋友圈,是指所有朋友的集合。
|
||||
|
||||
给定一个 N * N 的矩阵 M,表示班级中学生之间的朋友关系。如果 M[i][j] = 1,表示已知第 i 个和 j 个学生互为朋友关系,否则为不知道。你必须输出所有学生中的已知的朋友圈总数。
|
||||
#######################################################################
|
||||
'''
|
||||
|
||||
|
||||
class Solution(object):
|
||||
def findCircleNum(self, M):
|
||||
"""
|
||||
:type M: List[List[int]]
|
||||
:rtype: int
|
||||
"""
|
||||
n = len(M)
|
||||
self.data = [i for i in range(n)]
|
||||
for i in range(n):
|
||||
for j in range(n):
|
||||
if M[i][j]==1:
|
||||
self.union(i,j)
|
||||
ret = set()
|
||||
for i in range(n):
|
||||
ret.add(self.find(i))
|
||||
return len(ret)
|
||||
def find(self,i):
|
||||
if self.data[i]!=i:
|
||||
self.data[i] = self.find(self.data[i])
|
||||
return self.data[i]
|
||||
def union(self,i,j):
|
||||
if i!=j:
|
||||
n = self.find(i)
|
||||
if n!=self.find(j):
|
||||
self.data[n]= self.data[j]
|
|
@ -10,6 +10,7 @@
|
|||
#########################################################################
|
||||
'''
|
||||
|
||||
|
||||
class winnerTree:
|
||||
'''if i<lowExt p = (i+offset)//2
|
||||
else p = (i+n-1-lowExt)//2
|
||||
|
@ -18,79 +19,92 @@ class winnerTree:
|
|||
i is the index of players
|
||||
lowExt is the double node num of the lowest layer of the tree
|
||||
'''
|
||||
def __init__(self,players,reverse=False):
|
||||
self.n=len(players)
|
||||
|
||||
def __init__(self, players, reverse=False):
|
||||
self.n = len(players)
|
||||
self.tree = [0]*self.n
|
||||
players.insert(0,0)
|
||||
self.players=players
|
||||
self.reverse=reverse
|
||||
self.getNum()
|
||||
players.insert(0, 0)
|
||||
self.players = players
|
||||
self.reverse = reverse
|
||||
self.getNum()
|
||||
self.initTree(1)
|
||||
|
||||
def getNum(self):
|
||||
i=1
|
||||
while 2*i< self.n:i=i*2
|
||||
if 2*i ==self. n:
|
||||
self.lowExt=0
|
||||
i = 1
|
||||
while 2*i < self.n:
|
||||
i = i*2
|
||||
if 2*i == self. n:
|
||||
self.lowExt = 0
|
||||
self.s = 2*i-1
|
||||
else:
|
||||
self.lowExt = (self.n-i)*2
|
||||
self.s = i-1
|
||||
self.offset = 2*i-1
|
||||
def treeToArray(self,p):
|
||||
return 2*p-self.offset if p>self.s else 2*p+self.lowExt-self.n+1
|
||||
def arrayToTree(self,i):
|
||||
return (i+self.offset)//2 if i<=self.lowExt else (i-self.lowExt+ self.n-1)//2
|
||||
def win(self,a,b):
|
||||
return a<b if self.reverse else a>b
|
||||
def initTree(self,p):
|
||||
if p>=self.n:
|
||||
delta = p%2 #!!! good job notice delta mark the lchild or rchlid
|
||||
|
||||
def treeToArray(self, p):
|
||||
return 2*p-self.offset if p > self.s else 2*p+self.lowExt-self.n+1
|
||||
|
||||
def arrayToTree(self, i):
|
||||
return (i+self.offset)//2 if i <= self.lowExt else (i-self.lowExt + self.n-1)//2
|
||||
|
||||
def win(self, a, b):
|
||||
return a < b if self.reverse else a > b
|
||||
|
||||
def initTree(self, p):
|
||||
if p >= self.n:
|
||||
delta = p % 2 # !!! good job notice delta mark the lchild or rchlid
|
||||
return self.players[self.treeToArray(p//2)+delta]
|
||||
l = self.initTree(2*p)
|
||||
r = self.initTree(2*p+1)
|
||||
self.tree[p] = l if self.win(l,r) else r
|
||||
self.tree[p] = l if self.win(l, r) else r
|
||||
return self.tree[p]
|
||||
|
||||
def winner(self):
|
||||
idx = 1
|
||||
while 2*idx<self.n:
|
||||
while 2*idx < self.n:
|
||||
idx = 2*idx if self.tree[2*idx] == self.tree[idx] else idx*2+1
|
||||
num = self.treeToArray(idx)
|
||||
num = num+1 if self.players[num] !=self.tree[1] else num
|
||||
return self.tree[1],num
|
||||
def getOppo(self,i,x,p):
|
||||
oppo=None
|
||||
if 2*p<self.n:oppo=self.tree[2*p]
|
||||
elif i<=self.lowExt:oppo=self.players[i-1+i%2*2]
|
||||
num = num+1 if self.players[num] != self.tree[1] else num
|
||||
return self.tree[1], num
|
||||
|
||||
def getOppo(self, i, x, p):
|
||||
oppo = None
|
||||
if 2*p < self.n:
|
||||
oppo = self.tree[2*p]
|
||||
elif i <= self.lowExt:
|
||||
oppo = self.players[i-1+i % 2*2]
|
||||
else:
|
||||
lpl= self.players[2*p+self.lowExt-self.n+1]
|
||||
oppo = lpl if lpl!=x else self.players[2*p+self.lowExt-self.n+2]
|
||||
lpl = self.players[2*p+self.lowExt-self.n+1]
|
||||
oppo = lpl if lpl != x else self.players[2*p+self.lowExt-self.n+2]
|
||||
return oppo
|
||||
def update(self,i,x):
|
||||
|
||||
def update(self, i, x):
|
||||
''' i is 1-indexed which is the num of player
|
||||
and x is the new val of the player '''
|
||||
self.players[i]=x
|
||||
self.players[i] = x
|
||||
p = self.arrayToTree(i)
|
||||
oppo =self.getOppo(i,x,p)
|
||||
self.tree[p] = x if self.win(x,oppo) else oppo
|
||||
p=p//2
|
||||
oppo = self.getOppo(i, x, p)
|
||||
self.tree[p] = x if self.win(x, oppo) else oppo
|
||||
p = p//2
|
||||
while p:
|
||||
l = self.tree[p*2]
|
||||
r = None
|
||||
if 2*p+1<self.n:r=self.tree[p*2+1] #notice this !!!
|
||||
else:r = self.players[2*p+self.lowExt-self.n+1]
|
||||
self.tree[p] = l if self.win(l,r) else r
|
||||
p=p//2
|
||||
|
||||
|
||||
|
||||
if __name__ =='__main__':
|
||||
s= [4,1,6,7,9,5234,0,2,7,4,123]
|
||||
if 2*p+1 < self.n:
|
||||
r = self.tree[p*2+1] # notice this !!!
|
||||
else:
|
||||
r = self.players[2*p+self.lowExt-self.n+1]
|
||||
self.tree[p] = l if self.win(l, r) else r
|
||||
p = p//2
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
s = [4, 1, 6, 7, 9, 5234, 0, 2, 7, 4, 123]
|
||||
t = winnerTree(s)
|
||||
print(t.players,t.tree)
|
||||
print(t.players, t.tree)
|
||||
for i in s:
|
||||
val,idx=t.winner()
|
||||
print(val,idx)
|
||||
t.update(idx,-1)
|
||||
val, idx = t.winner()
|
||||
print(val, idx)
|
||||
t.update(idx, -1)
|
||||
|
||||
|
||||
'''
|
||||
|
|
|
@ -13,123 +13,146 @@ from random import randint
|
|||
from time import time
|
||||
from functools import total_ordering
|
||||
|
||||
|
||||
@total_ordering
|
||||
class point:
|
||||
def __init__(self,x,y):
|
||||
self.x=x
|
||||
self.y=y
|
||||
def __init__(self, x, y):
|
||||
self.x = x
|
||||
self.y = y
|
||||
|
||||
def __neg__(self):
|
||||
return pont(-self.x, -self.y)
|
||||
|
||||
def __len__(self):
|
||||
return self.norm(2)
|
||||
def __lt__(self,p):
|
||||
return self.x<p.x or (self.x==p.x and self.y<p.y)
|
||||
def __eq__(self,p):
|
||||
return self.x==p.x and self.y == p.y
|
||||
|
||||
def __lt__(self, p):
|
||||
return self.x < p.x or (self.x == p.x and self.y < p.y)
|
||||
|
||||
def __eq__(self, p):
|
||||
return self.x == p.x and self.y == p.y
|
||||
|
||||
def __hash__(self):
|
||||
return hash((self.x,self.y))
|
||||
return hash((self.x, self.y))
|
||||
|
||||
def __repr__(self):
|
||||
return 'point({},{})'.format(self.x,self.y)
|
||||
return 'point({},{})'.format(self.x, self.y)
|
||||
|
||||
def __str__(self):
|
||||
return self.__repr__()
|
||||
def norm(self,n=2):
|
||||
if n<=0: return max(abs(self.x),abs(self.y))
|
||||
|
||||
def norm(self, n=2):
|
||||
if n <= 0:
|
||||
return max(abs(self.x), abs(self.y))
|
||||
return (abs(self.x)**n+abs(self.y)**n)**(1/n)
|
||||
def distance(self,p):
|
||||
|
||||
def distance(self, p):
|
||||
return ((self.x-p.x)**2+(self.y-p.y)**2)**0.5
|
||||
|
||||
|
||||
def minDistance_n2(points):
|
||||
n = len(points)
|
||||
if n<=1: return 0
|
||||
p,q=points[:2]
|
||||
if n <= 1:
|
||||
return 0
|
||||
p, q = points[:2]
|
||||
minD = points[0].distance(points[1])
|
||||
for i in range(n-1):
|
||||
for j in range(i+1,n):
|
||||
for j in range(i+1, n):
|
||||
d = points[i].distance(points[j])
|
||||
if d<minD:
|
||||
if d < minD:
|
||||
minD = d
|
||||
p = points[i]
|
||||
q= points[j]
|
||||
return minD, p,q
|
||||
q = points[j]
|
||||
return minD, p, q
|
||||
|
||||
def findif(points, f,reverse = False):
|
||||
|
||||
def findif(points, f, reverse=False):
|
||||
n = len(points)
|
||||
rg = range(n-1,-1,-1) if reverse else range(n)
|
||||
for i in rg:
|
||||
if not f(points[i]):
|
||||
return points[i+1:] if reverse else points[:i]
|
||||
return points.copy() # note that don't return exactly points, return a copy one
|
||||
rg = range(n-1, -1, -1) if reverse else range(n)
|
||||
for i in rg:
|
||||
if not f(points[i]):
|
||||
return points[i+1:] if reverse else points[:i]
|
||||
return points.copy() # note that don't return exactly points, return a copy one
|
||||
|
||||
|
||||
def floatEql(f1, f2, epsilon=1e-6):
|
||||
return abs(f1-f2) < epsilon
|
||||
|
||||
def floatEql(f1,f2,epsilon=1e-6):
|
||||
return abs(f1-f2)<epsilon
|
||||
|
||||
def minDistance_nlogn(n_points):
|
||||
def _min(pts):
|
||||
n = len(pts)
|
||||
if n==2: return pts[0].distance(pts[1]) , pts[0],pts[1]
|
||||
if n==3:
|
||||
if n == 2:
|
||||
return pts[0].distance(pts[1]), pts[0], pts[1]
|
||||
if n == 3:
|
||||
minD = pts[0].distance(pts[1])
|
||||
p,q = pts[0],pts[1]
|
||||
p, q = pts[0], pts[1]
|
||||
d2 = pts[2].distance(pts[1])
|
||||
if minD>d2:
|
||||
if minD > d2:
|
||||
minD = d2
|
||||
p,q = pts[1], pts[2]
|
||||
p, q = pts[1], pts[2]
|
||||
d2 = pts[0].distance(pts[2])
|
||||
if minD>d2: return d2, pts[0],pts[2]
|
||||
else : return minD, p,q
|
||||
if minD > d2:
|
||||
return d2, pts[0], pts[2]
|
||||
else:
|
||||
return minD, p, q
|
||||
n2 = n//2
|
||||
mid = (pts[n2].x +pts[n2-1].x)/2
|
||||
mid = (pts[n2].x + pts[n2-1].x)/2
|
||||
s1 = pts[:n2]
|
||||
s2 = pts[n2:]
|
||||
minD ,p,q = _min(s1)
|
||||
minD, p, q = _min(s1)
|
||||
d2, p2, q2 = _min(s2)
|
||||
#print('\n\n',minD,p,q,s1)
|
||||
#print(d2,p2,q2,s2)
|
||||
if minD> d2:
|
||||
minD,p,q = d2, p2, q2
|
||||
# print('\n\n',minD,p,q,s1)
|
||||
# print(d2,p2,q2,s2)
|
||||
if minD > d2:
|
||||
minD, p, q = d2, p2, q2
|
||||
|
||||
linePoints = findif(s1,lambda pt:floatEql(pt.x,mid),reverse=True)
|
||||
linePoints += findif(s2,lambda pt:floatEql(pt.x,mid))
|
||||
linePoints = findif(s1, lambda pt: floatEql(pt.x, mid), reverse=True)
|
||||
linePoints += findif(s2, lambda pt: floatEql(pt.x, mid))
|
||||
n = len(linePoints)
|
||||
if n>1:
|
||||
for i in range(1,n):
|
||||
dis = linePoints[i].y -linePoints[i-1].y
|
||||
if dis<minD:
|
||||
if n > 1:
|
||||
for i in range(1, n):
|
||||
dis = linePoints[i].y - linePoints[i-1].y
|
||||
if dis < minD:
|
||||
minD = dis
|
||||
p,q = linePoints[i-1], linePoints[i]
|
||||
leftPoints = findif(s1,lambda pt:pt.x>= mid-minD,reverse=True)
|
||||
rightPoints = findif(s2,lambda pt:pt.x<= mid+minD)
|
||||
p, q = linePoints[i-1], linePoints[i]
|
||||
leftPoints = findif(s1, lambda pt: pt.x >= mid-minD, reverse=True)
|
||||
rightPoints = findif(s2, lambda pt: pt.x <= mid+minD)
|
||||
for lp in leftPoints:
|
||||
y1,y2 = lp.y-minD, lp.y+minD
|
||||
y1, y2 = lp.y-minD, lp.y+minD
|
||||
for rp in rightPoints:
|
||||
if y1< rp.y <y2:
|
||||
if y1 < rp.y < y2:
|
||||
dis = lp.distance(rp)
|
||||
if dis< minD:
|
||||
if dis < minD:
|
||||
minD = dis
|
||||
p,q = lp,rp
|
||||
return minD, p,q
|
||||
p, q = lp, rp
|
||||
return minD, p, q
|
||||
return _min(sorted(n_points))
|
||||
|
||||
|
||||
def test(f=minDistance_n2):
|
||||
print('\ntest : ', f.__name__)
|
||||
begin = time()
|
||||
minD, p, q = f(points)
|
||||
print('time : {:.6f} s'.format(time()-begin))
|
||||
print('result: {:.2f} {} {}\n'.format(minD, p,q))
|
||||
print('result: {:.2f} {} {}\n'.format(minD, p, q))
|
||||
|
||||
def genData(n,unique=True):
|
||||
|
||||
def genData(n, unique=True):
|
||||
upper = 1000000
|
||||
if unique:
|
||||
points = set()
|
||||
for i in range(n):
|
||||
points.add(point(randint(1,upper),randint(1,upper)))
|
||||
points.add(point(randint(1, upper), randint(1, upper)))
|
||||
return list(points)
|
||||
else:return [point(randint(1,upper),randint(1,upper)) for i in range(n)]
|
||||
else:
|
||||
return [point(randint(1, upper), randint(1, upper)) for i in range(n)]
|
||||
|
||||
if __name__ =='__main__':
|
||||
|
||||
if __name__ == '__main__':
|
||||
n = 1000
|
||||
points = genData(n, unique=True)
|
||||
print('min distance of {} points'.format(n))
|
||||
#print(sorted(points))
|
||||
# print(sorted(points))
|
||||
test(minDistance_n2)
|
||||
test(minDistance_nlogn)
|
||||
|
|
|
@ -21,12 +21,13 @@ leetcode 1049: https://leetcode-cn.com/problems/last-stone-weight-ii/
|
|||
#######################################################################
|
||||
'''
|
||||
|
||||
|
||||
class Solution:
|
||||
def lastStoneWeightII(self, stones: List[int]) -> int:
|
||||
sm = sum(stones)
|
||||
ans = sm//2
|
||||
dp = [0]*(ans+1)
|
||||
for x in stones:
|
||||
for j in range(ans,x-1,-1):
|
||||
dp[j] = max(dp[j],dp[j-x]+x)
|
||||
for j in range(ans, x-1, -1):
|
||||
dp[j] = max(dp[j], dp[j-x]+x)
|
||||
return sm-2*dp[ans]
|
||||
|
|
|
@ -10,41 +10,44 @@
|
|||
#########################################################################
|
||||
'''
|
||||
|
||||
def lcs(a,b):
|
||||
|
||||
def lcs(a, b):
|
||||
'''time: O(mn); space: O(mn)'''
|
||||
m,n= len(a),len(b)
|
||||
m, n = len(a), len(b)
|
||||
board = [[[] for i in range(n+1)] for i in range(m+1)]
|
||||
for i in range(m):
|
||||
for j in range(n):
|
||||
if a[i]==b[j]:
|
||||
board[i+1][j+1] =board[i][j]+[a[i]]
|
||||
if a[i] == b[j]:
|
||||
board[i+1][j+1] = board[i][j]+[a[i]]
|
||||
elif len(board[i][j+1]) < len(board[i+1][j]):
|
||||
board[i+1][j+1] = board[i+1][j]
|
||||
else :
|
||||
else:
|
||||
board[i+1][j+1] = board[i][1+j]
|
||||
return board[m][n]
|
||||
|
||||
def lcs2(a,b):
|
||||
|
||||
def lcs2(a, b):
|
||||
'''time: O(mn); space: O(m)'''
|
||||
m,n= len(a),len(b)
|
||||
m, n = len(a), len(b)
|
||||
board = [[] for i in range(n+1)]
|
||||
for i in range(m):
|
||||
upperLevel = board[0].copy()
|
||||
for j in range(n):
|
||||
tmp = board[j+1].copy()
|
||||
if a[i]==b[j]:
|
||||
if a[i] == b[j]:
|
||||
board[j+1] = upperLevel+[a[i]]
|
||||
elif len(board[j+1]) < len(board[j]):
|
||||
board[j+1] = board[j].copy() # copy is needed
|
||||
board[j+1] = board[j].copy() # copy is needed
|
||||
upperLevel = tmp
|
||||
return board[n]
|
||||
|
||||
if __name__ =='__main__':
|
||||
|
||||
if __name__ == '__main__':
|
||||
a = 'ABCBDAB'
|
||||
b = 'BDCABA'
|
||||
print('s1:',a)
|
||||
print('s2:',b)
|
||||
print('s1:', a)
|
||||
print('s2:', b)
|
||||
while 1:
|
||||
print('lcs:',lcs2(a,b))
|
||||
print('lcs:', lcs2(a, b))
|
||||
a = input('s1: ')
|
||||
b = input('s2: ')
|
||||
|
|
|
@ -11,11 +11,13 @@
|
|||
给两个整数数组 A 和 B ,返回两个数组中公共的、长度最长的子数组的长度。
|
||||
#######################################################################
|
||||
'''
|
||||
def findLength(A,B):
|
||||
n,m = len(A),len(B)
|
||||
|
||||
|
||||
def findLength(A, B):
|
||||
n, m = len(A), len(B)
|
||||
dp = [[0]*(m+1) for i in range(n+1)]
|
||||
for i in range(1,n+1):
|
||||
for j in range(1,m+1):
|
||||
if A[i-1]==B[j-1]:
|
||||
dp[i][j]=dp[i-1][j-1]+1
|
||||
for i in range(1, n+1):
|
||||
for j in range(1, m+1):
|
||||
if A[i-1] == B[j-1]:
|
||||
dp[i][j] = dp[i-1][j-1]+1
|
||||
return max(max(row) for row in dp)
|
||||
|
|
|
@ -16,33 +16,36 @@
|
|||
then find the maximum price to split the stripe in different shorter stripes
|
||||
( including the original length if possible)
|
||||
'''
|
||||
|
||||
def count(n,prices):
|
||||
def best(cur):
|
||||
|
||||
|
||||
def count(n, prices):
|
||||
def best(cur):
|
||||
# note that copying the list or create a new list in the following new_stripes codes
|
||||
if cur in values: return values[cur],stripes[cur]
|
||||
if cur in values:
|
||||
return values[cur], stripes[cur]
|
||||
maxPrice = 0
|
||||
new_stripes=[]
|
||||
for i,j in prices.items():
|
||||
if i<=cur:
|
||||
new_stripes = []
|
||||
for i, j in prices.items():
|
||||
if i <= cur:
|
||||
p, tmp = best(cur-i)
|
||||
if maxPrice<p+j:
|
||||
new_stripes = tmp+[i] # if the list is not copyed, create a new list, don't use append
|
||||
maxPrice =p+j
|
||||
if maxPrice < p+j:
|
||||
# if the list is not copyed, create a new list, don't use append
|
||||
new_stripes = tmp+[i]
|
||||
maxPrice = p+j
|
||||
values[cur] = maxPrice
|
||||
stripes[cur] = new_stripes
|
||||
return maxPrice,new_stripes
|
||||
values = {0:0}
|
||||
stripes = {0:[]}
|
||||
return maxPrice, new_stripes
|
||||
values = {0: 0}
|
||||
stripes = {0: []}
|
||||
return best(n)
|
||||
|
||||
|
||||
|
||||
if __name__=='__main__':
|
||||
li = [(1,1),(2,5),(3,8),(4,9),(5,10),(6,17),(7,17),(8,20),(9,24),(10,30)]
|
||||
prices = {i:j for i,j in li}
|
||||
if __name__ == '__main__':
|
||||
li = [(1, 1), (2, 5), (3, 8), (4, 9), (5, 10),
|
||||
(6, 17), (7, 17), (8, 20), (9, 24), (10, 30)]
|
||||
prices = {i: j for i, j in li}
|
||||
n = 40
|
||||
|
||||
d = {i:count(i,prices) for i in range(n+1)}
|
||||
d = {i: count(i, prices) for i in range(n+1)}
|
||||
for i in range(n+1):
|
||||
print(i,d[i])
|
||||
print(i, d[i])
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#coding: utf-8
|
||||
# coding: utf-8
|
||||
''' mbinary
|
||||
#######################################################################
|
||||
# File : stoneGame.py
|
||||
|
@ -14,6 +14,8 @@
|
|||
leetcode-cn 877: https://leetcode-cn.com/problems/stone-game/
|
||||
#######################################################################
|
||||
'''
|
||||
|
||||
|
||||
def stoneGame(li):
|
||||
'''li: list, len(li)%2==0, sum(li)%2==1'''
|
||||
def f(p,q):
|
||||
|
@ -29,7 +31,7 @@ def stoneGame(li):
|
|||
n2 = li[q] + min(-li[p]+f(p+1,q-1),-li[q-1]+f(p,q-2))
|
||||
ret = max(n1,n2)
|
||||
dp[p][q] = ret
|
||||
#print(li[p:q+1],ret)
|
||||
# print(li[p:q+1],ret)
|
||||
return ret
|
||||
n = len(li)
|
||||
dp = [[None for i in range(n)] for i in range(n)]
|
||||
|
|
|
@ -9,18 +9,23 @@
|
|||
# Description:
|
||||
#########################################################################
|
||||
*/
|
||||
class Solution {
|
||||
class Solution
|
||||
{
|
||||
public:
|
||||
map<Node*,Node*> st;
|
||||
Node *cloneGraph(Node *node){
|
||||
Node* ret = new Node(node->val,vector<Node*>());
|
||||
st[node]=ret;
|
||||
for(auto x:node->neighbors){
|
||||
map<Node*, Node*> st;
|
||||
Node *cloneGraph(Node *node)
|
||||
{
|
||||
Node* ret = new Node(node->val, vector<Node*>());
|
||||
st[node] = ret;
|
||||
|
||||
for (auto x : node->neighbors) {
|
||||
auto p = st.find(x);
|
||||
if(p==st.end()){
|
||||
|
||||
if (p == st.end()) {
|
||||
ret->neighbors.push_back(cloneGraph(x));
|
||||
}else ret->neighbors.push_back(p->second);
|
||||
} else ret->neighbors.push_back(p->second);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
|
38
graph/dfs.py
38
graph/dfs.py
|
@ -20,36 +20,37 @@
|
|||
#######################################################################
|
||||
'''
|
||||
|
||||
|
||||
class Solution:
|
||||
def longestStrChain(self, words: List[str]) -> int:
|
||||
def isAdj(s1,s2):
|
||||
if len(s1)>len(s2):
|
||||
s1,s2 = s2,s1
|
||||
n1,n2 = len(s1),len(s2)
|
||||
if n2-n1!=1:
|
||||
def isAdj(s1, s2):
|
||||
if len(s1) > len(s2):
|
||||
s1, s2 = s2, s1
|
||||
n1, n2 = len(s1), len(s2)
|
||||
if n2-n1 != 1:
|
||||
return False
|
||||
i=j=0
|
||||
i = j = 0
|
||||
flag = False
|
||||
while i<n1 and j<n2:
|
||||
if s1[i]!=s2[j]:
|
||||
while i < n1 and j < n2:
|
||||
if s1[i] != s2[j]:
|
||||
if flag:
|
||||
return False
|
||||
flag = True
|
||||
j+=1
|
||||
j += 1
|
||||
else:
|
||||
i+=1
|
||||
j+=1
|
||||
i += 1
|
||||
j += 1
|
||||
return True
|
||||
|
||||
|
||||
def dfs(begin):
|
||||
ans = 1
|
||||
w = words[begin]
|
||||
n = len(w)
|
||||
if n+1 in lenDic:
|
||||
for nd in lenDic[n+1]:
|
||||
#print(w,words[nd],isAdj(w,words[nd]))
|
||||
if isAdj(w,words[nd]):
|
||||
ans = max(ans,1+dfs(nd))
|
||||
# print(w,words[nd],isAdj(w,words[nd]))
|
||||
if isAdj(w, words[nd]):
|
||||
ans = max(ans, 1+dfs(nd))
|
||||
return ans
|
||||
lenDic = {}
|
||||
for i in range(len(words)):
|
||||
|
@ -57,14 +58,13 @@ class Solution:
|
|||
if n in lenDic:
|
||||
lenDic[n].add(i)
|
||||
else:
|
||||
lenDic[n]={i}
|
||||
|
||||
lenDic[n] = {i}
|
||||
|
||||
lens = sorted(lenDic)
|
||||
n = len(lens)
|
||||
ans = 0
|
||||
for i in range(n):
|
||||
if ans < n-i:
|
||||
for nd in lenDic[lens[i]]:
|
||||
ans = max(ans,dfs(nd))
|
||||
ans = max(ans, dfs(nd))
|
||||
return ans
|
||||
|
||||
|
|
|
@ -21,10 +21,13 @@ def isBipartite(self, graph):
|
|||
"""
|
||||
n = len(graph)
|
||||
self.node = graph
|
||||
self.color = {i:None for i in range(n)}
|
||||
return all(self.dfs(i,True) for i in range(n) if self.color[i] is None)
|
||||
def dfs(self,n,col=True):
|
||||
self.color = {i: None for i in range(n)}
|
||||
return all(self.dfs(i, True) for i in range(n) if self.color[i] is None)
|
||||
|
||||
|
||||
def dfs(self, n, col=True):
|
||||
if self.color[n] is None:
|
||||
self.color[n]=col
|
||||
return all(self.dfs(i,not col) for i in self.node[n])
|
||||
else:return col==self.color[n]
|
||||
self.color[n] = col
|
||||
return all(self.dfs(i, not col) for i in self.node[n])
|
||||
else:
|
||||
return col == self.color[n]
|
||||
|
|
|
@ -54,7 +54,7 @@ def _fft2(a, invert=False):
|
|||
N = len(a)
|
||||
if N & (N - 1) == 0: # O(nlogn), 2^k
|
||||
r = int(np.log(N))
|
||||
c = np.array(a,dtype='complex')
|
||||
c = np.array(a, dtype='complex')
|
||||
i = 2j if invert else -2j
|
||||
w = np.exp(i * np.pi / N)
|
||||
for h in range(r - 1, -1, -1):
|
||||
|
|
|
@ -11,21 +11,23 @@
|
|||
#######################################################################
|
||||
'''
|
||||
|
||||
def fastPow(a,n):
|
||||
|
||||
def fastPow(a, n):
|
||||
'''a^n'''
|
||||
rst = 1
|
||||
while n:
|
||||
if n%2:
|
||||
rst *=a
|
||||
n>>=1
|
||||
a*=a
|
||||
if n % 2:
|
||||
rst *= a
|
||||
n >>= 1
|
||||
a *= a
|
||||
return rst
|
||||
|
||||
def fastMul(a,b):
|
||||
|
||||
def fastMul(a, b):
|
||||
'''a*b'''
|
||||
rst = 0
|
||||
while b:
|
||||
if b&1:
|
||||
rst +=a
|
||||
b>>=1
|
||||
a*=2
|
||||
if b & 1:
|
||||
rst += a
|
||||
b >>= 1
|
||||
a *= 2
|
||||
|
|
|
@ -11,27 +11,31 @@
|
|||
#######################################################################
|
||||
'''
|
||||
|
||||
|
||||
def fib(n):
|
||||
"""Calculates the nth Fibonacci number"""
|
||||
mat,p = (1,1,1,0),n-2
|
||||
if n<=0: # for negative fib item, use f(n) = f(n+2)-f(n-1) to calculate
|
||||
mat = (0,1,1,-1),2-n
|
||||
li = matrix_pow((0,1,1,-1),1-n)
|
||||
return li[0]+li[1]
|
||||
def matrix_pow(mat,n):
|
||||
ans = (1,0,0,1) # element matrix
|
||||
while n>0:
|
||||
if n%2==1:
|
||||
ans = matrix_mul(ans,mat)
|
||||
n>>=1
|
||||
mat = matrix_mul(mat,mat)
|
||||
"""Calculates the nth Fibonacci number"""
|
||||
mat, p = (1, 1, 1, 0), n-2
|
||||
if n <= 0: # for negative fib item, use f(n) = f(n+2)-f(n-1) to calculate
|
||||
mat = (0, 1, 1, -1), 2-n
|
||||
li = matrix_pow((0, 1, 1, -1), 1-n)
|
||||
return li[0]+li[1]
|
||||
|
||||
|
||||
def matrix_pow(mat, n):
|
||||
ans = (1, 0, 0, 1) # element matrix
|
||||
while n > 0:
|
||||
if n % 2 == 1:
|
||||
ans = matrix_mul(ans, mat)
|
||||
n >>= 1
|
||||
mat = matrix_mul(mat, mat)
|
||||
return ans
|
||||
|
||||
def matrix_mul(a,b):
|
||||
|
||||
def matrix_mul(a, b):
|
||||
'''a,b are four-item tuple, represent matrix [[a[0],a[1]],[a[2],a[3]]]'''
|
||||
return a[0]*b[0]+a[1]*b[2], a[0]*b[1]+a[1]*b[3], a[2]*b[0]+a[3]*b[2],a[2]*b[1]+a[3]*b[3]
|
||||
return a[0]*b[0]+a[1]*b[2], a[0]*b[1]+a[1]*b[3], a[2]*b[0]+a[3]*b[2], a[2]*b[1]+a[3]*b[3]
|
||||
|
||||
|
||||
if __name__=='__main__':
|
||||
for i in range(-5,5):
|
||||
print(i,fib(i))
|
||||
if __name__ == '__main__':
|
||||
for i in range(-5, 5):
|
||||
print(i, fib(i))
|
||||
|
|
|
@ -23,6 +23,7 @@ eg
|
|||
'''
|
||||
from nega import nega
|
||||
|
||||
|
||||
def addNegaBin(arr1: list, arr2: list) -> list:
|
||||
if len(arr1) < len(arr2):
|
||||
arr1, arr2 = arr2, arr1
|
||||
|
@ -42,19 +43,20 @@ def addNegaBin(arr1: list, arr2: list) -> list:
|
|||
|
||||
elif arr1[i] == 0 and arr2[i] == 1:
|
||||
arr1[i] = arr2[i]
|
||||
#print(arr1,arr2,i)
|
||||
# print(arr1,arr2,i)
|
||||
while len(arr1) > 1 and arr1[0] == 0:
|
||||
arr1.pop(0)
|
||||
return arr1
|
||||
|
||||
if __name__=='__main__':
|
||||
|
||||
if __name__ == '__main__':
|
||||
while 1:
|
||||
print("input q to quit or input x1 x2: ")
|
||||
s = input()
|
||||
if s=='q':
|
||||
if s == 'q':
|
||||
break
|
||||
n1,n2 =[int(i) for i in s.split()]
|
||||
l1,l2 = nega(n1),nega(n2)
|
||||
print(n1,l1)
|
||||
print(n2,l2)
|
||||
n1, n2 = [int(i) for i in s.split()]
|
||||
l1, l2 = nega(n1), nega(n2)
|
||||
print(n1, l1)
|
||||
print(n2, l2)
|
||||
print(f'{n1}+{n2}={n1+n2}: {addNegaBin(l1,l2)}')
|
||||
|
|
|
@ -10,34 +10,37 @@
|
|||
#########################################################################
|
||||
'''
|
||||
|
||||
def covert(s,basefrom=10,baseto=2):
|
||||
return d2n(n2d(s,basefrom),baseto)
|
||||
def n2d(s,base=16):
|
||||
|
||||
def covert(s, basefrom=10, baseto=2):
|
||||
return d2n(n2d(s, basefrom), baseto)
|
||||
|
||||
|
||||
def n2d(s, base=16):
|
||||
''' num of base_n(n<36) to decimal'''
|
||||
dic = {chr(i+ord('0')):i for i in range(10)}
|
||||
s=s.upper()
|
||||
if base>10:
|
||||
dic.update({chr(i+ord('A')):i+10 for i in range(26)})
|
||||
#if base in [16,8,2] :
|
||||
dic = {chr(i+ord('0')): i for i in range(10)}
|
||||
s = s.upper()
|
||||
if base > 10:
|
||||
dic.update({chr(i+ord('A')): i+10 for i in range(26)})
|
||||
# if base in [16,8,2] :
|
||||
# p=max(map(s.find,'OBX'))
|
||||
# s=s[p+1:] #remove prefix of hex or bin or oct
|
||||
rst=0
|
||||
rst = 0
|
||||
for i in s:
|
||||
rst=dic[i]+rst*base
|
||||
rst = dic[i]+rst*base
|
||||
return rst
|
||||
|
||||
def d2n(n,base=16):
|
||||
''' num of base_n(n<36) to decimal'''
|
||||
dic = {i:chr(i+ord('0')) for i in range(10)}
|
||||
if base>10:
|
||||
dic.update({i+10:chr(i+ord('A')) for i in range(26)})
|
||||
rst=[]
|
||||
while n!=0:
|
||||
i=int(n/base)
|
||||
rst.append(dic[n-i*base])
|
||||
n=i
|
||||
return ''.join(rst[::-1])
|
||||
|
||||
def d2n(n, base=16):
|
||||
''' num of base_n(n<36) to decimal'''
|
||||
dic = {i: chr(i+ord('0')) for i in range(10)}
|
||||
if base > 10:
|
||||
dic.update({i+10: chr(i+ord('A')) for i in range(26)})
|
||||
rst = []
|
||||
while n != 0:
|
||||
i = int(n/base)
|
||||
rst.append(dic[n-i*base])
|
||||
n = i
|
||||
return ''.join(rst[::-1])
|
||||
|
||||
|
||||
'''
|
||||
|
|
|
@ -9,15 +9,18 @@
|
|||
# Description:
|
||||
#########################################################################
|
||||
'''
|
||||
def nega(n:int,base=-2:int)->:list:
|
||||
|
||||
|
||||
def nega(n: int, base=-2: int)->: list:
|
||||
'''return list of num, the first is the highest digit'''
|
||||
if base>-2:
|
||||
raise Exception(f"[Error]: invalid base: {base}, base should be no more than -2")
|
||||
if base > -2:
|
||||
raise Exception(
|
||||
f"[Error]: invalid base: {base}, base should be no more than -2")
|
||||
ans = []
|
||||
while n:
|
||||
k = n%base
|
||||
if k<0:
|
||||
k-=base
|
||||
k = n % base
|
||||
if k < 0:
|
||||
k -= base
|
||||
ans.append(k)
|
||||
n = (n-k)//base
|
||||
return ans[::-1]
|
||||
|
|
|
@ -17,17 +17,20 @@ from factor import factor
|
|||
from collections import Counter
|
||||
from functools import reduce
|
||||
from operator import mul
|
||||
|
||||
|
||||
def phi(n):
|
||||
st = set(factor(n))
|
||||
return round(reduce(mul,(1-1/p for p in st),n))
|
||||
st = set(factor(n))
|
||||
return round(reduce(mul, (1-1/p for p in st), n))
|
||||
|
||||
|
||||
def sigma(n):
|
||||
ct = Counter(factor(n))
|
||||
return reduce(mul,(round((p**(ct[p]+1)-1)/(p-1)) for p in ct),1)
|
||||
return reduce(mul, (round((p**(ct[p]+1)-1)/(p-1)) for p in ct), 1)
|
||||
|
||||
if __name__=='__main__':
|
||||
|
||||
if __name__ == '__main__':
|
||||
while 1:
|
||||
n = int(input('n: '))
|
||||
print('phi(n):',phi(n))
|
||||
print('sigma(n):',sigma(n))
|
||||
|
||||
print('phi(n):', phi(n))
|
||||
print('sigma(n):', sigma(n))
|
||||
|
|
|
@ -13,41 +13,49 @@
|
|||
|
||||
from random import randint
|
||||
from isPrime import isPrime
|
||||
from gcd import gcd
|
||||
from gcd import gcd
|
||||
|
||||
|
||||
def factor(n):
|
||||
'''pollard's rho algorithm'''
|
||||
if n<1:raise Exception('[Error]: {} is less than 1'.format(n))
|
||||
if n==1: return []
|
||||
if isPrime(n):return [n]
|
||||
fact=1
|
||||
cycle_size=2
|
||||
if n < 1:
|
||||
raise Exception('[Error]: {} is less than 1'.format(n))
|
||||
if n == 1:
|
||||
return []
|
||||
if isPrime(n):
|
||||
return [n]
|
||||
fact = 1
|
||||
cycle_size = 2
|
||||
x = x_fixed = 2
|
||||
c = randint(1,n)
|
||||
while fact==1:
|
||||
c = randint(1, n)
|
||||
while fact == 1:
|
||||
for i in range(cycle_size):
|
||||
if fact>1:break
|
||||
x=(x*x+c)%n
|
||||
if x==x_fixed:
|
||||
c = randint(1,n)
|
||||
if fact > 1:
|
||||
break
|
||||
x = (x*x+c) % n
|
||||
if x == x_fixed:
|
||||
c = randint(1, n)
|
||||
continue
|
||||
fact = gcd(x-x_fixed,n)
|
||||
cycle_size *=2
|
||||
fact = gcd(x-x_fixed, n)
|
||||
cycle_size *= 2
|
||||
x_fixed = x
|
||||
return factor(fact)+factor(n//fact)
|
||||
|
||||
|
||||
def fact(n):
|
||||
f=2
|
||||
f = 2
|
||||
ret = []
|
||||
while f*f<=n:
|
||||
while not n%f:
|
||||
while f*f <= n:
|
||||
while not n % f:
|
||||
ret.append(f)
|
||||
n//f
|
||||
f+=1
|
||||
if n>1:ret.append(n)
|
||||
f += 1
|
||||
if n > 1:
|
||||
ret.append(n)
|
||||
return ret
|
||||
|
||||
|
||||
if __name__=='__main__':
|
||||
if __name__ == '__main__':
|
||||
while 1:
|
||||
n = int(input('n: '))
|
||||
print(factor(n))
|
||||
|
|
|
@ -11,23 +11,28 @@
|
|||
#######################################################################
|
||||
'''
|
||||
|
||||
def gcd(a,b):
|
||||
while b!=0:
|
||||
a,b=b,a%b
|
||||
|
||||
def gcd(a, b):
|
||||
while b != 0:
|
||||
a, b = b, a % b
|
||||
return a
|
||||
|
||||
def lcm(a,b):
|
||||
return int(a*b/gcd(a,b))
|
||||
def xgcd(a,b):
|
||||
'''return gcd(a,b), x,y where ax+by=gcd(a,b)'''
|
||||
if b==0:return a,1,0
|
||||
g,x,y = xgcd(b,a%b)
|
||||
return g,y,x-a//b*y
|
||||
|
||||
if __name__=='__main__':
|
||||
def lcm(a, b):
|
||||
return int(a*b/gcd(a, b))
|
||||
|
||||
|
||||
def xgcd(a, b):
|
||||
'''return gcd(a,b), x,y where ax+by=gcd(a,b)'''
|
||||
if b == 0:
|
||||
return a, 1, 0
|
||||
g, x, y = xgcd(b, a % b)
|
||||
return g, y, x-a//b*y
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
while 1:
|
||||
a = int(input('a: '))
|
||||
b = int(input('b: '))
|
||||
print('gcd :',gcd(a,b))
|
||||
print('xgcd:',xgcd(a,b))
|
||||
|
||||
print('gcd :', gcd(a, b))
|
||||
print('xgcd:', xgcd(a, b))
|
||||
|
|
|
@ -13,48 +13,51 @@
|
|||
#######################################################################
|
||||
'''
|
||||
|
||||
def hammingDistance(a,b):
|
||||
if isinstance(a,int):
|
||||
n = a^b
|
||||
|
||||
def hammingDistance(a, b):
|
||||
if isinstance(a, int):
|
||||
n = a ^ b
|
||||
ct = 0
|
||||
while n:
|
||||
ct+=n%2
|
||||
n>>=1
|
||||
ct += n % 2
|
||||
n >>= 1
|
||||
return ct
|
||||
else:
|
||||
n,m = len(a),len(b)
|
||||
n, m = len(a), len(b)
|
||||
ret = 0
|
||||
for i,j in zip(a,b):
|
||||
ret+= i==j
|
||||
for i, j in zip(a, b):
|
||||
ret += i == j
|
||||
return ret+abs(n-m)
|
||||
|
||||
|
||||
def totalHammingDistance(lst):
|
||||
'''return sum of any two items(num or lst( str)) in lst'''
|
||||
length = len(lst)
|
||||
if length ==0:return 0
|
||||
if isinstance(lst[0],int):
|
||||
length = len(lst)
|
||||
if length == 0:
|
||||
return 0
|
||||
if isinstance(lst[0], int):
|
||||
bits = [0] * len(bin(max(lst)))
|
||||
for n in lst:
|
||||
ct = 0
|
||||
while n:
|
||||
if n%2==1:
|
||||
bits[ct]+=1
|
||||
ct+=1
|
||||
n>>=1
|
||||
if n % 2 == 1:
|
||||
bits[ct] += 1
|
||||
ct += 1
|
||||
n >>= 1
|
||||
return sum(i*(length-i) for i in bits)
|
||||
else:
|
||||
mx = len(max(lst,key=len))
|
||||
mx = len(max(lst, key=len))
|
||||
position = [dict() for i in range(mx)]
|
||||
for li in lst:
|
||||
for i,x in enumerate(li):
|
||||
for i, x in enumerate(li):
|
||||
if x in position[i]:
|
||||
position[i][x] +=1
|
||||
position[i][x] += 1
|
||||
else:
|
||||
position[i][x] =1
|
||||
position[i][x] = 1
|
||||
ret = 0
|
||||
for dic in position:
|
||||
left = length
|
||||
for i in dic.values():
|
||||
ret+=i*(left-i) # key step
|
||||
left -=i # key step
|
||||
ret += i*(left-i) # key step
|
||||
left -= i # key step
|
||||
return ret
|
||||
|
|
|
@ -12,56 +12,61 @@
|
|||
from random import randint
|
||||
|
||||
|
||||
def quickMulMod(a,b,m):
|
||||
def quickMulMod(a, b, m):
|
||||
'''a*b%m, quick'''
|
||||
ret = 0
|
||||
while b:
|
||||
if b&1:
|
||||
ret = (a+ret)%m
|
||||
b//=2
|
||||
a = (a+a)%m
|
||||
if b & 1:
|
||||
ret = (a+ret) % m
|
||||
b //= 2
|
||||
a = (a+a) % m
|
||||
return ret
|
||||
|
||||
def quickPowMod(a,b,m):
|
||||
|
||||
def quickPowMod(a, b, m):
|
||||
'''a^b %m, quick, O(logn)'''
|
||||
ret =1
|
||||
ret = 1
|
||||
while b:
|
||||
if b&1:
|
||||
ret =quickMulMod(ret,a,m)
|
||||
b//=2
|
||||
a = quickMulMod(a,a,m)
|
||||
if b & 1:
|
||||
ret = quickMulMod(ret, a, m)
|
||||
b //= 2
|
||||
a = quickMulMod(a, a, m)
|
||||
return ret
|
||||
|
||||
|
||||
def isPrime(n,t=5):
|
||||
def isPrime(n, t=5):
|
||||
'''miller rabin primality test, a probability result
|
||||
t is the number of iteration(witness)
|
||||
'''
|
||||
t = min(n-3,t)
|
||||
if n<2:
|
||||
t = min(n-3, t)
|
||||
if n < 2:
|
||||
print('[Error]: {} can\'t be classed with prime or composite'.format(n))
|
||||
return
|
||||
if n==2: return True
|
||||
if n == 2:
|
||||
return True
|
||||
d = n-1
|
||||
r = 0
|
||||
while d%2==0:
|
||||
r+=1
|
||||
d//=2
|
||||
tested=set()
|
||||
while d % 2 == 0:
|
||||
r += 1
|
||||
d //= 2
|
||||
tested = set()
|
||||
for i in range(t):
|
||||
a = randint(2,n-2)
|
||||
a = randint(2, n-2)
|
||||
while a in tested:
|
||||
a = randint(2,n-2)
|
||||
a = randint(2, n-2)
|
||||
tested.add(a)
|
||||
x= quickPowMod(a,d,n)
|
||||
if x==1 or x==n-1: continue #success,
|
||||
x = quickPowMod(a, d, n)
|
||||
if x == 1 or x == n-1:
|
||||
continue # success,
|
||||
for j in range(r-1):
|
||||
x= quickMulMod(x,x,n)
|
||||
if x==n-1:break
|
||||
x = quickMulMod(x, x, n)
|
||||
if x == n-1:
|
||||
break
|
||||
else:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
'''
|
||||
we shouldn't use Fermat's little theory
|
||||
Namyly:
|
||||
|
@ -73,49 +78,23 @@ The inverse theorem of it is not True.
|
|||
a counter-example: 2^340 \equiv 1 (mod 341), but 341 is a composite
|
||||
'''
|
||||
|
||||
class primeSieve:
|
||||
'''sieve of Eratosthenes, It will be more efficient when judging many times'''
|
||||
primes = [2,3,5,7,11,13]
|
||||
def isPrime(self,x):
|
||||
if x<=primes[-1]:
|
||||
return twoDivideFind(x,self.primes)
|
||||
while x>self.primes[-1]:
|
||||
left = self.primes[-1]
|
||||
right = (left+1)**2
|
||||
lst = []
|
||||
for i in range(left,right):
|
||||
for j in self.primes:
|
||||
if i%j==0:break
|
||||
else:lst.append(i)
|
||||
self.primes+=lst
|
||||
return twoDivideFind(x,lst)
|
||||
def nPrime(n):
|
||||
'''return the n-th prime'''
|
||||
i=n-len(self.primes)
|
||||
last = self.primes[-1]
|
||||
for _ in range(i):
|
||||
while 1:
|
||||
last +=2
|
||||
for p in self.primes:
|
||||
if last%p==0:
|
||||
break
|
||||
else:
|
||||
self.primes.append(last)
|
||||
break
|
||||
return self.primes[n-1]
|
||||
|
||||
def twoDivideFind(x,li):
|
||||
a,b = 0, len(li)
|
||||
while a<=b:
|
||||
def twoDivideFind(x, li):
|
||||
a, b = 0, len(li)
|
||||
while a <= b:
|
||||
mid = (a+b)//2
|
||||
if li[mid]<x:a=mid+1
|
||||
elif li[mid]>x: b= mid-1
|
||||
else:return mid
|
||||
if li[mid] < x:
|
||||
a = mid+1
|
||||
elif li[mid] > x:
|
||||
b = mid-1
|
||||
else:
|
||||
return mid
|
||||
return -1
|
||||
|
||||
if __name__=='__main__':
|
||||
|
||||
if __name__ == '__main__':
|
||||
n = 100
|
||||
print('prime numbers below',n)
|
||||
print('prime numbers below', n)
|
||||
print([i for i in range(n) if isPrime(i)])
|
||||
while 1:
|
||||
n = int(input('n: '))
|
||||
|
|
|
@ -18,110 +18,124 @@ from euler import phi
|
|||
from isPrime import isPrime
|
||||
from factor import factor
|
||||
|
||||
def ind(m,g):
|
||||
''' mod m ,primary root g -> {n:indg n}'''
|
||||
return {j:i for i in range(m-1) \
|
||||
for j in range(m) if (g**i-j)%m==0}
|
||||
|
||||
def gs(m,num=100):
|
||||
'''return list of m's primary roots below num'''
|
||||
def ind(m, g):
|
||||
''' mod m ,primary root g -> {n:indg n}'''
|
||||
return {j: i for i in range(m-1)
|
||||
for j in range(m) if (g**i-j) % m == 0}
|
||||
|
||||
|
||||
def gs(m, num=100):
|
||||
'''return list of m's primary roots below num'''
|
||||
p = phi(m)
|
||||
mp = factor(p)
|
||||
checkLst = [p//i for i in mp]
|
||||
return [i for i in range(2,num) if all((i**n-1)%m !=0 for n in checkLst)]
|
||||
return [i for i in range(2, num) if all((i**n-1) % m != 0 for n in checkLst)]
|
||||
|
||||
|
||||
def minG(m):
|
||||
p = phi(m)
|
||||
mp = factor(p)
|
||||
checkLst = [p//i for i in mp]
|
||||
i=2
|
||||
while 1:
|
||||
if all((i**n-1)%m !=0 for n in checkLst):return i
|
||||
i+=1
|
||||
i = 2
|
||||
while 1:
|
||||
if all((i**n-1) % m != 0 for n in checkLst):
|
||||
return i
|
||||
i += 1
|
||||
|
||||
|
||||
class solve:
|
||||
def __init__(self,equ=None):
|
||||
self.linearPat= re.compile(r'\s*(\d+)\s*--\s*(\d+)[\s\(]*mod\s*(\d+)')
|
||||
self.sol = []
|
||||
def __init__(self, equ=None):
|
||||
self.linearPat = re.compile(r'\s*(\d+)\s*--\s*(\d+)[\s\(]*mod\s*(\d+)')
|
||||
self.sol = []
|
||||
#self.m = m
|
||||
#self.ind_mp = ind(m,minG(m))
|
||||
|
||||
def noSol(self):
|
||||
print('equation {equ} has no solution'.format(equ=self.equ))
|
||||
|
||||
def error(self):
|
||||
print("Error! The divisor m must be postive integer")
|
||||
def solveLinear(self,a,b,m):
|
||||
|
||||
def solveLinear(self, a, b, m):
|
||||
'''ax--b(mod m): solve linear equation with one unknown
|
||||
return ([x1,x2,...],m)
|
||||
'''
|
||||
a,b,m = self.check(a,b,m)
|
||||
g,x,y=xgcd(a,m)
|
||||
if a*b%g!=0:
|
||||
a, b, m = self.check(a, b, m)
|
||||
g, x, y = xgcd(a, m)
|
||||
if a*b % g != 0:
|
||||
self.noSol()
|
||||
return None
|
||||
sol=x*b//g
|
||||
sol = x*b//g
|
||||
m0 = m//g
|
||||
sols = [(sol+i*m0)%m for i in range(g)]
|
||||
print('{}x--{}(mod {}), solution: {} mod {}'.format(a,b,m,sols,m))
|
||||
return (sols,m)
|
||||
def check(self,a,b,m):
|
||||
if m<=0:
|
||||
sols = [(sol+i*m0) % m for i in range(g)]
|
||||
print('{}x--{}(mod {}), solution: {} mod {}'.format(a, b, m, sols, m))
|
||||
return (sols, m)
|
||||
|
||||
def check(self, a, b, m):
|
||||
if m <= 0:
|
||||
self.error()
|
||||
return None
|
||||
if a<0:a,b=-a,-b ## important
|
||||
if b<0:b+= -b//m * m
|
||||
return a,b,m
|
||||
if a < 0:
|
||||
a, b = -a, -b # important
|
||||
if b < 0:
|
||||
b += -b//m * m
|
||||
return a, b, m
|
||||
|
||||
def solveHigh(self,a,n,b,m):
|
||||
def solveHigh(self, a, n, b, m):
|
||||
''' ax^n -- b (mod m) ind_mp is a dict of m's {n: indg n}'''
|
||||
ind_mp = ind(m,minG(m))
|
||||
ind_mp = ind(m, minG(m))
|
||||
tmp = ind_mp[b] - ind_mp[a]
|
||||
if tmp < 0:tmp+=m
|
||||
sol = self.solveLinear(n,tmp,phi(m))
|
||||
re_mp = {j:i for i ,j in ind_mp.items()}
|
||||
if tmp < 0:
|
||||
tmp += m
|
||||
sol = self.solveLinear(n, tmp, phi(m))
|
||||
re_mp = {j: i for i, j in ind_mp.items()}
|
||||
sols = [re_mp[i] for i in sol[0]]
|
||||
print('{}x^{}--{}(mod {}), solution: {} mod {}'.format(a,n,b,m,sols,m))
|
||||
return sols,m
|
||||
print('{}x^{}--{}(mod {}), solution: {} mod {}'.format(a, n, b, m, sols, m))
|
||||
return sols, m
|
||||
|
||||
def solveGroup(self,tups):
|
||||
def solveGroup(self, tups):
|
||||
'''tups is a list of tongyu equation groups, like
|
||||
[(a1,b1,m1),(a2,b2,m2)...]
|
||||
and, m1,m2... are all primes
|
||||
'''
|
||||
mp = {}
|
||||
print('solving group of equations: ')
|
||||
for a,b,m in tups:
|
||||
print('{}x--{}(mod {})'.format(a,b,m))
|
||||
for a, b, m in tups:
|
||||
print('{}x--{}(mod {})'.format(a, b, m))
|
||||
if m in mp:
|
||||
if mp[m][0]*b!=mp[m][1]*a:
|
||||
if mp[m][0]*b != mp[m][1]*a:
|
||||
self.noSol()
|
||||
return
|
||||
else:mp[m] = (a,b)
|
||||
else:
|
||||
mp[m] = (a, b)
|
||||
product = 1
|
||||
for i in mp.keys():
|
||||
product *=i
|
||||
product *= i
|
||||
sol = [0]
|
||||
for i in mp:
|
||||
xs,m = self.solveLinear(product//i*mp[i][0],1,i)
|
||||
xs, m = self.solveLinear(product//i*mp[i][0], 1, i)
|
||||
new = []
|
||||
for x in xs:
|
||||
cur = x*product//i*mp[i][1]
|
||||
for old in sol:
|
||||
new.append(old+cur)
|
||||
sol = new
|
||||
sol= [i%product for i in sol]
|
||||
print('final solution: {} mod {}'.format(sol,product))
|
||||
return sol,product
|
||||
sol = [i % product for i in sol]
|
||||
print('final solution: {} mod {}'.format(sol, product))
|
||||
return sol, product
|
||||
|
||||
def __call__(self):
|
||||
s=input('输入同余方程,用--代表同于号,形如3--5(mod 7)代表3x模7同余于5')
|
||||
li= self.linearPat.findall(s)
|
||||
li = [(int(a),int(b),int(m)) for a,b,m in li]
|
||||
s = input('输入同余方程,用--代表同于号,形如3--5(mod 7)代表3x模7同余于5')
|
||||
li = self.linearPat.findall(s)
|
||||
li = [(int(a), int(b), int(m)) for a, b, m in li]
|
||||
print(self.solveLinear(li[0]))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
solver = solve()
|
||||
res = solver.solveLinear(3,6,9)
|
||||
solver = solve()
|
||||
res = solver.solveLinear(3, 6, 9)
|
||||
print()
|
||||
res = solver.solveHigh(1,8,3,11)
|
||||
res = solver.solveHigh(1, 8, 3, 11)
|
||||
print()
|
||||
res = solver.solveGroup([(5,11,2),(3,8,5),(4,1,7)])
|
||||
res = solver.solveGroup([(5, 11, 2), (3, 8, 5), (4, 1, 7)])
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
genPrimes 2= [2]
|
||||
genPrimes n = let li = genPrimes $n-1
|
||||
in if all (\x-> mod n x /=0) li then n:li else li
|
||||
in if all (\x-> mod n x /=0) li then n:li else li
|
||||
|
|
56
math/numberTheory/sievePrime.py
Normal file
56
math/numberTheory/sievePrime.py
Normal file
|
@ -0,0 +1,56 @@
|
|||
def sievePrime(n):
|
||||
if n < 2:
|
||||
return 0
|
||||
prime = [1] * (n + 1)
|
||||
prime[0] = prime[1] = 0
|
||||
for i in range(2, int(n**0.5) + 1):
|
||||
if prime[i] == 1:
|
||||
prime[i*i:n + 1:i] = [0]*len(prime[i*i:n + 1:i])
|
||||
return [i for i in range(n+1) if prime[i] == 1]
|
||||
|
||||
|
||||
class primeSiever:
|
||||
'''sieve of Eratosthenes, It will be more efficient when judging many times'''
|
||||
primes = [2, 3, 5, 7, 11, 13]
|
||||
|
||||
def isPrime(self, x):
|
||||
if x <= primes[-1]:
|
||||
return twoDivideFind(x, self.primes)
|
||||
while x > self.primes[-1]:
|
||||
left = self.primes[-1]
|
||||
right = (left+1)**2
|
||||
lst = []
|
||||
for i in range(left, right):
|
||||
for j in self.primes:
|
||||
if i % j == 0:
|
||||
break
|
||||
else:
|
||||
lst.append(i)
|
||||
self.primes += lst
|
||||
return twoDivideFind(x, lst)
|
||||
|
||||
def nPrime(n):
|
||||
'''return the n-th prime'''
|
||||
i = n-len(self.primes)
|
||||
last = self.primes[-1]
|
||||
for _ in range(i):
|
||||
while 1:
|
||||
last += 2
|
||||
for p in self.primes:
|
||||
if last % p == 0:
|
||||
break
|
||||
else:
|
||||
self.primes.append(last)
|
||||
break
|
||||
return self.primes[n-1]
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
if len(sys.argv) < 2:
|
||||
n = 100
|
||||
else:
|
||||
n = int(sys.argv[1])
|
||||
ans = sievePrime(n)
|
||||
print(f'primes <= {n}, nums: {len(ans)}')
|
||||
print(ans)
|
|
@ -26,58 +26,65 @@ from collections import namedtuple
|
|||
from functools import reduce
|
||||
from operator import mul
|
||||
|
||||
X = sympy.Symbol ('x')
|
||||
point = namedtuple('point',['x','y'])
|
||||
X = sympy.Symbol('x')
|
||||
point = namedtuple('point', ['x', 'y'])
|
||||
|
||||
|
||||
class interplotion:
|
||||
def __init__(self,points):
|
||||
self.points = [point(x,y) for x,y in points]
|
||||
self.xs= [i for i,j in points]
|
||||
self.poly,self.rem = self.newton(self.points,0,len(self.points)-1)
|
||||
def __init__(self, points):
|
||||
self.points = [point(x, y) for x, y in points]
|
||||
self.xs = [i for i, j in points]
|
||||
self.poly, self.rem = self.newton(self.points, 0, len(self.points)-1)
|
||||
|
||||
def newton(self,li,a,b):
|
||||
def newton(self, li, a, b):
|
||||
'''li:[(x,f(x))...]'''
|
||||
|
||||
|
||||
qs = [li[0].y]
|
||||
|
||||
def quoDiff(begin,end):
|
||||
if begin == end:return li[begin].y
|
||||
q = (quoDiff(begin+1,end)-quoDiff(begin,end-1))/(li[end].x-li[begin].x)
|
||||
if begin == a:qs.append(q)
|
||||
|
||||
def quoDiff(begin, end):
|
||||
if begin == end:
|
||||
return li[begin].y
|
||||
q = (quoDiff(begin+1, end)-quoDiff(begin, end-1)) / \
|
||||
(li[end].x-li[begin].x)
|
||||
if begin == a:
|
||||
qs.append(q)
|
||||
return q
|
||||
|
||||
quoDiff(a,b)
|
||||
poly ,base = 0, 1
|
||||
for i,q in enumerate(qs):
|
||||
quoDiff(a, b)
|
||||
poly, base = 0, 1
|
||||
for i, q in enumerate(qs):
|
||||
poly += q*base
|
||||
base*= X-li[i].x
|
||||
base *= X-li[i].x
|
||||
return poly, base*qs[-1]
|
||||
def lagrange(self,points=None):
|
||||
|
||||
def lagrange(self, points=None):
|
||||
xs = None
|
||||
if points is None:
|
||||
xs = self.xs
|
||||
points = self.points
|
||||
else: xs =[x for x,y in points]
|
||||
product = reduce(mul,[X-x for x in xs],1)
|
||||
else:
|
||||
xs = [x for x, y in points]
|
||||
product = reduce(mul, [X-x for x in xs], 1)
|
||||
poly = 0
|
||||
for x,y in points:
|
||||
tmp = product/(X-x)
|
||||
coef = y/(tmp.subs(X,x))
|
||||
poly+= coef *tmp
|
||||
for x, y in points:
|
||||
tmp = product/(X-x)
|
||||
coef = y/(tmp.subs(X, x))
|
||||
poly += coef * tmp
|
||||
return poly
|
||||
|
||||
def predict(self,val,poly = None):
|
||||
if poly is None:poly = self.poly
|
||||
return poly.subs(X,val) # note the func subs
|
||||
|
||||
def predict(self, val, poly=None):
|
||||
if poly is None:
|
||||
poly = self.poly
|
||||
return poly.subs(X, val) # note the func subs
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
f = interplotion([(81,9),(100,10),(121,11)])
|
||||
f = interplotion([(81, 9), (100, 10), (121, 11)])
|
||||
p = f.lagrange()
|
||||
print(p.subs(X,105))
|
||||
print(p.subs(X, 105))
|
||||
print(p)
|
||||
|
||||
intor = interplotion([(0,11),(0.02,9),(0.04,7),(0.06,10)])
|
||||
intor = interplotion([(0, 11), (0.02, 9), (0.04, 7), (0.06, 10)])
|
||||
p = intor.lagrange()
|
||||
print(p)
|
||||
res = intor.predict(0.08)
|
||||
|
|
|
@ -15,94 +15,98 @@ import numpy as np
|
|||
from math import sqrt
|
||||
|
||||
|
||||
def newton(y:sympy.core,x0:float,epsilon:float=0.00001,maxtime:int=50) ->(list,list):
|
||||
def newton(y: sympy.core, x0: float, epsilon: float = 0.00001, maxtime: int = 50) ->(list, list):
|
||||
'''
|
||||
newton 's iteration method for finding a zeropoint of a func
|
||||
y is the func, x0 is the init x val: int float epsilon is the accurrency
|
||||
'''
|
||||
if epsilon <0:epsilon = -epsilon
|
||||
ct =0
|
||||
t = y.free_symbols
|
||||
varsymbol = 'x' if len(t)==0 else t.pop()
|
||||
x0= float(x0)
|
||||
if epsilon < 0:
|
||||
epsilon = -epsilon
|
||||
ct = 0
|
||||
t = y.free_symbols
|
||||
varsymbol = 'x' if len(t) == 0 else t.pop()
|
||||
x0 = float(x0)
|
||||
y_diff = y.diff()
|
||||
li = [x0]
|
||||
vals = []
|
||||
while 1:
|
||||
val = y.subs(varsymbol,x0)
|
||||
val = y.subs(varsymbol, x0)
|
||||
vals.append(val)
|
||||
x = x0- val/y_diff.subs(varsymbol,x0)
|
||||
x = x0 - val/y_diff.subs(varsymbol, x0)
|
||||
li.append(x)
|
||||
ct+=1
|
||||
if ct>maxtime:
|
||||
ct += 1
|
||||
if ct > maxtime:
|
||||
print("after iteration for {} times, I still havn't reach the accurrency.\
|
||||
Maybe this function havsn't zeropoint\n".format(ct))
|
||||
return li ,val
|
||||
if abs(x-x0)<epsilon:return li,vals
|
||||
return li, val
|
||||
if abs(x-x0) < epsilon:
|
||||
return li, vals
|
||||
x0 = x
|
||||
|
||||
|
||||
def secant(y:sympy.core,x0:float,x1:float,epsilon:float =0.00001,maxtime:int=50) ->(list,list):
|
||||
|
||||
def secant(y: sympy.core, x0: float, x1: float, epsilon: float = 0.00001, maxtime: int = 50) ->(list, list):
|
||||
'''
|
||||
弦截法, 使用newton 差商计算,每次只需计算一次f(x)
|
||||
secant method for finding a zeropoint of a func
|
||||
y is the func , x0 is the init x val, epsilon is the accurrency
|
||||
'''
|
||||
if epsilon <0:epsilon = -epsilon
|
||||
ct =0
|
||||
x0,x1 = float(x0),float(x1)
|
||||
li = [x0,x1]
|
||||
t = y.free_symbols
|
||||
varsymbol = 'x' if len(t)==0 else t.pop()
|
||||
last = y.subs(varsymbol,x0)
|
||||
if epsilon < 0:
|
||||
epsilon = -epsilon
|
||||
ct = 0
|
||||
x0, x1 = float(x0), float(x1)
|
||||
li = [x0, x1]
|
||||
t = y.free_symbols
|
||||
varsymbol = 'x' if len(t) == 0 else t.pop()
|
||||
last = y.subs(varsymbol, x0)
|
||||
vals = [last]
|
||||
while 1:
|
||||
cur = y.subs(varsymbol,x1)
|
||||
cur = y.subs(varsymbol, x1)
|
||||
vals.append(cur)
|
||||
x = x1-cur*(x1-x0)/(cur-last)
|
||||
x0 ,x1= x1,x
|
||||
x0, x1 = x1, x
|
||||
last = cur
|
||||
li.append(x)
|
||||
ct+=1
|
||||
if ct>maxtime:
|
||||
ct += 1
|
||||
if ct > maxtime:
|
||||
print("after iteration for {} times, I still havn't reach the accurrency.\
|
||||
Maybe this function havsn't zeropoint\n".format(ct))
|
||||
return li,vals
|
||||
if abs(x0-x1)<epsilon:return li,vals
|
||||
return li, vals
|
||||
if abs(x0-x1) < epsilon:
|
||||
return li, vals
|
||||
x0 = x
|
||||
|
||||
|
||||
def solveNonlinearEquations(funcs:[sympy.core],init_dic:dict,epsilon:float=0.001,maxtime:int=50)->dict:
|
||||
def solveNonlinearEquations(funcs: [sympy.core], init_dic: dict, epsilon: float = 0.001, maxtime: int = 50)->dict:
|
||||
'''solve nonlinear equations:'''
|
||||
li = list(init_dic.keys())
|
||||
delta = {i:0 for i in li}
|
||||
delta = {i: 0 for i in li}
|
||||
ct = 0
|
||||
while 1:
|
||||
ys = np.array([f.subs(init_dic) for f in funcs],dtype = 'float')
|
||||
mat = np.matrix([[i.diff(x).subs(init_dic) for x in li] for i in funcs ],dtype = 'float')
|
||||
delt = np.linalg.solve(mat,-ys)
|
||||
for i,j in enumerate(delt):
|
||||
init_dic[li[i]] +=j
|
||||
ys = np.array([f.subs(init_dic) for f in funcs], dtype='float')
|
||||
mat = np.matrix([[i.diff(x).subs(init_dic) for x in li]
|
||||
for i in funcs], dtype='float')
|
||||
delt = np.linalg.solve(mat, -ys)
|
||||
for i, j in enumerate(delt):
|
||||
init_dic[li[i]] += j
|
||||
delta[li[i]] = j
|
||||
if ct>maxtime:
|
||||
if ct > maxtime:
|
||||
print("after iteration for {} times, I still havn't reach the accurrency.\
|
||||
Maybe this function havsn't zeropoint\n".format(ct))
|
||||
return init_dic
|
||||
if sqrt(sum(i**2 for i in delta.values()))<epsilon:return init_dic
|
||||
if sqrt(sum(i**2 for i in delta.values())) < epsilon:
|
||||
return init_dic
|
||||
|
||||
|
||||
if __name__ =='__main__':
|
||||
x,y,z = sympy.symbols('x y z')
|
||||
|
||||
res,res2= newton(x**5-9,2,0.01)
|
||||
print(res,res2)
|
||||
if __name__ == '__main__':
|
||||
x, y, z = sympy.symbols('x y z')
|
||||
|
||||
res, res2 = newton(x**5-9, 2, 0.01)
|
||||
print(res, res2)
|
||||
|
||||
res,res2 = secant (x**3-3*x-2,1,3,1e-3)
|
||||
print(res,res2)
|
||||
res, res2 = secant(x**3-3*x-2, 1, 3, 1e-3)
|
||||
print(res, res2)
|
||||
|
||||
|
||||
funcs=[x**2+y**2-1,x**3-y]
|
||||
init = {x:0.8,y:0.6}
|
||||
res_dic = solveNonlinearEquations(funcs,init,0.001)
|
||||
funcs = [x**2+y**2-1, x**3-y]
|
||||
init = {x: 0.8, y: 0.6}
|
||||
res_dic = solveNonlinearEquations(funcs, init, 0.001)
|
||||
print(res_dic)
|
||||
|
|
|
@ -20,12 +20,11 @@
|
|||
************************************************************************'''
|
||||
|
||||
|
||||
|
||||
|
||||
import re
|
||||
import numpy as np
|
||||
|
||||
|
||||
|
||||
def solveConflitEqualtion(A,y):
|
||||
def solveConflitEqualtion(A, y):
|
||||
'''solve equation like this: Av = y,
|
||||
A:m*n v:n*1 y:m*1
|
||||
return vector v
|
||||
|
@ -35,43 +34,49 @@ def solveConflitEqualtion(A,y):
|
|||
ata = A.T*A
|
||||
print('AtA')
|
||||
print(ata)
|
||||
return np.linalg.solve(ata,A.T*y) # note that is numpy.linalg.solve
|
||||
return np.linalg.solve(ata, A.T*y) # note that is numpy.linalg.solve
|
||||
|
||||
def solveLinear(point,index):
|
||||
|
||||
def solveLinear(point, index):
|
||||
y = [[i[1]] for i in point]
|
||||
x = [[i[0]] for i in point]
|
||||
A = []
|
||||
for i in x:
|
||||
A.append([i[0]**j for j in index])
|
||||
res = solveConflitEqualtion(A,y)
|
||||
print('the solution is : \n',res)
|
||||
res = solveConflitEqualtion(A, y)
|
||||
print('the solution is : \n', res)
|
||||
print('namely: ')
|
||||
items = ['{:.4f}x^{}'.format(res[i,0],j) for i, j in enumerate(index)]
|
||||
print('phi(x) = ',' + '.join(items))
|
||||
items = ['{:.4f}x^{}'.format(res[i, 0], j) for i, j in enumerate(index)]
|
||||
print('phi(x) = ', ' + '.join(items))
|
||||
|
||||
def handleInput(s=None,y=None):
|
||||
|
||||
def handleInput(s=None, y=None):
|
||||
# numPt = re.compile (r'\d*\.{0,1}\d+')
|
||||
if not s: s = input('input matrix A:m*n //m>=n\n')
|
||||
s = s.replace(' ','')
|
||||
li = re.findall(r'(\[(\d+)(,(\d+))+\])',s)
|
||||
li = [parseLst(i[0]) for i in li]
|
||||
if not y:y = input('input a vector y:n*1\n')
|
||||
if not s:
|
||||
s = input('input matrix A:m*n //m>=n\n')
|
||||
s = s.replace(' ', '')
|
||||
li = re.findall(r'(\[(\d+)(,(\d+))+\])', s)
|
||||
li = [parseLst(i[0]) for i in li]
|
||||
if not y:
|
||||
y = input('input a vector y:n*1\n')
|
||||
y = parseLst(y)
|
||||
print('Equation: Av = y:')
|
||||
|
||||
|
||||
print('y is as follows: ')
|
||||
print(y)
|
||||
print('A is as follows: ')
|
||||
for i in li:
|
||||
for j in i:
|
||||
print('{}'.format(j).rjust(5),end='')
|
||||
print('{}'.format(j).rjust(5), end='')
|
||||
print('')
|
||||
|
||||
|
||||
print('result v is as follows: ')
|
||||
res = solveConflitEqualtion(li,y)
|
||||
res = solveConflitEqualtion(li, y)
|
||||
print(res)
|
||||
|
||||
|
||||
def parseLst(s):
|
||||
s = s.strip('[]')
|
||||
s = s.strip('[]')
|
||||
li = s.split(',')
|
||||
li = [float(j) for j in li]
|
||||
return li
|
||||
|
@ -86,19 +91,19 @@ if __name__ == '__main__':
|
|||
s = input('input y to continue, n for exit')
|
||||
if s!='y':break
|
||||
'''
|
||||
point = [(-3,14.3),(-2,8.3),(-1,4.7),(2,-8.3),(4,-22.7)]
|
||||
lst = [0,3]
|
||||
solveLinear(point,lst)
|
||||
point = [(-3, 14.3), (-2, 8.3), (-1, 4.7), (2, -8.3), (4, -22.7)]
|
||||
lst = [0, 3]
|
||||
solveLinear(point, lst)
|
||||
|
||||
point = [(-3, 14.3), (-2, 8.3), (-1, 4.7), (2, 8.3), (4, 22.7)]
|
||||
lst = [0, 2]
|
||||
solveLinear(point, lst)
|
||||
|
||||
A = [[1, 2], [2, 1], [1, 1]]
|
||||
y = [[5], [6], [4]]
|
||||
res = solveConflitEqualtion(A, y)
|
||||
|
||||
point= [(-3,14.3),(-2,8.3),(-1,4.7),(2,8.3),(4,22.7)]
|
||||
lst = [0,2]
|
||||
solveLinear(point,lst)
|
||||
|
||||
A = [[1,2],[2,1],[1,1]]
|
||||
y = [[5],[6],[4]]
|
||||
res = solveConflitEqualtion(A,y)
|
||||
|
||||
print(res)
|
||||
A = [[1,-2],[1,5],[2,1],[1,1]]
|
||||
y = [[1],[13.1],[7.9],[5.1]]
|
||||
print(solveConflitEqualtion(A,y))
|
||||
A = [[1, -2], [1, 5], [2, 1], [1, 1]]
|
||||
y = [[1], [13.1], [7.9], [5.1]]
|
||||
print(solveConflitEqualtion(A, y))
|
||||
|
|
|
@ -19,86 +19,105 @@
|
|||
> Created Time: 2018-04-20 08:32
|
||||
************************************************************************'''
|
||||
|
||||
|
||||
|
||||
|
||||
import numpy as np
|
||||
def getLU(A):
|
||||
'''doolittle : A = LU,
|
||||
L is in down-triangle form,
|
||||
U is in up-triangle form
|
||||
'''
|
||||
m,n = A.shape
|
||||
if m!=n:raise Exception("this matrix is not inversable")
|
||||
m, n = A.shape
|
||||
if m != n:
|
||||
raise Exception("this matrix is not inversable")
|
||||
|
||||
L = np.zeros([m,m])
|
||||
U = np.zeros([m,m])
|
||||
L = np.zeros([m, m])
|
||||
U = np.zeros([m, m])
|
||||
L = np.matrix(L)
|
||||
U = np. matrix(U)
|
||||
U[0] = A[0]
|
||||
L[:,0] = A[:,0] / A[0,0]
|
||||
for i in range(1,m):
|
||||
for j in range(i,m):
|
||||
U[i,j]= A[i,j] - sum(L[i,k]*U[k,j] for k in range(i))
|
||||
L[j,i] = (A[j,i] - sum(L[j,k]*U[k,i] for k in range(i)))/U[i,i]
|
||||
L[:, 0] = A[:, 0] / A[0, 0]
|
||||
for i in range(1, m):
|
||||
for j in range(i, m):
|
||||
U[i, j] = A[i, j] - sum(L[i, k]*U[k, j] for k in range(i))
|
||||
L[j, i] = (A[j, i] - sum(L[j, k]*U[k, i]
|
||||
for k in range(i)))/U[i, i]
|
||||
print(L)
|
||||
print(U)
|
||||
return L,U
|
||||
return L, U
|
||||
|
||||
|
||||
def gauss_prior_elimination(A):
|
||||
'''using guass elimination,get up_trianglge form of A'''
|
||||
m,n = A.shape
|
||||
if m!=n:raise Exception("[Error]: matrix is not inversable")
|
||||
B = np.matrix(A,dtype=float) # necessary,otherwise when the dtype of A is int, then it will be wrong
|
||||
for i in range(m-1):
|
||||
col = abs(B[i:,i]) # note using abs value, return a matrix in (m-i)x1 form
|
||||
m, n = A.shape
|
||||
if m != n:
|
||||
raise Exception("[Error]: matrix is not inversable")
|
||||
# necessary,otherwise when the dtype of A is int, then it will be wrong
|
||||
B = np.matrix(A, dtype=float)
|
||||
for i in range(m-1):
|
||||
# note using abs value, return a matrix in (m-i)x1 form
|
||||
col = abs(B[i:, i])
|
||||
mx = col.max()
|
||||
if mx==0: raise Exception("[Error]: matrix is not inversable")
|
||||
if mx == 0:
|
||||
raise Exception("[Error]: matrix is not inversable")
|
||||
pos = i+col.argmax()
|
||||
if pos != i : B[[pos,i],:] = B[[i,pos],:] # note how to swap cols/rows
|
||||
B[i,:] = 1/mx*B[i,:]
|
||||
for j in range(i+1,m):
|
||||
#print(B)
|
||||
B[j,:] -= B[j,i] * B[i,:]
|
||||
if pos != i:
|
||||
B[[pos, i], :] = B[[i, pos], :] # note how to swap cols/rows
|
||||
B[i, :] = 1/mx*B[i, :]
|
||||
for j in range(i+1, m):
|
||||
# print(B)
|
||||
B[j, :] -= B[j, i] * B[i, :]
|
||||
print(B)
|
||||
return B
|
||||
|
||||
def solveDown(A,b):
|
||||
|
||||
def solveDown(A, b):
|
||||
'''A is a matrix in down-triangle form'''
|
||||
sol = np.zeros(b.shape)
|
||||
for i in range(b.shape[0]):
|
||||
sol[i,0] = (b[i,0]-sum(A[i,j]*sol[j,0] for j in range(i)))/A[i,i]
|
||||
sol[i, 0] = (b[i, 0]-sum(A[i, j]*sol[j, 0] for j in range(i)))/A[i, i]
|
||||
return sol
|
||||
|
||||
def solveUp(A,b):
|
||||
|
||||
def solveUp(A, b):
|
||||
'''A is a matrix in up-triangle form'''
|
||||
sol = np.zeros(b.shape)
|
||||
n = b.shape[0]
|
||||
for i in range(n-1,-1,-1):
|
||||
sol[i,0] = (b[i,0]-sum(A[i,j]*sol[j,0] for j in range(n-1,i,-1)))/A[i,i]
|
||||
for i in range(n-1, -1, -1):
|
||||
sol[i, 0] = (b[i, 0]-sum(A[i, j]*sol[j, 0]
|
||||
for j in range(n-1, i, -1)))/A[i, i]
|
||||
return sol
|
||||
def doolittle(A,b):
|
||||
L,U = getLU(A)
|
||||
y = solveDown(L,b)
|
||||
x = solveUp(U,y)
|
||||
|
||||
|
||||
def doolittle(A, b):
|
||||
L, U = getLU(A)
|
||||
y = solveDown(L, b)
|
||||
x = solveUp(U, y)
|
||||
print(y)
|
||||
print(x)
|
||||
return x
|
||||
def ldlt(A,b):
|
||||
L,U = getLU(A)
|
||||
|
||||
|
||||
def ldlt(A, b):
|
||||
L, U = getLU(A)
|
||||
D = np.diag(np.diag(U))
|
||||
print(D,"D")
|
||||
z = np.linalg.solve(L,b)
|
||||
print(z,"z")
|
||||
y = np.linalg.solve(D,z)
|
||||
print(y,"y")
|
||||
x = np.linalg.solve(L.T,y)
|
||||
print(x,"x")
|
||||
print(D, "D")
|
||||
z = np.linalg.solve(L, b)
|
||||
print(z, "z")
|
||||
y = np.linalg.solve(D, z)
|
||||
print(y, "y")
|
||||
x = np.linalg.solve(L.T, y)
|
||||
print(x, "x")
|
||||
return x
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
A = np.matrix([[10,5,0,0],
|
||||
[2,2,1,0],
|
||||
[0,10,0,5],
|
||||
[0,0,2,1]])
|
||||
b = np.matrix([[5],[3],[27],[6]])
|
||||
A = np.matrix([[10, 5, 0, 0],
|
||||
[2, 2, 1, 0],
|
||||
[0, 10, 0, 5],
|
||||
[0, 0, 2, 1]])
|
||||
b = np.matrix([[5], [3], [27], [6]])
|
||||
gauss_prior_elimination(A)
|
||||
|
||||
'''ldlt
|
||||
|
@ -115,4 +134,3 @@ if __name__ == '__main__':
|
|||
b = np.matrix([[4],[6],[5]])
|
||||
doolittle(A,b)
|
||||
'''
|
||||
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
''' mbinary
|
||||
#########################################################################
|
||||
# File : numerical_differential.py
|
||||
# Author: mbinary
|
||||
# Mail: zhuheqin1@gmail.com
|
||||
# Blog: https://mbinary.xyz
|
||||
# Github: https://github.com/mbinary
|
||||
# Created Time: 2018-10-02 21:14
|
||||
# Description:
|
||||
#########################################################################
|
||||
'''
|
||||
|
||||
|
|
@ -18,53 +18,56 @@
|
|||
# Blog: https://mbinary.xyz
|
||||
# Github: https://github.com/mbinary
|
||||
# Created Time: 2018-05-11 08:58
|
||||
# Description:
|
||||
# Description:
|
||||
# numerical intergration: using Newton-Cotes integration, and Simpson
|
||||
# 数值积分, 使用 牛顿-科特斯积分, 辛普森
|
||||
#########################################################################
|
||||
|
||||
|
||||
|
||||
import numpy as np
|
||||
def trapezoidal(a,b,h,fs):
|
||||
|
||||
|
||||
def trapezoidal(a, b, h, fs):
|
||||
'''梯形积分公式'''
|
||||
xs = [i for i in np.arange(a,b+h,h)]
|
||||
xs = [i for i in np.arange(a, b+h, h)]
|
||||
print(xs)
|
||||
ret = h*(sum(fs)-fs[0]/2 - fs[-1]/2)
|
||||
print(ret)
|
||||
return ret
|
||||
|
||||
|
||||
def simpson(a,b,h,fs):
|
||||
def simpson(a, b, h, fs):
|
||||
'''辛普森积分公式'''
|
||||
xs = [i for i in np.arange(a,b+h,h)]
|
||||
xs = [i for i in np.arange(a, b+h, h)]
|
||||
print(xs)
|
||||
ret = h/3*(4* sum(fs[1::2])+ 2*sum(fs[2:-1:2]) + fs[0]+fs[-1])
|
||||
ret = h/3*(4 * sum(fs[1::2]) + 2*sum(fs[2:-1:2]) + fs[0]+fs[-1])
|
||||
print(ret)
|
||||
return ret
|
||||
|
||||
|
||||
def romberg(a,b,f,epcilon):
|
||||
def romberg(a, b, f, epcilon):
|
||||
'''romberg(龙贝格) 数值积分'''
|
||||
h = b-a
|
||||
lst1=[h*(f(a)+f(b))/2]
|
||||
lst1 = [h*(f(a)+f(b))/2]
|
||||
print(lst1)
|
||||
delta = epcilon
|
||||
k=1
|
||||
k = 1
|
||||
while delta >= epcilon:
|
||||
h/=2
|
||||
k+=1
|
||||
lst2=[]
|
||||
lst2.append((lst1[0]+h*2*sum(f(a+(2*i-1)*h) for i in range(1,2**(k-2)+1)))/2)
|
||||
for j in range(0,k-1):
|
||||
h /= 2
|
||||
k += 1
|
||||
lst2 = []
|
||||
lst2.append((lst1[0]+h*2*sum(f(a+(2*i-1)*h)
|
||||
for i in range(1, 2**(k-2)+1)))/2)
|
||||
for j in range(0, k-1):
|
||||
lst2.append(lst2[j]+(lst2[j]-lst1[j])/(4**(j+1)-1))
|
||||
delta = abs(lst2[-1]-lst1[-1])
|
||||
lst1=lst2
|
||||
lst1 = lst2
|
||||
print(lst1)
|
||||
|
||||
if __name__=='__main__':
|
||||
a,b,h = 0.6,1.8,0.2
|
||||
fs=[5.7,4.6,3.5,3.7,4.9,5.2,5.5]
|
||||
trapezoidal(a,b,h,fs)
|
||||
simpson(a,b,h,fs)
|
||||
romberg(1,2,lambda x:sin(x**4),1e-4)
|
||||
|
||||
if __name__ == '__main__':
|
||||
a, b, h = 0.6, 1.8, 0.2
|
||||
fs = [5.7, 4.6, 3.5, 3.7, 4.9, 5.2, 5.5]
|
||||
trapezoidal(a, b, h, fs)
|
||||
simpson(a, b, h, fs)
|
||||
romberg(1, 2, lambda x: sin(x**4), 1e-4)
|
||||
|
|
|
@ -21,46 +21,59 @@
|
|||
# Description:
|
||||
#########################################################################
|
||||
'''
|
||||
import numpy as np
|
||||
from operator import le,lt
|
||||
|
||||
def jacob(A,b,x,accuracy=None,times=6):
|
||||
|
||||
|
||||
|
||||
import numpy as np
|
||||
from operator import le, lt
|
||||
def jacob(A, b, x, accuracy=None, times=6):
|
||||
''' Ax=b, arg x is the init val, times is the time of iterating'''
|
||||
A,b,x = np.matrix(A),np.matrix(b),np.matrix(x)
|
||||
n,m = A.shape
|
||||
if n!=m:raise Exception("Not square matrix: {A}".format(A=A))
|
||||
if b.shape !=( n,1) : raise Exception('Error: {b} must be {n} x1 in dimension'.format(b = b,n=n))
|
||||
A, b, x = np.matrix(A), np.matrix(b), np.matrix(x)
|
||||
n, m = A.shape
|
||||
if n != m:
|
||||
raise Exception("Not square matrix: {A}".format(A=A))
|
||||
if b.shape != (n, 1):
|
||||
raise Exception(
|
||||
'Error: {b} must be {n} x1 in dimension'.format(b=b, n=n))
|
||||
D = np.diag(np.diag(A))
|
||||
DI = np.zeros([n,n])
|
||||
for i in range(n):DI[i,i]= 1/D[i,i]
|
||||
DI = np.zeros([n, n])
|
||||
for i in range(n):
|
||||
DI[i, i] = 1/D[i, i]
|
||||
R = np.eye(n) - DI * A
|
||||
g = DI * b
|
||||
print('R =\n{}'.format(R))
|
||||
print('g =\n{}'.format(g))
|
||||
last = -x
|
||||
if accuracy != None:
|
||||
ct=0
|
||||
ct = 0
|
||||
while 1:
|
||||
ct+=1
|
||||
ct += 1
|
||||
tmp = x-last
|
||||
last = x
|
||||
mx = max ( abs(i) for i in tmp)
|
||||
if mx<accuracy:return x
|
||||
mx = max(abs(i) for i in tmp)
|
||||
if mx < accuracy:
|
||||
return x
|
||||
x = R*x+g
|
||||
print('x{ct} =\n{x}'.format(ct = ct,x=x))
|
||||
print('x{ct} =\n{x}'.format(ct=ct, x=x))
|
||||
else:
|
||||
for i in range(times):
|
||||
x = R*x+g
|
||||
print('x{ct} = \n{x}'.format(ct=i+1,x=x))
|
||||
print('x{ct} = \n{x}'.format(ct=i+1, x=x))
|
||||
print('isLimitd: {}'.format(isLimited(A)))
|
||||
return x
|
||||
def gauss_seidel(A,b,x,accuracy=None,times=6):
|
||||
|
||||
|
||||
def gauss_seidel(A, b, x, accuracy=None, times=6):
|
||||
''' Ax=b, arg x is the init val, times is the time of iterating'''
|
||||
A,b,x = np.matrix(A),np.matrix(b),np.matrix(x)
|
||||
n,m = A.shape
|
||||
if n!=m:raise Exception("Not square matrix: {A}".format(A=A))
|
||||
if b.shape !=( n,1) : raise Exception('Error: {b} must be {n} x1 in dimension'.format(b = b,n=n))
|
||||
D =np. matrix(np.diag(np.diag(A)))
|
||||
A, b, x = np.matrix(A), np.matrix(b), np.matrix(x)
|
||||
n, m = A.shape
|
||||
if n != m:
|
||||
raise Exception("Not square matrix: {A}".format(A=A))
|
||||
if b.shape != (n, 1):
|
||||
raise Exception(
|
||||
'Error: {b} must be {n} x1 in dimension'.format(b=b, n=n))
|
||||
D = np. matrix(np.diag(np.diag(A)))
|
||||
L = np.tril(A) - D # L = np.triu(D.T) - D
|
||||
U = np.triu(A) - D
|
||||
DLI = (D+L).I
|
||||
|
@ -70,61 +83,69 @@ def gauss_seidel(A,b,x,accuracy=None,times=6):
|
|||
print('f =\n{}'.format(f))
|
||||
last = -x
|
||||
if accuracy != None:
|
||||
ct=0
|
||||
ct = 0
|
||||
while 1:
|
||||
ct+=1
|
||||
ct += 1
|
||||
tmp = x-last
|
||||
last = x
|
||||
mx = max ( abs(i) for i in tmp)
|
||||
if mx<accuracy:return x
|
||||
mx = max(abs(i) for i in tmp)
|
||||
if mx < accuracy:
|
||||
return x
|
||||
x = S*x+f
|
||||
print('x{ct} =\n{x}'.format(ct=ct,x=x))
|
||||
print('x{ct} =\n{x}'.format(ct=ct, x=x))
|
||||
else:
|
||||
for i in range(times):
|
||||
x = S*x+f
|
||||
print('x{ct} = \n{x}'.format(ct=i+1,x=x))
|
||||
print('x{ct} = \n{x}'.format(ct=i+1, x=x))
|
||||
print('isLimitd: {}'.format(isLimited(A)))
|
||||
return x
|
||||
|
||||
|
||||
def isLimited(A,strict=False):
|
||||
def isLimited(A, strict=False):
|
||||
'''通过检查A是否是[严格]对角优来判断迭代是否收敛, 即对角线上的值是否都大于对应行(或者列)的值'''
|
||||
diag = np.diag(A)
|
||||
op = lt if strict else le
|
||||
if op(A.max(axis=0),diag).all(): return True
|
||||
if op(A.max(axis=1), diag).all(): return True
|
||||
if op(A.max(axis=0), diag).all():
|
||||
return True
|
||||
if op(A.max(axis=1), diag).all():
|
||||
return True
|
||||
return False
|
||||
|
||||
testcase=[]
|
||||
|
||||
testcase = []
|
||||
|
||||
|
||||
def test():
|
||||
for func,A,b,x,*args in testcase:
|
||||
acc =None
|
||||
for func, A, b, x, *args in testcase:
|
||||
acc = None
|
||||
times = 6
|
||||
if args !=[] :
|
||||
if isinstance(args[0],int):times = args[0]
|
||||
else : acc = args[0]
|
||||
return func(A,b,x,acc,times)
|
||||
if args != []:
|
||||
if isinstance(args[0], int):
|
||||
times = args[0]
|
||||
else:
|
||||
acc = args[0]
|
||||
return func(A, b, x, acc, times)
|
||||
|
||||
|
||||
if __name__ =='__main__':
|
||||
A = [[2,-1,-1],
|
||||
[1,5,-1],
|
||||
[1,1,10]
|
||||
]
|
||||
b = [[-5],[8],[11]]
|
||||
x = [[1],[1],[1]]
|
||||
#testcase.append([gauss_seidel,A,b,x])
|
||||
if __name__ == '__main__':
|
||||
A = [[2, -1, -1],
|
||||
[1, 5, -1],
|
||||
[1, 1, 10]
|
||||
]
|
||||
b = [[-5], [8], [11]]
|
||||
x = [[1], [1], [1]]
|
||||
# testcase.append([gauss_seidel,A,b,x])
|
||||
|
||||
A = [[2,-1,1],[3,3,9],[3,3,5]]
|
||||
b = [[-1],[0],[4]]
|
||||
x = [[0],[0],[0]]
|
||||
#testcase.append([jacob,A,b,x])
|
||||
A = [[2, -1, 1], [3, 3, 9], [3, 3, 5]]
|
||||
b = [[-1], [0], [4]]
|
||||
x = [[0], [0], [0]]
|
||||
# testcase.append([jacob,A,b,x])
|
||||
|
||||
A = [[5,-1,-1],
|
||||
[3,6,2],
|
||||
[1,-1,2]
|
||||
]
|
||||
b= [[16],[11],[-2]]
|
||||
x = [[1],[1],[-1]]
|
||||
testcase.append([gauss_seidel,A,b,x,0.001])
|
||||
A = [[5, -1, -1],
|
||||
[3, 6, 2],
|
||||
[1, -1, 2]
|
||||
]
|
||||
b = [[16], [11], [-2]]
|
||||
x = [[1], [1], [-1]]
|
||||
testcase.append([gauss_seidel, A, b, x, 0.001])
|
||||
test()
|
||||
|
|
|
@ -10,35 +10,43 @@
|
|||
#########################################################################
|
||||
'''
|
||||
|
||||
from random import randint,random
|
||||
from random import randint, random
|
||||
import numpy as np
|
||||
from operator import neg,and_
|
||||
from operator import neg, and_
|
||||
from functools import reduce
|
||||
|
||||
|
||||
class obj():
|
||||
def __init__(self,data):
|
||||
self.data=np.array(data)
|
||||
def __add__(self,x):
|
||||
data = x.data if self.__class__ == x.__class__ else x
|
||||
class obj():
|
||||
def __init__(self, data):
|
||||
self.data = np.array(data)
|
||||
|
||||
def __add__(self, x):
|
||||
data = x.data if self.__class__ == x.__class__ else x
|
||||
return self.__class__(self.data + data)
|
||||
def __radd__(self,x):
|
||||
data = x.data if self.__class__ == x.__class__ else x
|
||||
return self.__class__(data +self.data)
|
||||
def __iadd__(self,x):
|
||||
data = x.data if self.__class__ == x.__class__ else x
|
||||
|
||||
def __radd__(self, x):
|
||||
data = x.data if self.__class__ == x.__class__ else x
|
||||
return self.__class__(data + self.data)
|
||||
|
||||
def __iadd__(self, x):
|
||||
data = x.data if self.__class__ == x.__class__ else x
|
||||
self.data += data
|
||||
def __mul__(self,x):
|
||||
data = x.data if self.__class__ == x.__class__ else x
|
||||
|
||||
def __mul__(self, x):
|
||||
data = x.data if self.__class__ == x.__class__ else x
|
||||
return self.__class__(self.data * data)
|
||||
def __imul__(self,x):
|
||||
data = x.data if self.__class__ == x.__class__ else x
|
||||
|
||||
def __imul__(self, x):
|
||||
data = x.data if self.__class__ == x.__class__ else x
|
||||
self.data *= data
|
||||
def __rmul__(self,x):
|
||||
data = x.data if self.__class__ == x.__class__ else x
|
||||
|
||||
def __rmul__(self, x):
|
||||
data = x.data if self.__class__ == x.__class__ else x
|
||||
return self.__class__(data * self.data)
|
||||
|
||||
def __neg__(self):
|
||||
return neg(self)
|
||||
|
||||
def __abs__(self):
|
||||
return abs(self.data)
|
||||
'''
|
||||
|
@ -49,42 +57,49 @@ class obj():
|
|||
def data(self,s):
|
||||
self.data = s
|
||||
'''
|
||||
def norm(self,n=0):
|
||||
|
||||
def norm(self, n=0):
|
||||
'''the default is +oo norm'''
|
||||
absolute = abs(self.data)
|
||||
if n < 1 :return max(absolute)
|
||||
if n < 1:
|
||||
return max(absolute)
|
||||
return (sum(absolute**n))**(1/n)
|
||||
|
||||
def hasNorm(self):
|
||||
'''check norm's three necessary conditions:
|
||||
1. not neg
|
||||
2. homogenious (qici)
|
||||
3. triangle inequlity
|
||||
|
||||
|
||||
there is much probably wrong
|
||||
'''
|
||||
bl = reduce(and_,[self.norm(i)>=0 for i in range(3)])
|
||||
bl = reduce(and_, [self.norm(i) >= 0 for i in range(3)])
|
||||
if bl:
|
||||
n = randint(2,100)
|
||||
bl = reduce(and_,[n*(self.norm(i))==(n*self).norm(i) for i in range(3)])
|
||||
n = randint(2, 100)
|
||||
bl = reduce(and_, [n*(self.norm(i)) == (n*self).norm(i)
|
||||
for i in range(3)])
|
||||
if bl:
|
||||
another = self*randint(2,10)-randint(1,100)
|
||||
return reduce(and_,[(another+self).norm(i)<=another.norm(i)+self.norm(i) for i in range(3)])
|
||||
another = self*randint(2, 10)-randint(1, 100)
|
||||
return reduce(and_, [(another+self).norm(i) <= another.norm(i)+self.norm(i) for i in range(3)])
|
||||
return False
|
||||
|
||||
|
||||
|
||||
class vector(obj):
|
||||
def __init__(self,arr):
|
||||
def __init__(self, arr):
|
||||
''' arr: iterable'''
|
||||
self.data =np.array(arr)
|
||||
def innerProduct(self,x):
|
||||
self.data = np.array(arr)
|
||||
|
||||
def innerProduct(self, x):
|
||||
return sum(self.data*x)
|
||||
def outerProduct(self,x):
|
||||
|
||||
def outerProduct(self, x):
|
||||
pass
|
||||
|
||||
|
||||
class matrix(obj):
|
||||
def __init__(self,s):
|
||||
def __init__(self, s):
|
||||
'''s is a list of lists'''
|
||||
self.data=np.mat(s)
|
||||
self.data = np.mat(s)
|
||||
self.T = None
|
||||
self. I = None
|
||||
'''
|
||||
|
@ -104,31 +119,38 @@ class matrix(obj):
|
|||
def I(self,s):
|
||||
self.I = s
|
||||
'''
|
||||
def E(self,n=None):
|
||||
if n is None: n = self.data.shape[0]
|
||||
|
||||
def E(self, n=None):
|
||||
if n is None:
|
||||
n = self.data.shape[0]
|
||||
return np.eye(n)
|
||||
|
||||
def norm(self,n=0):
|
||||
absolute = abs(self.data)
|
||||
def norm(self, n=0):
|
||||
absolute = abs(self.data)
|
||||
if n < 1:
|
||||
# max of one row sum
|
||||
return max([sum(i) for i in absolute])
|
||||
if n==1:return self.norm1()
|
||||
elif n==2:return self.norm2()
|
||||
if n == 1:
|
||||
return self.norm1()
|
||||
elif n == 2:
|
||||
return self.norm2()
|
||||
|
||||
def norm1(self):
|
||||
''' max of sum of cols'''
|
||||
absolute = abs(self.data)
|
||||
return max(absolute.sum(axis=0))
|
||||
return max(absolute.sum(axis=0))
|
||||
|
||||
def norm2(self):
|
||||
''' max of sum of rows'''
|
||||
absolute = abs(self.data)
|
||||
return max(absolute.sum(axis=1))
|
||||
|
||||
def norm_f(self):
|
||||
return sum((self.data**2).sum(axis=1))**0.5
|
||||
|
||||
if __name__ =='__main__':
|
||||
v1 = vector([1,-2,3,4])
|
||||
v2 = vector([0,2,0,5])
|
||||
m1 = matrix([v1,v2,v2,v1])
|
||||
|
||||
if __name__ == '__main__':
|
||||
v1 = vector([1, -2, 3, 4])
|
||||
v2 = vector([0, 2, 0, 5])
|
||||
m1 = matrix([v1, v2, v2, v1])
|
||||
print([v1.norm(i) for i in range(3)])
|
||||
|
||||
|
|
|
@ -12,56 +12,64 @@
|
|||
#include<stdio.h>
|
||||
|
||||
//使用康托展开计算全排列, 下面存储的是0!,1!,2!...(n-1)!
|
||||
long long int fac[100]={};
|
||||
long long int fac[100] = {};
|
||||
void calFac(int n)
|
||||
{
|
||||
int i;
|
||||
fac[0]=1;
|
||||
for(i=1;i<=n;i++){
|
||||
fac[i]=i*fac[i-1];
|
||||
fac[0] = 1;
|
||||
|
||||
for (i = 1; i <= n; i++) {
|
||||
fac[i] = i * fac[i - 1];
|
||||
}
|
||||
}
|
||||
|
||||
void permute(int *arr,int n,int sum)
|
||||
void permute(int *arr, int n, int sum)
|
||||
{
|
||||
/*sum表示全排列由小到大排序后的名次,从0 开始计数, 由名次求出 n位的排列存储到 arr 中*/
|
||||
int i,j,ct=0,k, ct2;
|
||||
int i, j, ct = 0, k, ct2;
|
||||
int flag[n];
|
||||
for(i=0;i<n;i++)flag[i]=1;
|
||||
|
||||
for(i=n-1;i>=0;i--){
|
||||
for(j=i;j>=0;j--){
|
||||
if(j*fac[i]<=sum){
|
||||
ct2=0;
|
||||
for(k=0;k<n;++k){
|
||||
for (i = 0; i < n; i++)flag[i] = 1;
|
||||
|
||||
for (i = n - 1; i >= 0; i--) {
|
||||
for (j = i; j >= 0; j--) {
|
||||
if (j * fac[i] <= sum) {
|
||||
ct2 = 0;
|
||||
|
||||
for (k = 0; k < n; ++k) {
|
||||
//printf("i%d j%d k%d\n",i,j,k);
|
||||
if(flag[k]==1)ct2++;
|
||||
if(ct2>j)break;
|
||||
if (flag[k] == 1)ct2++;
|
||||
|
||||
if (ct2 > j)break;
|
||||
}
|
||||
|
||||
arr[ct++] = k;
|
||||
flag[k]=0;
|
||||
sum -=j*fac[i];
|
||||
flag[k] = 0;
|
||||
sum -= j * fac[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void printArr(int *p,int n)
|
||||
void printArr(int *p, int n)
|
||||
{
|
||||
for(int i=0;i<n;++i)printf("%d, ",p[i]);
|
||||
for (int i = 0; i < n; ++i)printf("%d, ", p[i]);
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int n = 5,arr[n];
|
||||
int n = 5, arr[n];
|
||||
calFac(n);
|
||||
for(int i=0;i<5;++i)arr[i]=i;
|
||||
for(int i=0;i<fac[n];++i){
|
||||
printArr(arr,n);
|
||||
permute(arr,n,i);
|
||||
|
||||
for (int i = 0; i < 5; ++i)arr[i] = i;
|
||||
|
||||
for (int i = 0; i < fac[n]; ++i) {
|
||||
printArr(arr, n);
|
||||
permute(arr, n, i);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
''' mbinary
|
||||
#########################################################################
|
||||
# File : 8Astar.py
|
||||
# File : Astar.py
|
||||
# Author: mbinary
|
||||
# Mail: zhuheqin1@gmail.com
|
||||
# Blog: https://mbinary.xyz
|
||||
|
@ -10,53 +10,62 @@
|
|||
#########################################################################
|
||||
'''
|
||||
|
||||
isVisited = [0]*362880 # 0 for not visited,1 for occured,2 for visited
|
||||
fac = [1,1,2,6,24,120,720,5040,40320]
|
||||
from random import shuffle
|
||||
isVisited = [0]*362880 # 0 for not visited,1 for occured,2 for visited
|
||||
fac = [1, 1, 2, 6, 24, 120, 720, 5040, 40320]
|
||||
lf = len(fac)
|
||||
h = [[0,1,2,1,2,3,2,3,4],
|
||||
[1,0,1,2,1,2,3,2,3],
|
||||
[2,1,0,3,2,1,4,3,2],
|
||||
[1,2,3,0,1,2,1,2,3],
|
||||
[2,1,2,1,0,1,2,1,2],
|
||||
[3,2,1,2,1,0,3,2,1],
|
||||
[2,3,4,1,2,3,0,1,2],
|
||||
[3,2,3,2,1,2,1,0,1],
|
||||
[4,3,2,3,2,1,2,1,0]]
|
||||
h = [[0, 1, 2, 1, 2, 3, 2, 3, 4],
|
||||
[1, 0, 1, 2, 1, 2, 3, 2, 3],
|
||||
[2, 1, 0, 3, 2, 1, 4, 3, 2],
|
||||
[1, 2, 3, 0, 1, 2, 1, 2, 3],
|
||||
[2, 1, 2, 1, 0, 1, 2, 1, 2],
|
||||
[3, 2, 1, 2, 1, 0, 3, 2, 1],
|
||||
[2, 3, 4, 1, 2, 3, 0, 1, 2],
|
||||
[3, 2, 3, 2, 1, 2, 1, 0, 1],
|
||||
[4, 3, 2, 3, 2, 1, 2, 1, 0]]
|
||||
|
||||
|
||||
def cantor(s):
|
||||
sum = 0
|
||||
ls = len(s)
|
||||
for i in range(ls):
|
||||
count = 0
|
||||
for j in range(i+1,ls):
|
||||
if s[i] > s[j]: count +=1
|
||||
for j in range(i+1, ls):
|
||||
if s[i] > s[j]:
|
||||
count += 1
|
||||
sum += count*fac[lf-i-1]
|
||||
return sum
|
||||
|
||||
|
||||
que = []
|
||||
dir = {-3:'u',1:'r',3:'d',-1:'l'}
|
||||
dir = {-3: 'u', 1: 'r', 3: 'd', -1: 'l'}
|
||||
|
||||
|
||||
class state:
|
||||
flag = True
|
||||
def __init__(self,s,x,f,step=0,last=0):
|
||||
|
||||
def __init__(self, s, x, f, step=0, last=0):
|
||||
self.x = x
|
||||
self.s = list(s)
|
||||
self.step = step
|
||||
self.path = []
|
||||
self.last = last
|
||||
self.f = f
|
||||
|
||||
def can(self):
|
||||
cans = [-1,1,3,-3]
|
||||
if self.last in cans :
|
||||
cans = [-1, 1, 3, -3]
|
||||
if self.last in cans:
|
||||
cans.remove(-self.last)
|
||||
if self.x<3:
|
||||
if self.x < 3:
|
||||
cans.remove(-3)
|
||||
if self.x>5:
|
||||
if self.x > 5:
|
||||
cans.remove(3)
|
||||
if self.x%3 is 0:
|
||||
if self.x % 3 is 0:
|
||||
cans.remove(-1)
|
||||
if self.x%3 is 2:
|
||||
if self.x % 3 is 2:
|
||||
cans.remove(1)
|
||||
return cans
|
||||
|
||||
def move(self):
|
||||
cans = self.can()
|
||||
for i in cans:
|
||||
|
@ -65,36 +74,46 @@ class state:
|
|||
s[self.x] = s[tmp]
|
||||
s[tmp] = '9'
|
||||
ct = cantor(s)
|
||||
if isVisited[ct] != 2 :
|
||||
if isVisited[ct] != 2:
|
||||
val = int(s[self.x])
|
||||
f = h[8][tmp] +h[val-1][self.x]-h[8][self.x]-h[val-1][tmp]+self.step+1
|
||||
new = state(s,tmp,f,self.step +1,i)
|
||||
f = h[8][tmp] + h[val-1][self.x] - \
|
||||
h[8][self.x]-h[val-1][tmp]+self.step+1
|
||||
new = state(s, tmp, f, self.step + 1, i)
|
||||
new.path = self.path + [dir[i]]
|
||||
if isVisited[ct] == 1:
|
||||
for i,node in enumerate(que):
|
||||
for i, node in enumerate(que):
|
||||
if mew.s == node.s:
|
||||
del que[i]
|
||||
break
|
||||
else:isVisited[ct] = 1
|
||||
else:
|
||||
isVisited[ct] = 1
|
||||
if que == []:
|
||||
que.append(new)
|
||||
continue
|
||||
for i,node in enumerate(que):
|
||||
if new.f<=node.f:
|
||||
que.insert(i,new)
|
||||
for i, node in enumerate(que):
|
||||
if new.f <= node.f:
|
||||
que.insert(i, new)
|
||||
|
||||
|
||||
def solvable(s):
|
||||
reverse = 0
|
||||
for i in range(8):
|
||||
if s[i] is '9':continue
|
||||
for j in range(i+1,9):
|
||||
if s[i]>s[j]:reverse +=1
|
||||
if reverse % 2 is 0:return True
|
||||
else:return False
|
||||
def getPath(s,index):
|
||||
if s[i] is '9':
|
||||
continue
|
||||
for j in range(i+1, 9):
|
||||
if s[i] > s[j]:
|
||||
reverse += 1
|
||||
if reverse % 2 is 0:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
def getPath(s, index):
|
||||
f = 0
|
||||
for i,j in enumerate(s):
|
||||
f+=h[int(j)-1][i]
|
||||
que.append(state(s,index,f,0,0))
|
||||
for i, j in enumerate(s):
|
||||
f += h[int(j)-1][i]
|
||||
que.append(state(s, index, f, 0, 0))
|
||||
while que != []:
|
||||
cur = que.pop(0)
|
||||
ct = cantor(cur.s)
|
||||
|
@ -102,28 +121,34 @@ def getPath(s,index):
|
|||
if ct is 0:
|
||||
return cur.path
|
||||
cur.move()
|
||||
|
||||
|
||||
def info():
|
||||
print('input a 3x3 matrix in one line')
|
||||
print('from left to right,from up to down')
|
||||
print('from left to right,from up to down')
|
||||
print('such as 56831247x represent matrix as follow')
|
||||
print('5 6 8\n3 1 2\n4 7 x')
|
||||
print('then, if it has, I will print the path of moving x to reach state as follows')
|
||||
print('1 2 3\n4 5 6\n7 8 x')
|
||||
print('print q to quit')
|
||||
|
||||
from random import shuffle
|
||||
|
||||
case = list('12345678x')
|
||||
|
||||
|
||||
def genCase():
|
||||
tmp = case.copy()
|
||||
shuffle(tmp)
|
||||
print(f'Using random data: {tmp}')
|
||||
index = -1
|
||||
for i,j in enumerate(tmp):
|
||||
if j=='x':
|
||||
for i, j in enumerate(tmp):
|
||||
if j == 'x':
|
||||
index = i
|
||||
break
|
||||
tmp[index] = '9'
|
||||
return tmp,index
|
||||
return tmp, index
|
||||
|
||||
|
||||
def isValid(li):
|
||||
for i in '123456789':
|
||||
if not i in li:
|
||||
|
@ -131,12 +156,13 @@ def isValid(li):
|
|||
return False
|
||||
return True
|
||||
|
||||
|
||||
def run():
|
||||
while 1:
|
||||
print('\n\n'+'-'*10+'Game Begins'+ '-'*10)
|
||||
print('\n\n'+'-'*10+'Game Begins' + '-'*10)
|
||||
info()
|
||||
s=input('input: ')
|
||||
if s=='q' or s=='Q' or s=='quit':
|
||||
s = input('input: ')
|
||||
if s == 'q' or s == 'Q' or s == 'quit':
|
||||
break
|
||||
index = s.find('x')
|
||||
li = list(s)
|
||||
|
@ -145,8 +171,9 @@ def run():
|
|||
if not isValid(li):
|
||||
li, index = genCase()
|
||||
if solvable(li):
|
||||
print(''.join(getPath(li,index)))
|
||||
else:print('unsolvable')
|
||||
print(''.join(getPath(li, index)))
|
||||
else:
|
||||
print('unsolvable')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
|
@ -13,22 +13,27 @@ from bitarray import bitarray
|
|||
|
||||
import mmh3
|
||||
|
||||
|
||||
class bloomFilter(set):
|
||||
def __init__(self,size,hash_count):
|
||||
super(bloomFilter,self).__init__()
|
||||
def __init__(self, size, hash_count):
|
||||
super(bloomFilter, self).__init__()
|
||||
self.bits = bitarray(size)
|
||||
self.bits.setall(0)
|
||||
self.size = size
|
||||
self.hash_count = hash_count
|
||||
|
||||
def __len__(self):
|
||||
return self.size
|
||||
|
||||
def __iter__(self):
|
||||
return iter(self.bits)
|
||||
def add(self,item):
|
||||
|
||||
def add(self, item):
|
||||
for i in range(self.hash_count):
|
||||
idx = mmh3.hash(item,i) % self.size
|
||||
self.bits[idx]=1
|
||||
idx = mmh3.hash(item, i) % self.size
|
||||
self.bits[idx] = 1
|
||||
return self
|
||||
def __contains__(self,item):
|
||||
idxs = [mmh3.hash(item,i)%self.size for i in range(self.hash_count)]
|
||||
return all([self.bits[i]==1 for i in idxs])
|
||||
|
||||
def __contains__(self, item):
|
||||
idxs = [mmh3.hash(item, i) % self.size for i in range(self.hash_count)]
|
||||
return all([self.bits[i] == 1 for i in idxs])
|
||||
|
|
|
@ -15,89 +15,105 @@
|
|||
|
||||
设有n个任务由k个可并行工作的机器来完成,完成任务i需要时间为 。试设计一个算法找出完成这n个任务的最佳调度,使完成全部任务的时间最早。
|
||||
'''
|
||||
|
||||
|
||||
|
||||
|
||||
from time import time
|
||||
from functools import total_ordering
|
||||
@total_ordering
|
||||
class record:
|
||||
def __init__(self,nums=None):
|
||||
def __init__(self, nums=None):
|
||||
if nums is None:
|
||||
nums=[]
|
||||
self.nums=nums
|
||||
nums = []
|
||||
self.nums = nums
|
||||
self.sum = sum(nums)
|
||||
def append(self,x):
|
||||
|
||||
def append(self, x):
|
||||
self.nums.append(x)
|
||||
self.sum+=x
|
||||
self.sum += x
|
||||
|
||||
def pop(self):
|
||||
x = self.nums.pop()
|
||||
self.sum-=x
|
||||
self.sum -= x
|
||||
return x
|
||||
|
||||
def __repr__(self):
|
||||
return repr(self.nums)
|
||||
def __lt__(self,r):
|
||||
return self.sum<r.sum
|
||||
def __eq__(self,r):
|
||||
return self.sum==r.sum
|
||||
|
||||
def __lt__(self, r):
|
||||
return self.sum < r.sum
|
||||
|
||||
def __eq__(self, r):
|
||||
return self.sum == r.sum
|
||||
|
||||
def tolist(self):
|
||||
return self.nums.copy()
|
||||
|
||||
def __hash__(self):
|
||||
return self.sum
|
||||
def schedule(works,k):
|
||||
def backtrackSearch(i,lsts):
|
||||
nonlocal best,rst
|
||||
if i==n:
|
||||
cost = max(r.sum for r in lsts )
|
||||
if best>cost:
|
||||
best= cost
|
||||
|
||||
|
||||
def schedule(works, k):
|
||||
def backtrackSearch(i, lsts):
|
||||
nonlocal best, rst
|
||||
if i == n:
|
||||
cost = max(r.sum for r in lsts)
|
||||
if best > cost:
|
||||
best = cost
|
||||
rst = [st.tolist() for st in lsts]
|
||||
else:
|
||||
for cur in set(lsts):
|
||||
if best>cur.sum+works[i]:
|
||||
if best > cur.sum+works[i]:
|
||||
cur.append(works[i])
|
||||
backtrackSearch(i+1,lsts)
|
||||
backtrackSearch(i+1, lsts)
|
||||
cur.pop()
|
||||
def findInitial(i,lst):
|
||||
|
||||
def findInitial(i, lst):
|
||||
nonlocal best
|
||||
if i==n:
|
||||
if i == n:
|
||||
cost = max(lst)
|
||||
if best>cost:best = cost
|
||||
if best > cost:
|
||||
best = cost
|
||||
else:
|
||||
mn = lst[0]
|
||||
idx = 0
|
||||
visited=set()
|
||||
for j,cur in enumerate(lst):
|
||||
visited = set()
|
||||
for j, cur in enumerate(lst):
|
||||
if cur not in visited:
|
||||
visited.add(cur)
|
||||
if mn>cur:
|
||||
if mn > cur:
|
||||
mn = cur
|
||||
idx = j
|
||||
lst[idx]+=works[i]
|
||||
findInitial(i+1,lst)
|
||||
lst[idx]-=works[i]
|
||||
|
||||
lst[idx] += works[i]
|
||||
findInitial(i+1, lst)
|
||||
lst[idx] -= works[i]
|
||||
|
||||
n = len(works)
|
||||
print()
|
||||
print('machine Num:',n)
|
||||
print('works :',works)
|
||||
rst = None
|
||||
works.sort(reverse=True) # key step
|
||||
print('machine Num:', n)
|
||||
print('works :', works)
|
||||
rst = None
|
||||
works.sort(reverse=True) # key step
|
||||
best = sum(works[:n-k+1])
|
||||
t = time()
|
||||
findInitial(0,[0]*k) # key step
|
||||
findInitial(0, [0]*k) # key step
|
||||
t1 = time()-t
|
||||
print('init solution: {} cost time {:.6f}s'.format(best,t1))
|
||||
print('init solution: {} cost time {:.6f}s'.format(best, t1))
|
||||
t = time()
|
||||
backtrackSearch(0,[record() for i in range(k)])
|
||||
backtrackSearch(0, [record() for i in range(k)])
|
||||
t2 = time()-t
|
||||
print('final solution: {} cost time {:.6f}s'.format(best,t2))
|
||||
print('schedule plan:',rst)
|
||||
return best,rst
|
||||
print('final solution: {} cost time {:.6f}s'.format(best, t2))
|
||||
print('schedule plan:', rst)
|
||||
return best, rst
|
||||
|
||||
if __name__=='__main__':
|
||||
|
||||
if __name__ == '__main__':
|
||||
from random import randint
|
||||
schedule([47,20,28,44,21,45,30,39,28,33],3)
|
||||
schedule([98,84,50,23,32,99,22,76,72,61,81,39,76,54,37],5)
|
||||
schedule([39,39,23,45,100,69,21,81,39,55,20,86,34,53,58,99,36,45,46],8)
|
||||
schedule([47, 20, 28, 44, 21, 45, 30, 39, 28, 33], 3)
|
||||
schedule([98, 84, 50, 23, 32, 99, 22, 76, 72, 61, 81, 39, 76, 54, 37], 5)
|
||||
schedule([39, 39, 23, 45, 100, 69, 21, 81, 39, 55,
|
||||
20, 86, 34, 53, 58, 99, 36, 45, 46], 8)
|
||||
|
||||
'''
|
||||
machine Num: 19
|
||||
|
|
|
@ -12,37 +12,39 @@
|
|||
'''
|
||||
设有n件工作要分配给n个人去完成,将工作i分配给第j个人所需费用为c_ij 。试设计一个算法,为每个人分配1件不同的工作,并使总费用达到最小。
|
||||
'''
|
||||
|
||||
|
||||
|
||||
|
||||
import random
|
||||
def dispatch(mat):
|
||||
'''mat: matrix of c_ij'''
|
||||
def _util(i,arrange,cost):
|
||||
def _util(i, arrange, cost):
|
||||
''' for i-th work'''
|
||||
nonlocal total,used,rst
|
||||
if i==n:
|
||||
total=cost
|
||||
rst = arrange.copy() # copy is needed
|
||||
nonlocal total, used, rst
|
||||
if i == n:
|
||||
total = cost
|
||||
rst = arrange.copy() # copy is needed
|
||||
else:
|
||||
for j in range(n):
|
||||
if not used[j] and( total is None or cost+mat[i][j]<total):
|
||||
used[j]=True
|
||||
if not used[j] and(total is None or cost+mat[i][j] < total):
|
||||
used[j] = True
|
||||
arrange[i] = j
|
||||
_util(i+1,arrange,cost+mat[i][j])
|
||||
used[j]=False
|
||||
_util(i+1, arrange, cost+mat[i][j])
|
||||
used[j] = False
|
||||
total = None
|
||||
rst = None
|
||||
n = len(mat)
|
||||
used = [False for i in range(n)]
|
||||
_util(0,[-1]*n,0)
|
||||
return total,rst
|
||||
_util(0, [-1]*n, 0)
|
||||
return total, rst
|
||||
|
||||
|
||||
import random
|
||||
if __name__=='__main__':
|
||||
if __name__ == '__main__':
|
||||
n = 10
|
||||
mat = [[random.randint(1,100) for i in range(n)] for i in range(n)]
|
||||
mat = [[random.randint(1, 100) for i in range(n)] for i in range(n)]
|
||||
print('work matrix: c_ij: work_i and person_j')
|
||||
for i in range(n):
|
||||
print(mat[i])
|
||||
print('result: ',end='')
|
||||
print('result: ', end='')
|
||||
print(dispatch(mat))
|
||||
|
||||
|
||||
|
|
|
@ -12,57 +12,69 @@
|
|||
|
||||
from functools import total_ordering
|
||||
|
||||
|
||||
@total_ordering
|
||||
class node:
|
||||
def __init__(self,val,left=None,right=None):
|
||||
self.val=val
|
||||
def __init__(self, val, left=None, right=None):
|
||||
self.val = val
|
||||
self.frequency = 1
|
||||
self.left=left
|
||||
self.right=right
|
||||
def __lt__(self,x):
|
||||
return self.val<x.val
|
||||
def __eq__(self,x):
|
||||
return self.val==x.val
|
||||
self.left = left
|
||||
self.right = right
|
||||
|
||||
def __lt__(self, x):
|
||||
return self.val < x.val
|
||||
|
||||
def __eq__(self, x):
|
||||
return self.val == x.val
|
||||
|
||||
def inc(self):
|
||||
self.val+=1
|
||||
self.val += 1
|
||||
|
||||
def dec(self):
|
||||
self.val-=1
|
||||
self.val -= 1
|
||||
|
||||
def incFreq(self):
|
||||
self.frequency +=1
|
||||
self.frequency += 1
|
||||
|
||||
def decFreq(self):
|
||||
self.frequency -=1
|
||||
self.frequency -= 1
|
||||
|
||||
|
||||
class binaryTree:
|
||||
def __init__(self,reverse = True):
|
||||
def __init__(self, reverse=True):
|
||||
self.reverse = reverse
|
||||
self.data=None
|
||||
def cmp(self,n1,n2):
|
||||
ret=0
|
||||
if n1 < n2: ret=-1
|
||||
if n1 > n2: ret= 1
|
||||
self.data = None
|
||||
|
||||
def cmp(self, n1, n2):
|
||||
ret = 0
|
||||
if n1 < n2:
|
||||
ret = -1
|
||||
if n1 > n2:
|
||||
ret = 1
|
||||
return ret * -1 if self.reverse else ret
|
||||
def addNode(self,nd):
|
||||
def _add(prt,chd):
|
||||
if self.cmp(prt,chd)==0:
|
||||
|
||||
def addNode(self, nd):
|
||||
def _add(prt, chd):
|
||||
if self.cmp(prt, chd) == 0:
|
||||
prt.incFreq()
|
||||
return
|
||||
if self.cmp(prt,chd)<0:
|
||||
if self.cmp(prt, chd) < 0:
|
||||
|
||||
if not isinstance(nd,node):nd=node(nd)
|
||||
if not self.root :
|
||||
self.root=node(val)
|
||||
if not isinstance(nd, node):
|
||||
nd = node(nd)
|
||||
if not self.root:
|
||||
self.root = node(val)
|
||||
else:
|
||||
if self.root == val:
|
||||
self.root.incfreq()
|
||||
else:
|
||||
cur = self.root
|
||||
def build(self,lst):
|
||||
|
||||
def build(self, lst):
|
||||
dic = {}
|
||||
for i in lst:
|
||||
if i in dic:
|
||||
dic[i].incFreq()
|
||||
else:
|
||||
dic[i] = node(i)
|
||||
self.data =list( dic.values())
|
||||
|
||||
|
||||
self.data = list(dic.values())
|
||||
|
|
|
@ -11,62 +11,76 @@
|
|||
'''
|
||||
|
||||
from functools import partial
|
||||
|
||||
|
||||
class heap:
|
||||
def __init__(self,lst,reverse = False):
|
||||
self.data= heapify(lst,reverse)
|
||||
self.cmp = partial(lambda i,j,r:cmp(self.data[i],self.data[j],r),r= reverse)
|
||||
def __init__(self, lst, reverse=False):
|
||||
self.data = heapify(lst, reverse)
|
||||
self.cmp = partial(lambda i, j, r: cmp(
|
||||
self.data[i], self.data[j], r), r=reverse)
|
||||
|
||||
def getTop(self):
|
||||
return self.data[0]
|
||||
def __getitem__(self,idx):
|
||||
|
||||
def __getitem__(self, idx):
|
||||
return self.data[idx]
|
||||
|
||||
def __bool__(self):
|
||||
return self.data != []
|
||||
|
||||
def popTop(self):
|
||||
ret = self.data[0]
|
||||
n = len(self.data)
|
||||
cur = 1
|
||||
while cur * 2<=n:
|
||||
while cur * 2 <= n:
|
||||
chd = cur-1
|
||||
r_idx = cur*2
|
||||
l_idx = r_idx-1
|
||||
if r_idx==n:
|
||||
if r_idx == n:
|
||||
self.data[chd] = self.data[l_idx]
|
||||
break
|
||||
j = l_idx if self.cmp(l_idx,r_idx)<0 else r_idx
|
||||
j = l_idx if self.cmp(l_idx, r_idx) < 0 else r_idx
|
||||
self.data[chd] = self.data[j]
|
||||
cur = j+1
|
||||
self.data[cur-1] = self.data[-1]
|
||||
self.data.pop()
|
||||
return ret
|
||||
|
||||
def addNode(self,val):
|
||||
def addNode(self, val):
|
||||
self.data.append(val)
|
||||
self.data = one_heapify(len(self.data)-1)
|
||||
|
||||
|
||||
def cmp(n1,n2,reverse=False):
|
||||
def cmp(n1, n2, reverse=False):
|
||||
fac = -1 if reverse else 1
|
||||
if n1 < n2: return -fac
|
||||
elif n1 > n2: return fac
|
||||
if n1 < n2:
|
||||
return -fac
|
||||
elif n1 > n2:
|
||||
return fac
|
||||
return 0
|
||||
|
||||
def heapify(lst,reverse = False):
|
||||
|
||||
def heapify(lst, reverse=False):
|
||||
for i in range(len(lst)):
|
||||
lst = one_heapify(lst,i,reverse)
|
||||
lst = one_heapify(lst, i, reverse)
|
||||
return lst
|
||||
def one_heapify(lst,cur,reverse = False):
|
||||
cur +=1
|
||||
while cur>1:
|
||||
|
||||
|
||||
def one_heapify(lst, cur, reverse=False):
|
||||
cur += 1
|
||||
while cur > 1:
|
||||
chd = cur-1
|
||||
prt = cur//2-1
|
||||
if cmp(lst[prt],lst[chd],reverse)<0:
|
||||
if cmp(lst[prt], lst[chd], reverse) < 0:
|
||||
break
|
||||
lst[prt],lst[chd] = lst[chd], lst[prt]
|
||||
lst[prt], lst[chd] = lst[chd], lst[prt]
|
||||
cur = prt+1
|
||||
return lst
|
||||
def heapSort(lst,reverse = False):
|
||||
|
||||
|
||||
def heapSort(lst, reverse=False):
|
||||
lst = lst.copy()
|
||||
hp = heap(lst,reverse)
|
||||
hp = heap(lst, reverse)
|
||||
ret = []
|
||||
while hp:
|
||||
ret.append(hp.popTop())
|
||||
|
@ -75,10 +89,10 @@ def heapSort(lst,reverse = False):
|
|||
|
||||
if __name__ == '__main__':
|
||||
from random import randint
|
||||
n = randint(10,20)
|
||||
lst = [randint(0,100) for i in range(n)]
|
||||
n = randint(10, 20)
|
||||
lst = [randint(0, 100) for i in range(n)]
|
||||
print('random : ', lst)
|
||||
print('small-heap: ', heapify(lst))
|
||||
print('big-heap : ', heapify(lst,True))
|
||||
print('big-heap : ', heapify(lst, True))
|
||||
print('ascend : ', heapSort(lst))
|
||||
print('descend : ', heapSort(lst,True))
|
||||
print('descend : ', heapSort(lst, True))
|
||||
|
|
|
@ -9,23 +9,28 @@
|
|||
# Description:
|
||||
#########################################################################
|
||||
*/
|
||||
int partition(int *arr,int i,int j)
|
||||
int partition(int *arr, int i, int j)
|
||||
{
|
||||
int pivot = arr[j],p=i,q=j;
|
||||
while(p<q){
|
||||
while(p<q && arr[p]<=pivot)++p;
|
||||
if(p<q)arr[q--]=arr[p];
|
||||
while(p<q && arr[q]>pivot)--q;
|
||||
if(p<q)arr[p++]=arr[q];
|
||||
int pivot = arr[j], p = i, q = j;
|
||||
|
||||
while (p < q) {
|
||||
while (p < q && arr[p] <= pivot)++p;
|
||||
|
||||
if (p < q)arr[q--] = arr[p];
|
||||
|
||||
while (p < q && arr[q] > pivot)--q;
|
||||
|
||||
if (p < q)arr[p++] = arr[q];
|
||||
}
|
||||
arr[p]=pivot;
|
||||
|
||||
arr[p] = pivot;
|
||||
return p;
|
||||
}
|
||||
void quickSort(int *arr,int i,int j)
|
||||
void quickSort(int *arr, int i, int j)
|
||||
{
|
||||
if(i<j){
|
||||
int p = partition(arr,i,j);
|
||||
quickSort(arr,i,p-1);
|
||||
quickSort(arr,p+1,j);
|
||||
if (i < j) {
|
||||
int p = partition(arr, i, j);
|
||||
quickSort(arr, i, p - 1);
|
||||
quickSort(arr, p + 1, j);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,9 @@
|
|||
'''
|
||||
|
||||
|
||||
from time import time
|
||||
|
||||
|
||||
def quickSort(lst):
|
||||
'''A optimized version of Hoare partition'''
|
||||
|
||||
|
@ -31,7 +34,8 @@ def quickSort(lst):
|
|||
return a
|
||||
|
||||
def _sort(a, b):
|
||||
if a >= b: return
|
||||
if a >= b:
|
||||
return
|
||||
mid = (a + b) // 2
|
||||
# 三数取中值置于第一个作为 pivot
|
||||
if (lst[a] < lst[mid]) ^ (lst[b] < lst[mid]):
|
||||
|
@ -55,12 +59,14 @@ def quickSort2(lst):
|
|||
for i in range(a, b):
|
||||
if lst[i] <= pivot:
|
||||
j += 1
|
||||
if i != j: lst[i], lst[j] = lst[j], lst[i]
|
||||
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
|
||||
if a >= b:
|
||||
return
|
||||
mid = (a + b) // 2
|
||||
# 三数取中值置于第一个作为 pivot
|
||||
if (lst[a] < lst[mid]) ^ (lst[b] < lst[mid]):
|
||||
|
@ -84,7 +90,8 @@ def quickSort3(lst):
|
|||
for i in range(a, b):
|
||||
if lst[i] <= pivot:
|
||||
j += 1
|
||||
if i != j: lst[i], lst[j] = lst[j], lst[i]
|
||||
if i != j:
|
||||
lst[i], lst[j] = lst[j], lst[i]
|
||||
lst[j + 1], lst[b] = lst[b], lst[j + 1]
|
||||
return j + 1
|
||||
|
||||
|
@ -104,9 +111,6 @@ def quickSort3(lst):
|
|||
return lst
|
||||
|
||||
|
||||
from time import time
|
||||
|
||||
|
||||
def timer(func, lst, n=100):
|
||||
t = time()
|
||||
for i in range(n):
|
||||
|
|
|
@ -10,43 +10,47 @@
|
|||
#########################################################################
|
||||
'''
|
||||
|
||||
def radixSort(lst,radix=10):
|
||||
ls = [[] for i in range(radix)]
|
||||
mx = max(lst)
|
||||
weight = 1
|
||||
while mx >= weight:
|
||||
for i in lst:
|
||||
ls[(i // weight)%radix].append(i)
|
||||
weight *= radix
|
||||
lst = sum(ls,[])
|
||||
ls = [[] for i in range(radix)]
|
||||
return lst
|
||||
|
||||
def countSort(lst,mn,mx):
|
||||
mark = [0]*(mx-mn+1)
|
||||
for i in lst:
|
||||
mark[i-mn]+=1
|
||||
ret =[]
|
||||
for n,i in enumerate(mark):
|
||||
ret +=[n+mn]*i
|
||||
return ret
|
||||
|
||||
from random import randint
|
||||
from quickSort import quickSort
|
||||
from time import time
|
||||
from random import randint
|
||||
def timer(funcs,span,num=1000000):
|
||||
lst = [randint(0,span) for i in range(num)]
|
||||
print('range({}), {} items'.format(span,num))
|
||||
|
||||
|
||||
def radixSort(lst, radix=10):
|
||||
ls = [[] for i in range(radix)]
|
||||
mx = max(lst)
|
||||
weight = 1
|
||||
while mx >= weight:
|
||||
for i in lst:
|
||||
ls[(i // weight) % radix].append(i)
|
||||
weight *= radix
|
||||
lst = sum(ls, [])
|
||||
ls = [[] for i in range(radix)]
|
||||
return lst
|
||||
|
||||
|
||||
def countSort(lst, mn, mx):
|
||||
mark = [0]*(mx-mn+1)
|
||||
for i in lst:
|
||||
mark[i-mn] += 1
|
||||
ret = []
|
||||
for n, i in enumerate(mark):
|
||||
ret += [n+mn]*i
|
||||
return ret
|
||||
|
||||
|
||||
def timer(funcs, span, num=1000000):
|
||||
lst = [randint(0, span) for i in range(num)]
|
||||
print('range({}), {} items'.format(span, num))
|
||||
for func in funcs:
|
||||
data = lst.copy()
|
||||
t = time()
|
||||
func(data)
|
||||
t = time()-t
|
||||
print('{}: {}s'.format(func.__name__,t))
|
||||
print('{}: {}s'.format(func.__name__, t))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
timer([quickSort,radixSort,sorted],1000000000000,1000)
|
||||
timer([quickSort,radixSort,sorted],10000,100000)
|
||||
lst = [randint(0,100) for i in range(1000)]
|
||||
print(countSort(lst,0,100)==sorted(lst))
|
||||
timer([quickSort, radixSort, sorted], 1000000000000, 1000)
|
||||
timer([quickSort, radixSort, sorted], 10000, 100000)
|
||||
lst = [randint(0, 100) for i in range(1000)]
|
||||
print(countSort(lst, 0, 100) == sorted(lst))
|
||||
|
|
|
@ -11,39 +11,47 @@
|
|||
'''
|
||||
|
||||
from random import randint
|
||||
def select(lst,i):
|
||||
|
||||
|
||||
def select(lst, i):
|
||||
lst = lst.copy()
|
||||
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
|
||||
lst[a]= pivot
|
||||
b -= 1
|
||||
lst[a] = pivot
|
||||
return a
|
||||
|
||||
def _select(a,b):
|
||||
if a>=b: return lst[a]
|
||||
def _select(a, b):
|
||||
if a >= b:
|
||||
return lst[a]
|
||||
# randomized select
|
||||
n = randint(a,b)
|
||||
lst[a],lst[n] = lst[n],lst[a]
|
||||
pos = partition(a,b)
|
||||
if pos>i:
|
||||
return _select(a,pos-1)
|
||||
elif pos<i:
|
||||
return _select(pos+1,b)
|
||||
else:return lst[pos]
|
||||
return _select(0,len(lst)-1)
|
||||
n = randint(a, b)
|
||||
lst[a], lst[n] = lst[n], lst[a]
|
||||
pos = partition(a, b)
|
||||
if pos > i:
|
||||
return _select(a, pos-1)
|
||||
elif pos < i:
|
||||
return _select(pos+1, b)
|
||||
else:
|
||||
return lst[pos]
|
||||
return _select(0, len(lst)-1)
|
||||
|
||||
|
||||
if __name__ =='__main__':
|
||||
lst = [randint(0,1000) for i in range(100)]
|
||||
if __name__ == '__main__':
|
||||
lst = [randint(0, 1000) for i in range(100)]
|
||||
st = sorted(lst)
|
||||
for i in range(10):
|
||||
n = randint(0,99)
|
||||
print('select {}th: \nexpect: {}\ngot: {}'.format(n,st[n],select(lst,n)))
|
||||
n = randint(0, 99)
|
||||
print('select {}th: \nexpect: {}\ngot: {}'.format(
|
||||
n, st[n], select(lst, n)))
|
||||
|
|
|
@ -10,26 +10,28 @@
|
|||
#########################################################################
|
||||
'''
|
||||
|
||||
def shellSort(s,gaps=None):
|
||||
|
||||
def shellSort(s, gaps=None):
|
||||
if gaps is None:
|
||||
gaps = [127,63,31,15,7,3,1]
|
||||
gaps = [127, 63, 31, 15, 7, 3, 1]
|
||||
n = len(s)
|
||||
for gap in gaps:
|
||||
for j in range(gap,n):
|
||||
for j in range(gap, n):
|
||||
cur = j
|
||||
num = s[j]
|
||||
while cur>=gap and num < s[cur-gap]:
|
||||
while cur >= gap and num < s[cur-gap]:
|
||||
s[cur] = s[cur-gap]
|
||||
cur-=gap
|
||||
cur -= gap
|
||||
s[cur] = num
|
||||
return s
|
||||
|
||||
if __name__=='__main__':
|
||||
|
||||
if __name__ == '__main__':
|
||||
from random import randint
|
||||
import sys
|
||||
n = 20
|
||||
if len(sys.argv)>1:
|
||||
if len(sys.argv) > 1:
|
||||
n = int(sys.argv[1])
|
||||
nums = [randint(1,100) for i in range(n)]
|
||||
nums = [randint(1, 100) for i in range(n)]
|
||||
print(nums)
|
||||
print(shellSort(nums))
|
||||
|
|
|
@ -11,48 +11,55 @@
|
|||
#########################################################################
|
||||
'''
|
||||
|
||||
|
||||
def getPrefixFunc(s):
|
||||
'''return the list of prefix function of s'''
|
||||
length = 0
|
||||
i = 1
|
||||
n = len(s)
|
||||
ret = [0]
|
||||
while i<n:
|
||||
if s[i]==s[length]:
|
||||
length +=1
|
||||
while i < n:
|
||||
if s[i] == s[length]:
|
||||
length += 1
|
||||
ret.append(length)
|
||||
i+=1
|
||||
i += 1
|
||||
else:
|
||||
if length==0:
|
||||
if length == 0:
|
||||
ret.append(0)
|
||||
i+=1
|
||||
i += 1
|
||||
else:
|
||||
length = ret[length-1]
|
||||
return ret
|
||||
|
||||
def findAll(s,p):
|
||||
pre = getPrefixFunc(p)
|
||||
i = j =0
|
||||
n,m = len(s),len(p)
|
||||
ret = []
|
||||
while i<n:
|
||||
if s[i]==p[j]:
|
||||
i+=1
|
||||
j+=1
|
||||
if j==m:
|
||||
ret.append(i-j)
|
||||
j=pre[j-1]
|
||||
else:
|
||||
if j==0: i+=1
|
||||
else: j = pre[j-1]
|
||||
return ret
|
||||
def randStr(n=3):
|
||||
return [randint(ord('a'),ord('z')) for i in range(n)]
|
||||
|
||||
if __name__ =='__main__':
|
||||
def findAll(s, p):
|
||||
pre = getPrefixFunc(p)
|
||||
i = j = 0
|
||||
n, m = len(s), len(p)
|
||||
ret = []
|
||||
while i < n:
|
||||
if s[i] == p[j]:
|
||||
i += 1
|
||||
j += 1
|
||||
if j == m:
|
||||
ret.append(i-j)
|
||||
j = pre[j-1]
|
||||
else:
|
||||
if j == 0:
|
||||
i += 1
|
||||
else:
|
||||
j = pre[j-1]
|
||||
return ret
|
||||
|
||||
|
||||
def randStr(n=3):
|
||||
return [randint(ord('a'), ord('z')) for i in range(n)]
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from random import randint
|
||||
s = randStr(50)
|
||||
p = randStr(1)
|
||||
print(s)
|
||||
print(p)
|
||||
print(findAll(s,p))
|
||||
print(findAll(s, p))
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#########################################################################
|
||||
'''
|
||||
|
||||
|
||||
class Solution:
|
||||
def longestPalindrome(self, s):
|
||||
"""
|
||||
|
@ -17,22 +18,23 @@ class Solution:
|
|||
:rtype: str
|
||||
"""
|
||||
n = len(s)
|
||||
s2='$#'+'#'.join(s)+'#@'
|
||||
ct =[0]*(2*n+4)
|
||||
mid=1
|
||||
for cur in range(1,2*n+2):
|
||||
if cur<mid+ct[mid]:
|
||||
ct[cur] = min(ct[2*mid-cur],mid+ct[mid]-cur)
|
||||
s2 = '$#'+'#'.join(s)+'#@'
|
||||
ct = [0]*(2*n+4)
|
||||
mid = 1
|
||||
for cur in range(1, 2*n+2):
|
||||
if cur < mid+ct[mid]:
|
||||
ct[cur] = min(ct[2*mid-cur], mid+ct[mid]-cur)
|
||||
else:
|
||||
ct[cur]=1
|
||||
while s2[cur-ct[cur]]==s2[cur+ct[cur]]:
|
||||
ct[cur]+=1
|
||||
if cur+ct[cur] > mid+ct[mid]:mid = cur
|
||||
ct[cur] = 1
|
||||
while s2[cur-ct[cur]] == s2[cur+ct[cur]]:
|
||||
ct[cur] += 1
|
||||
if cur+ct[cur] > mid+ct[mid]:
|
||||
mid = cur
|
||||
mx = max(ct)
|
||||
idxs = [i for i,j in enumerate(ct) if j == mx]
|
||||
idxs = [i for i, j in enumerate(ct) if j == mx]
|
||||
p = idxs[0]
|
||||
for i in idxs:
|
||||
if s2[i]=='#':p = i
|
||||
rst =s2[p-mx+1:p+mx].replace('#','')
|
||||
return rst
|
||||
|
||||
if s2[i] == '#':
|
||||
p = i
|
||||
rst = s2[p-mx+1:p+mx].replace('#', '')
|
||||
return rst
|
||||
|
|
|
@ -15,44 +15,50 @@ import re
|
|||
|
||||
|
||||
class markov:
|
||||
def __init__(self,txt):
|
||||
self.words= self.clean(txt)
|
||||
self.dic = self.getDic(self.words)
|
||||
def clean(self,text):
|
||||
text = text.replace("\n", " ");
|
||||
text = text.replace("\"", "");
|
||||
|
||||
# 保证每个标点符号都和前面的单词在一起
|
||||
# 这样不会被剔除,保留在马尔可夫链中
|
||||
punctuation = [',', '.', ';',':']
|
||||
for symbol in punctuation:
|
||||
text = text.replace(symbol, symbol+" ");
|
||||
|
||||
return re.split(' +',text)
|
||||
|
||||
def getDic(self,words):
|
||||
dic = {}
|
||||
end = len(words)
|
||||
for i in range(1,end):
|
||||
if words[i-1] not in dic:
|
||||
dic[words[i-1]] = {words[i]:1}
|
||||
elif words[i] not in dic[words[i-1]]:
|
||||
dic[words[i-1]][words[i]] = 1
|
||||
else: dic[words[i-1]][words[i]] +=1
|
||||
return dic
|
||||
def getSum(self,dic):
|
||||
if '%size' not in dic:
|
||||
dic['%size'] = sum(list(dic.values()))
|
||||
return dic['%size']
|
||||
def nextWord(self,word):
|
||||
k = randint(1,self.getSum(self.dic[word]))
|
||||
for i,j in self.dic[word].items():
|
||||
k-=j
|
||||
if k<=0:return i
|
||||
def genSentence(self,begin = 'I',length = 30):
|
||||
li = [begin]
|
||||
nextWord= begin
|
||||
for i in range(1,length):
|
||||
nextWord= self.nextWord(nextWord)
|
||||
li.append(nextWord)
|
||||
return ' '.join(li)
|
||||
def __init__(self, txt):
|
||||
self.words = self.clean(txt)
|
||||
self.dic = self.getDic(self.words)
|
||||
|
||||
def clean(self, text):
|
||||
text = text.replace("\n", " ")
|
||||
text = text.replace("\"", "")
|
||||
|
||||
# 保证每个标点符号都和前面的单词在一起
|
||||
# 这样不会被剔除,保留在马尔可夫链中
|
||||
punctuation = [',', '.', ';', ':']
|
||||
for symbol in punctuation:
|
||||
text = text.replace(symbol, symbol+" ")
|
||||
|
||||
return re.split(' +', text)
|
||||
|
||||
def getDic(self, words):
|
||||
dic = {}
|
||||
end = len(words)
|
||||
for i in range(1, end):
|
||||
if words[i-1] not in dic:
|
||||
dic[words[i-1]] = {words[i]: 1}
|
||||
elif words[i] not in dic[words[i-1]]:
|
||||
dic[words[i-1]][words[i]] = 1
|
||||
else:
|
||||
dic[words[i-1]][words[i]] += 1
|
||||
return dic
|
||||
|
||||
def getSum(self, dic):
|
||||
if '%size' not in dic:
|
||||
dic['%size'] = sum(list(dic.values()))
|
||||
return dic['%size']
|
||||
|
||||
def nextWord(self, word):
|
||||
k = randint(1, self.getSum(self.dic[word]))
|
||||
for i, j in self.dic[word].items():
|
||||
k -= j
|
||||
if k <= 0:
|
||||
return i
|
||||
|
||||
def genSentence(self, begin='I', length=30):
|
||||
li = [begin]
|
||||
nextWord = begin
|
||||
for i in range(1, length):
|
||||
nextWord = self.nextWord(nextWord)
|
||||
li.append(nextWord)
|
||||
return ' '.join(li)
|
||||
|
|
|
@ -27,34 +27,37 @@ When the window is no longer valid, start expanding again using the right pointe
|
|||
'''
|
||||
|
||||
from collections import defaultdict
|
||||
|
||||
|
||||
class Solution:
|
||||
def minWindow(self, s: str, t: str) -> str:
|
||||
def expand(j,lacked,dic):
|
||||
while j<n and lacked:
|
||||
def expand(j, lacked, dic):
|
||||
while j < n and lacked:
|
||||
if s[j] in lacked:
|
||||
lacked[s[j]]-=1
|
||||
if lacked[s[j]]==0:
|
||||
lacked[s[j]] -= 1
|
||||
if lacked[s[j]] == 0:
|
||||
del lacked[s[j]]
|
||||
dic[s[j]]+=1
|
||||
j+=1
|
||||
dic[s[j]] += 1
|
||||
j += 1
|
||||
return j
|
||||
def contract(left,right):
|
||||
for i in range(left,right):
|
||||
dic[s[i]]-=1
|
||||
if dic[s[i]]==0:
|
||||
|
||||
def contract(left, right):
|
||||
for i in range(left, right):
|
||||
dic[s[i]] -= 1
|
||||
if dic[s[i]] == 0:
|
||||
del dic[s[i]]
|
||||
if s[i] in chars and (s[i] not in dic or dic[s[i]]<chars[s[i]]):
|
||||
return i+1,{s[i]:1}
|
||||
n ,i, j= len(s),0,0
|
||||
if s[i] in chars and (s[i] not in dic or dic[s[i]] < chars[s[i]]):
|
||||
return i+1, {s[i]: 1}
|
||||
n, i, j = len(s), 0, 0
|
||||
ans = ''
|
||||
dic,lacked = defaultdict(int), defaultdict(int)
|
||||
dic, lacked = defaultdict(int), defaultdict(int)
|
||||
for c in t:
|
||||
lacked[c]+=1
|
||||
lacked[c] += 1
|
||||
chars = lacked.copy()
|
||||
while j<n and lacked:
|
||||
j = expand(j,lacked,dic)
|
||||
if not lacked:
|
||||
i,lacked=contract(i,j)
|
||||
if ans=='' or len(ans)>j-i+1:
|
||||
while j < n and lacked:
|
||||
j = expand(j, lacked, dic)
|
||||
if not lacked:
|
||||
i, lacked = contract(i, j)
|
||||
if ans == '' or len(ans) > j-i+1:
|
||||
ans = s[i-1:j]
|
||||
return ans
|
||||
return ans
|
||||
|
|
|
@ -11,50 +11,62 @@
|
|||
#########################################################################
|
||||
'''
|
||||
|
||||
|
||||
def isPrime(x):
|
||||
for i in range(2,int(x**0.5)+1):
|
||||
if x%i==0:return False
|
||||
for i in range(2, int(x**0.5)+1):
|
||||
if x % i == 0:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def getPrime(x):
|
||||
'''return a prime which is bigger than x'''
|
||||
for i in range(x,2*x):
|
||||
if isPrime(i):return i
|
||||
def findAll(s,p):
|
||||
for i in range(x, 2*x):
|
||||
if isPrime(i):
|
||||
return i
|
||||
|
||||
|
||||
def findAll(s, p):
|
||||
'''s: string p: pattern'''
|
||||
dic={}
|
||||
n,m = len(s),len(p)
|
||||
d=0 #radix
|
||||
dic = {}
|
||||
n, m = len(s), len(p)
|
||||
d = 0 # radix
|
||||
for c in s:
|
||||
if c not in dic:
|
||||
dic[c]=d
|
||||
d+=1
|
||||
dic[c] = d
|
||||
d += 1
|
||||
sm = 0
|
||||
for c in p:
|
||||
if c not in dic:return []
|
||||
if c not in dic:
|
||||
return []
|
||||
sm = sm*d+dic[c]
|
||||
|
||||
ret = []
|
||||
cur = 0
|
||||
for i in range(m): cur=cur*d + dic[s[i]]
|
||||
if cur==sm:ret.append(0)
|
||||
for i in range(m):
|
||||
cur = cur*d + dic[s[i]]
|
||||
if cur == sm:
|
||||
ret.append(0)
|
||||
tmp = n-m
|
||||
q = getPrime(m)
|
||||
cur = cur%q
|
||||
sm = sm%q
|
||||
cur = cur % q
|
||||
sm = sm % q
|
||||
exp = d**(m-1) % q
|
||||
for i in range(m,n):
|
||||
for i in range(m, n):
|
||||
cur = ((cur-dic[s[i-m]]*exp)*d+dic[s[i]]) % q
|
||||
if cur == sm and p==s[i-m+1:i+1]:
|
||||
if cur == sm and p == s[i-m+1:i+1]:
|
||||
ret.append(i-m+1)
|
||||
return ret
|
||||
|
||||
def randStr(n=3):
|
||||
return [randint(ord('a'),ord('z')) for i in range(n)]
|
||||
|
||||
if __name__ =='__main__':
|
||||
def randStr(n=3):
|
||||
return [randint(ord('a'), ord('z')) for i in range(n)]
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from random import randint
|
||||
s = randStr(50)
|
||||
p = randStr(1)
|
||||
print(s)
|
||||
print(p)
|
||||
print(findAll(s,p))
|
||||
print(findAll(s, p))
|
||||
|
|
103
string/rotate.py
103
string/rotate.py
|
@ -17,77 +17,80 @@
|
|||
#########################################################################
|
||||
'''
|
||||
|
||||
def rotate(s,k,right=False):
|
||||
def reverse(a,b):
|
||||
while a<b:
|
||||
s[a],s[b]=s[b],s[a]
|
||||
a+=1
|
||||
b-=1
|
||||
n=len(s)
|
||||
k = k%n if not right else n-k%n
|
||||
reverse(0,k-1)
|
||||
reverse(k,n-1)
|
||||
reverse(0,n-1)
|
||||
|
||||
def rotate(s, k, right=False):
|
||||
def reverse(a, b):
|
||||
while a < b:
|
||||
s[a], s[b] = s[b], s[a]
|
||||
a += 1
|
||||
b -= 1
|
||||
n = len(s)
|
||||
k = k % n if not right else n-k % n
|
||||
reverse(0, k-1)
|
||||
reverse(k, n-1)
|
||||
reverse(0, n-1)
|
||||
return s
|
||||
|
||||
|
||||
|
||||
def rotate2(s,k,right=False):
|
||||
def swap(a,b,c):
|
||||
def rotate2(s, k, right=False):
|
||||
def swap(a, b, c):
|
||||
for i in range(c):
|
||||
s[a+i],s[b+i] = s[b+i],s[a+i]
|
||||
def _rot(pl,pr):
|
||||
s[a+i], s[b+i] = s[b+i], s[a+i]
|
||||
|
||||
def _rot(pl, pr):
|
||||
''' swap s[pl,pr) , s[pr:]'''
|
||||
if pr==n:return
|
||||
if pr-pl<=n-pr:
|
||||
swap(pl,pr,pr-pl)
|
||||
_rot(pr,2*pr-pl)
|
||||
if pr == n:
|
||||
return
|
||||
if pr-pl <= n-pr:
|
||||
swap(pl, pr, pr-pl)
|
||||
_rot(pr, 2*pr-pl)
|
||||
else:
|
||||
swap(pl,pr,n-pr)
|
||||
_rot(n-pr+pl,pr)
|
||||
n=len(s)
|
||||
k = k%n if not right else n-k%n
|
||||
_rot(0,k)
|
||||
swap(pl, pr, n-pr)
|
||||
_rot(n-pr+pl, pr)
|
||||
n = len(s)
|
||||
k = k % n if not right else n-k % n
|
||||
_rot(0, k)
|
||||
return s
|
||||
|
||||
|
||||
def rotate3(s, k, right=False):
|
||||
def gcd(a, b):
|
||||
if b == 0:
|
||||
return a
|
||||
return gcd(b, a % b)
|
||||
|
||||
def rotate3(s,k,right=False):
|
||||
def gcd(a,b):
|
||||
if b==0:return a
|
||||
return gcd(b,a%b)
|
||||
|
||||
n=len(s)
|
||||
k = k%n if not right else n-k%n
|
||||
r=gcd(n,k)
|
||||
n = len(s)
|
||||
k = k % n if not right else n-k % n
|
||||
r = gcd(n, k)
|
||||
for i in range(r):
|
||||
tmp = s[i]
|
||||
j = (i+k)%n
|
||||
while j!=i:
|
||||
j = (i+k) % n
|
||||
while j != i:
|
||||
s[j-k] = s[j]
|
||||
j = (j+k)%n
|
||||
s[(j-k+n)%n] = tmp
|
||||
j = (j+k) % n
|
||||
s[(j-k+n) % n] = tmp
|
||||
return s
|
||||
|
||||
|
||||
def test():
|
||||
def f(func,*args,right=False):
|
||||
print(' '.join(['testing:',func.__name__,str(args),'right=',str(right)]))
|
||||
rst = func(*args,right=right)
|
||||
print('result',rst)
|
||||
def f(func, *args, right=False):
|
||||
print(' '.join(['testing:', func.__name__,
|
||||
str(args), 'right=', str(right)]))
|
||||
rst = func(*args, right=right)
|
||||
print('result', rst)
|
||||
print()
|
||||
return f
|
||||
|
||||
|
||||
if __name__=='__main__':
|
||||
s=[i for i in range(10)]
|
||||
tester= test()
|
||||
tester(rotate,s,4,right=True)
|
||||
tester(rotate,s,4)
|
||||
tester(rotate2,s,2,right=True)
|
||||
tester(rotate2,s,2)
|
||||
tester(rotate3,s,132,right=True)
|
||||
tester(rotate3,s,132)
|
||||
if __name__ == '__main__':
|
||||
s = [i for i in range(10)]
|
||||
tester = test()
|
||||
tester(rotate, s, 4, right=True)
|
||||
tester(rotate, s, 4)
|
||||
tester(rotate2, s, 2, right=True)
|
||||
tester(rotate2, s, 2)
|
||||
tester(rotate3, s, 132, right=True)
|
||||
tester(rotate3, s, 132)
|
||||
|
||||
|
||||
'''
|
||||
|
|
|
@ -12,66 +12,74 @@
|
|||
'''
|
||||
|
||||
|
||||
|
||||
def getPos(pattern):
|
||||
dic = {}
|
||||
for i,j in enumerate(pattern[::-1]):
|
||||
for i, j in enumerate(pattern[::-1]):
|
||||
if j not in dic:
|
||||
dic[j]= i
|
||||
dic[j] = i
|
||||
return dic
|
||||
def find(s,p):
|
||||
|
||||
|
||||
def find(s, p):
|
||||
dic = getPos(p)
|
||||
ps = pp = 0
|
||||
ns = len(s)
|
||||
np = len(p)
|
||||
while ps<ns and pp<np:
|
||||
while ps < ns and pp < np:
|
||||
if s[ps] == p[pp]:
|
||||
ps,pp = ps+1,pp+1
|
||||
ps, pp = ps+1, pp+1
|
||||
else:
|
||||
idx = ps+ np-pp
|
||||
if idx >=ns:return -1
|
||||
idx = ps + np-pp
|
||||
if idx >= ns:
|
||||
return -1
|
||||
ch = s[idx]
|
||||
if ch in dic:
|
||||
ps += dic[ch]+1-pp
|
||||
else:
|
||||
ps = idx+1
|
||||
pp = 0
|
||||
if pp==np:return ps-np
|
||||
if pp == np:
|
||||
return ps-np
|
||||
else:
|
||||
return -1
|
||||
def findAll(s,p):
|
||||
|
||||
|
||||
def findAll(s, p):
|
||||
ns = len(s)
|
||||
np = len(p)
|
||||
i = 0
|
||||
ret = []
|
||||
while s:
|
||||
print(s,p)
|
||||
tmp = find(s,p)
|
||||
if tmp==-1: break
|
||||
print(s, p)
|
||||
tmp = find(s, p)
|
||||
if tmp == -1:
|
||||
break
|
||||
ret.append(i+tmp)
|
||||
end = tmp+np
|
||||
i +=end
|
||||
i += end
|
||||
s = s[end:]
|
||||
return ret
|
||||
|
||||
|
||||
|
||||
def randStr(n=3):
|
||||
return [randint(ord('a'),ord('z')) for i in range(n)]
|
||||
return [randint(ord('a'), ord('z')) for i in range(n)]
|
||||
|
||||
|
||||
def test(n):
|
||||
s = randStr(n)
|
||||
p = randStr(3)
|
||||
str_s = ''.join((chr(i) for i in s))
|
||||
str_p = ''.join((chr(i) for i in p))
|
||||
n1 = find(s,p)
|
||||
n2 = str_s.find(str_p) # 利用已有的 str find 算法检验
|
||||
if n1!=n2:
|
||||
print(n1,n2,str_p,str_s)
|
||||
n1 = find(s, p)
|
||||
n2 = str_s.find(str_p) # 利用已有的 str find 算法检验
|
||||
if n1 != n2:
|
||||
print(n1, n2, str_p, str_s)
|
||||
return False
|
||||
return True
|
||||
if __name__ =='__main__':
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from random import randint
|
||||
n = 1000
|
||||
suc = sum(test(n) for i in range(n))
|
||||
print('test {n} times, success {suc} times'.format(n=n,suc=suc))
|
||||
print('test {n} times, success {suc} times'.format(n=n, suc=suc))
|
||||
|
|
|
@ -33,25 +33,26 @@ 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)
|
||||
n, m = len(s), len(p)
|
||||
last = [False]*(n+1)
|
||||
last[0] = True
|
||||
for j in range(m):
|
||||
if p[j]=='*':
|
||||
if p[j] == '*':
|
||||
for i in range(n):
|
||||
last[i+1] = last[i+1] or last[i]
|
||||
elif p[j]=='?':
|
||||
elif p[j] == '?':
|
||||
last.pop()
|
||||
last.insert(0,False)
|
||||
last.insert(0, False)
|
||||
else:
|
||||
li = [False]
|
||||
for i in range(n):
|
||||
li.append( last[i] and p[j]==s[i])
|
||||
li.append(last[i] and p[j] == s[i])
|
||||
last = li
|
||||
return last[-1]
|
||||
|
|
|
@ -14,39 +14,47 @@ import re
|
|||
import sys
|
||||
from translate import Translator as TR
|
||||
|
||||
FORMULA = re.compile(r'\${1,2}(?P<formula>.+?)\${1,2}',re.DOTALL)
|
||||
FORMULA = re.compile(r'\${1,2}(?P<formula>.+?)\${1,2}', re.DOTALL)
|
||||
Chinese = re.compile(u"(?P<chinese>[\u4e00-\u9fa5]+)")
|
||||
API = 'https://latex.codecogs.com/gif.latex?'
|
||||
|
||||
|
||||
def codecog(f):
|
||||
if os.path.exists(f) and f.endswith('.md'):
|
||||
with open(f) as fp:
|
||||
txt = fp.read()
|
||||
with open(f,'w') as fp:
|
||||
fp.write(re.sub(FORMULA,covert,txt))
|
||||
with open(f, 'w') as fp:
|
||||
fp.write(re.sub(FORMULA, covert, txt))
|
||||
else:
|
||||
s = re.sub(FORMULA,covert,f)
|
||||
s = re.sub(FORMULA, covert, f)
|
||||
print(s)
|
||||
|
||||
|
||||
def covert(matched):
|
||||
s = matched.group('formula').strip('$ ')
|
||||
s = re.sub(Chinese,zh2en,s)
|
||||
s = re.sub(r'\r+|\n+|\\n',' ',s)
|
||||
s = re.sub(' +','&space;',s)
|
||||
return '![]({})'.format(API+s)
|
||||
s = re.sub(Chinese, zh2en, s)
|
||||
s = re.sub(r'\r+|\n+|\\n', ' ', s)
|
||||
s = re.sub(' +', '&space;', s)
|
||||
return '![]({})'.format(API+s)
|
||||
|
||||
|
||||
def zh2en(txt):
|
||||
s = txt.group('chinese').strip()
|
||||
tran = TR(to_lang='en',from_lang='zh')
|
||||
tran = TR(to_lang='en', from_lang='zh')
|
||||
en = tran.translate(s)
|
||||
return re.sub(' +','-',en)
|
||||
return re.sub(' +', '-', en)
|
||||
|
||||
|
||||
def handle(path):
|
||||
if os.path.isdir(path):
|
||||
for p,ds,fs in os.walk(path):
|
||||
for p, ds, fs in os.walk(path):
|
||||
for f in fs:
|
||||
if f.endswith('.md'):
|
||||
codecog(os.path.join(p,f))
|
||||
codecog(os.path.join(p, f))
|
||||
else:
|
||||
codecog(path)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
args = sys.argv[1:]
|
||||
if not args:
|
||||
|
|
|
@ -16,17 +16,18 @@ from config import README
|
|||
|
||||
parser = ArgumentParser()
|
||||
|
||||
parser.add_argument('-p','--path',default='.',help='path to walk')
|
||||
parser.add_argument('-f','--fileinclude',action='store_true',default=True,help='if has, list files and dirs, else only dirs')
|
||||
parser.add_argument('-d','--depth', type = int, default = 2)
|
||||
#获取参数
|
||||
parser.add_argument('-p', '--path', default='.', help='path to walk')
|
||||
parser.add_argument('-f', '--fileinclude', action='store_true',
|
||||
default=True, help='if has, list files and dirs, else only dirs')
|
||||
parser.add_argument('-d', '--depth', type=int, default=2)
|
||||
# 获取参数
|
||||
args = parser.parse_args()
|
||||
FILE = args.fileinclude
|
||||
PATH = args.path
|
||||
DEPTH = args.depth
|
||||
|
||||
|
||||
idxs = tree(PATH,DEPTH,FILE)
|
||||
idxs = tree(PATH, DEPTH, FILE)
|
||||
s = README.format(index='\n'.join(idxs))
|
||||
with open('README.md','w') as f:
|
||||
with open('README.md', 'w') as f:
|
||||
f.write(s)
|
||||
|
|
|
@ -15,44 +15,55 @@ import sys
|
|||
import time
|
||||
from config import HEAD
|
||||
count = 0
|
||||
|
||||
|
||||
def handleFile(path):
|
||||
global count
|
||||
head = getHead(path)
|
||||
if head =='': return
|
||||
with open(path,'r',encoding='utf8',errors='ignore') as f:
|
||||
if head == '':
|
||||
return
|
||||
with open(path, 'r', encoding='utf8', errors='ignore') as f:
|
||||
s = f.read()
|
||||
if 'mbinary' in s:
|
||||
return
|
||||
count +=1
|
||||
count += 1
|
||||
name = os.path.basename(path)
|
||||
print('[{count}]: Adding head info to {name}'.format(count=count,name=name))
|
||||
with open(path,'w') as f:
|
||||
print('[{count}]: Adding head info to {name}'.format(count=count, name=name))
|
||||
with open(path, 'w') as f:
|
||||
f.write(head+s)
|
||||
|
||||
|
||||
def getHead(path):
|
||||
name = os.path.basename(path)
|
||||
# skip self or hidden file
|
||||
if name == os.path.basename(__file__) or name[0]=='.': return ''
|
||||
suf = name[name.rfind('.')+1 :]
|
||||
begin = end =''
|
||||
if name == os.path.basename(__file__) or name[0] == '.':
|
||||
return ''
|
||||
suf = name[name.rfind('.')+1:]
|
||||
begin = end = ''
|
||||
if suf == 'py':
|
||||
begin = end = "'''"
|
||||
elif suf in ['c','cc','cpp','java']:
|
||||
begin,end = '/*','*/'
|
||||
elif suf in ['c', 'cc', 'cpp', 'java']:
|
||||
begin, end = '/*', '*/'
|
||||
elif suf == 'sh':
|
||||
begin = end = '#'
|
||||
else:return ''
|
||||
else:
|
||||
return ''
|
||||
timeStamp = time.localtime(os.stat(path).st_ctime)
|
||||
ctime = time.strftime('%Y-%m-%d %H:%M',timeStamp)
|
||||
return HEAD.format(begin=begin,end=end,ctime=ctime,name = name)
|
||||
ctime = time.strftime('%Y-%m-%d %H:%M', timeStamp)
|
||||
return HEAD.format(begin=begin, end=end, ctime=ctime, name=name)
|
||||
|
||||
|
||||
def handleDir(dirPath):
|
||||
gen = os.walk(dirPath)
|
||||
for path,dirs,files in gen:
|
||||
for f in files: handleFile(os.path.join(path,f))
|
||||
for path, dirs, files in gen:
|
||||
for f in files:
|
||||
handleFile(os.path.join(path, f))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
works = sys.argv[1:]
|
||||
if works==[] : works = ['.']
|
||||
if works == []:
|
||||
works = ['.']
|
||||
for one in works:
|
||||
if not os.path.exists(one):
|
||||
print('[PathError]: {one} not exists'.format(one=one))
|
||||
|
|
|
@ -13,42 +13,51 @@
|
|||
import os
|
||||
from argparse import ArgumentParser
|
||||
|
||||
#命令行输入参数处理
|
||||
# 命令行输入参数处理
|
||||
parser = ArgumentParser()
|
||||
|
||||
parser.add_argument('-p','--path',default='.',help='path to walk')
|
||||
parser.add_argument('-f','--fileinclude',action='store_true',help='if has, list files and dirs, else only dirs')
|
||||
parser.add_argument('-d','--depth', type = int, default = 2)
|
||||
#获取参数
|
||||
parser.add_argument('-p', '--path', default='.', help='path to walk')
|
||||
parser.add_argument('-f', '--fileinclude', action='store_true',
|
||||
help='if has, list files and dirs, else only dirs')
|
||||
parser.add_argument('-d', '--depth', type=int, default=2)
|
||||
# 获取参数
|
||||
args = parser.parse_args()
|
||||
FILE = args.fileinclude
|
||||
PATH = args.path
|
||||
DEPTH = args.depth
|
||||
|
||||
|
||||
def mklink(path):
|
||||
return '* [{name}]({path})'.format(name=os.path.basename(path),path=path)
|
||||
return '* [{name}]({path})'.format(name=os.path.basename(path), path=path)
|
||||
|
||||
|
||||
def clean(paths):
|
||||
ret = []
|
||||
for path in paths:
|
||||
name = os.path.basename(path)
|
||||
if not ( name.startswith('.') or name.startswith('__')):
|
||||
if not (name.startswith('.') or name.startswith('__')):
|
||||
ret.append(path)
|
||||
return ret
|
||||
|
||||
def tree(path='.',depth=2,showfile=False):
|
||||
|
||||
def tree(path='.', depth=2, showfile=False):
|
||||
li = []
|
||||
if os.path.isdir(path):li = os.listdir(path)
|
||||
else:li=[path]
|
||||
items = [os.path.join(path,i) for i in li if not i.startswith('.')]
|
||||
if os.path.isdir(path):
|
||||
li = os.listdir(path)
|
||||
else:
|
||||
li = [path]
|
||||
items = [os.path.join(path, i) for i in li if not i.startswith('.')]
|
||||
items = clean(items)
|
||||
items = sorted(items)
|
||||
if not showfile: items = [i for i in items if os.path.isdir(i)]
|
||||
if depth==1:
|
||||
if not showfile:
|
||||
items = [i for i in items if os.path.isdir(i)]
|
||||
if depth == 1:
|
||||
return [mklink(path)] + [' '*4 + mklink(i) for i in items]
|
||||
else:
|
||||
uls = [tree(i,depth-1,showfile) for i in items]
|
||||
uls = [tree(i, depth-1, showfile) for i in items]
|
||||
ret = [' '*4 + li for ul in uls for li in ul]
|
||||
return [mklink(path)] + ret
|
||||
return [mklink(path)] + ret
|
||||
|
||||
if __name__ =='__main__':
|
||||
print('\n'.join(tree(PATH,DEPTH,FILE)))
|
||||
|
||||
if __name__ == '__main__':
|
||||
print('\n'.join(tree(PATH, DEPTH, FILE)))
|
||||
|
|
Loading…
Reference in New Issue
Block a user