Format codes
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:
|
||||
# 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:]
|
||||
# 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 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 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
|
||||
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}')
|
||||
|
|
|
@ -12,46 +12,66 @@
|
|||
|
||||
|
||||
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):
|
||||
|
||||
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 __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)
|
||||
|
@ -59,58 +79,69 @@ class binaryHeap:
|
|||
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 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,7 +41,7 @@ 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):
|
||||
|
@ -50,7 +53,6 @@ class MyCircularQueue:
|
|||
return -1
|
||||
return self.data[self.head]
|
||||
|
||||
|
||||
def Rear(self):
|
||||
"""
|
||||
Get the last item from the queue.
|
||||
|
@ -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){
|
||||
|
||||
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,107 +11,136 @@
|
|||
'''
|
||||
|
||||
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
|
||||
while li:
|
||||
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))
|
||||
|
||||
def levelTraverse(self):
|
||||
li = [(self.root, 0)]
|
||||
cur = 0
|
||||
while li:
|
||||
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))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
@ -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,10 +9,14 @@
|
|||
# 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):
|
||||
|
@ -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.
|
||||
|
@ -52,7 +59,6 @@ class MyLinkedList:
|
|||
self.tail.follow = node(val)
|
||||
self.tail = self.tail.follow
|
||||
|
||||
|
||||
def addAtIndex(self, index, val):
|
||||
"""
|
||||
Add a node of value val before the index-th node in the linked list. If index equals to the length of linked list, the node will be appended to the end of linked list. If index is greater than the length, the node will not be inserted.
|
||||
|
@ -65,12 +71,11 @@ 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):
|
||||
"""
|
||||
Delete the index-th node in the linked list, if the index is valid.
|
||||
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -16,56 +16,66 @@
|
|||
|
||||
# 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()
|
||||
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,7 +96,8 @@ 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):
|
||||
|
||||
def rotate(self, prt, chd):
|
||||
'''rotate prt with the center of chd'''
|
||||
if self.root is prt:
|
||||
self.setRoot(chd)
|
||||
|
@ -84,10 +105,11 @@ class redBlackTree:
|
|||
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)
|
||||
self.copyNode(y, nd)
|
||||
if self.checkBlack(y):
|
||||
self.fixUpDel(py, x)
|
||||
|
||||
def fixUpDel(self,prt,chd):
|
||||
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.
|
||||
# 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]
|
||||
|
||||
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
|
||||
|
||||
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)
|
||||
|
|
|
@ -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
|
||||
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 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 __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)
|
||||
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
|
||||
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)
|
||||
|
|
|
@ -17,32 +17,35 @@
|
|||
( including the original length if possible)
|
||||
'''
|
||||
|
||||
def count(n,prices):
|
||||
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
|
34
graph/dfs.py
34
graph/dfs.py
|
@ -20,25 +20,26 @@
|
|||
#######################################################################
|
||||
'''
|
||||
|
||||
|
||||
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):
|
||||
|
@ -47,9 +48,9 @@ class Solution:
|
|||
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,7 +58,7 @@ class Solution:
|
|||
if n in lenDic:
|
||||
lenDic[n].add(i)
|
||||
else:
|
||||
lenDic[n]={i}
|
||||
lenDic[n] = {i}
|
||||
|
||||
lens = sorted(lenDic)
|
||||
n = len(lens)
|
||||
|
@ -65,6 +66,5 @@ class Solution:
|
|||
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):
|
||||
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
|
||||
|
|
|
@ -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')
|
||||
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 = 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,27 +34,31 @@ 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)
|
||||
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 y:
|
||||
y = input('input a vector y:n*1\n')
|
||||
y = parseLst(y)
|
||||
print('Equation: Av = y:')
|
||||
|
||||
|
@ -64,12 +67,14 @@ def handleInput(s=None,y=None):
|
|||
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('[]')
|
||||
li = s.split(',')
|
||||
|
@ -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)
|
||||
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)
|
||||
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:
|
||||
#########################################################################
|
||||
'''
|
||||
|
||||
|
|
@ -24,47 +24,50 @@
|
|||
#########################################################################
|
||||
|
||||
|
||||
|
||||
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,11 +57,14 @@ 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
|
||||
|
@ -62,29 +73,33 @@ class obj():
|
|||
|
||||
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))
|
||||
|
||||
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])
|
||||
print([v1.norm(i) for i in range(3)])
|
||||
|
||||
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 @@
|
|||
#########################################################################
|
||||
'''
|
||||
|
||||
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]
|
||||
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,6 +121,8 @@ 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')
|
||||
|
@ -111,19 +132,23 @@ def info():
|
|||
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("\"", "");
|
||||
def __init__(self, txt):
|
||||
self.words = self.clean(txt)
|
||||
self.dic = self.getDic(self.words)
|
||||
|
||||
# 保证每个标点符号都和前面的单词在一起
|
||||
# 这样不会被剔除,保留在马尔可夫链中
|
||||
punctuation = [',', '.', ';',':']
|
||||
for symbol in punctuation:
|
||||
text = text.replace(symbol, symbol+" ");
|
||||
def clean(self, text):
|
||||
text = text.replace("\n", " ")
|
||||
text = text.replace("\"", "")
|
||||
|
||||
return re.split(' +',text)
|
||||
# 保证每个标点符号都和前面的单词在一起
|
||||
# 这样不会被剔除,保留在马尔可夫链中
|
||||
punctuation = [',', '.', ';', ':']
|
||||
for symbol in punctuation:
|
||||
text = text.replace(symbol, symbol+" ")
|
||||
|
||||
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)
|
||||
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
|
||||
|
|
|
@ -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