Format codes

master
mbinary 2020-04-15 12:28:20 +08:00
parent 985b29ce65
commit ab86fa483a
75 changed files with 3122 additions and 2426 deletions

View File

@ -6,7 +6,7 @@
[![repo-size](https://img.shields.io/github/repo-size/mbinary/algorithm.svg)]() [![repo-size](https://img.shields.io/github/repo-size/mbinary/algorithm.svg)]()
[![License](https://img.shields.io/badge/LICENSE-WTFPL-blue.svg)](LICENSE) [![License](https://img.shields.io/badge/LICENSE-WTFPL-blue.svg)](LICENSE)
[![Language](https://img.shields.io/badge/language-python3-orange.svg)]() [![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: >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) * [LICENSE](./LICENSE)
* [README.md](./README.md) * [README.md](./README.md)
* [backtracking](./backtracking)
* [dataStructure](./dataStructure) * [dataStructure](./dataStructure)
* [LRU](./dataStructure/LRU) * [LRU](./dataStructure/LRU)
* [bTree.py](./dataStructure/bTree.py) * [bTree.py](./dataStructure/bTree.py)
* [binaryHeap.py](./dataStructure/binaryHeap.py) * [binaryHeap.py](./dataStructure/binaryHeap.py)
* [binaryHeap1.py](./dataStructure/binaryHeap1.py)
* [binaryTree.py](./dataStructure/binaryTree.py) * [binaryTree.py](./dataStructure/binaryTree.py)
* [circularQueue.py](./dataStructure/circularQueue.py) * [circularQueue.py](./dataStructure/circularQueue.py)
* [graph](./dataStructure/graph) * [graph](./dataStructure/graph)
@ -32,7 +30,6 @@ Some pictures and ideas are from `<<Introduction to Algotithm>>`
* [intervalTree.py](./dataStructure/intervalTree.py) * [intervalTree.py](./dataStructure/intervalTree.py)
* [leftHeap.py](./dataStructure/leftHeap.py) * [leftHeap.py](./dataStructure/leftHeap.py)
* [linkedList.py](./dataStructure/linkedList.py) * [linkedList.py](./dataStructure/linkedList.py)
* [loserTree.py](./dataStructure/loserTree.py)
* [map.cc](./dataStructure/map.cc) * [map.cc](./dataStructure/map.cc)
* [polynomial.cpp](./dataStructure/polynomial.cpp) * [polynomial.cpp](./dataStructure/polynomial.cpp)
* [polynomial.py](./dataStructure/polynomial.py) * [polynomial.py](./dataStructure/polynomial.py)
@ -40,7 +37,7 @@ Some pictures and ideas are from `<<Introduction to Algotithm>>`
* [redBlackTree0.py](./dataStructure/redBlackTree0.py) * [redBlackTree0.py](./dataStructure/redBlackTree0.py)
* [splayTree.py](./dataStructure/splayTree.py) * [splayTree.py](./dataStructure/splayTree.py)
* [trie](./dataStructure/trie) * [trie](./dataStructure/trie)
* [unionFindSet](./dataStructure/unionFindSet) * [unionFindSet.py](./dataStructure/unionFindSet.py)
* [winnerTree.py](./dataStructure/winnerTree.py) * [winnerTree.py](./dataStructure/winnerTree.py)
* [divideAndConquer](./divideAndConquer) * [divideAndConquer](./divideAndConquer)
* [min_distance_of_n_points.py](./divideAndConquer/min_distance_of_n_points.py) * [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) * [PL0-compiler](./parser/PL0-compiler)
* [calculator](./parser/calculator) * [calculator](./parser/calculator)
* [declarationParser](./parser/declarationParser) * [declarationParser](./parser/declarationParser)
* [poly.c](./poly.c)
* [search](./search) * [search](./search)
* [8Astar.py](./search/8Astar.py) * [Astar.py](./search/Astar.py)
* [BFS_knight.hs](./search/BFS_knight.hs) * [BFS_knight.hs](./search/BFS_knight.hs)
* [binary_search.hs](./search/binary_search.hs) * [binary_search.hs](./search/binary_search.hs)
* [bloomFilter.py](./search/bloomFilter.py) * [bloomFilter.py](./search/bloomFilter.py)

View File

@ -10,213 +10,257 @@
######################################################################### #########################################################################
''' '''
class node: class node:
def __init__(self,keys=None,isLeaf = True,children=None): def __init__(self, keys=None, isLeaf=True, children=None):
if keys is None:keys=[] if keys is None:
if children is None: children =[] keys = []
if children is None:
children = []
self.keys = keys self.keys = keys
self.isLeaf = isLeaf self.isLeaf = isLeaf
self.children = [] self.children = []
def __getitem__(self,i):
def __getitem__(self, i):
return self.keys[i] return self.keys[i]
def __delitem__(self,i):
def __delitem__(self, i):
del self.keys[i] del self.keys[i]
def __setitem__(self,i,k):
def __setitem__(self, i, k):
self.keys[i] = k self.keys[i] = k
def __len__(self): def __len__(self):
return len(self.keys) return len(self.keys)
def __repr__(self): def __repr__(self):
return str(self.keys) return str(self.keys)
def __str__(self): def __str__(self):
children = ','.join([str(nd.keys) for nd in self.children]) children = ','.join([str(nd.keys) for nd in self.children])
return f'keys: {self.keys}\nchildren: {children}\nisLeaf: {self.isLeaf}' return f'keys: {self.keys}\nchildren: {children}\nisLeaf: {self.isLeaf}'
def getChd(self,i):
def getChd(self, i):
return self.children[i] return self.children[i]
def delChd(self,i):
def delChd(self, i):
del self.children[i] del self.children[i]
def setChd(self,i,chd):
def setChd(self, i, chd):
self.children[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] return self.children[begin:end]
def findKey(self,key):
for i,k in enumerate(self.keys): def findKey(self, key):
if k>=key: for i, k in enumerate(self.keys):
if k >= key:
return i return i
return len(self) return len(self)
def update(self,keys=None,isLeaf=None,children=None):
if keys is not None:self.keys = keys def update(self, keys=None, isLeaf=None, children=None):
if children is not None:self.children = children if keys is not None:
if isLeaf is not None: self.isLeaf = isLeaf self.keys = keys
def insert(self,i,key=None,nd=None): if children is not None:
if key is not None:self.keys.insert(i,key) self.children = children
if not self.isLeaf and nd is not None: self.children.insert(i,nd) if isLeaf is not None:
def isLeafNode(self):return self.isLeaf self.isLeaf = isLeaf
def split(self,prt,t):
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 # form new two nodes
k = self[t-1] k = self[t-1]
nd1 = node() nd1 = node()
nd2 = 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 nd1.isLeaf = nd2.isLeaf = self.isLeaf
if not self.isLeaf: if not self.isLeaf:
# note that children index is one bigger than key index, and all children included # note that children index is one bigger than key index, and all children included
nd1.children, nd2.children = self.children[0:t], self.children[t:] nd1.children, nd2.children = self.children[0:t], self.children[t:]
# connect them to parent # connect them to parent
idx = prt.findKey(k) idx = prt.findKey(k)
if prt.children !=[]: prt.children.remove(self) # remove the original node if prt.children != []:
prt.insert(idx,k,nd2) prt.children.remove(self) # remove the original node
prt.insert(idx,nd = nd1) prt.insert(idx, k, nd2)
prt.insert(idx, nd=nd1)
return prt return prt
class bTree: class bTree:
def __init__(self,degree=2): def __init__(self, degree=2):
self.root = node() self.root = node()
self.degree=degree self.degree = degree
self.nodeNum = 1 self.nodeNum = 1
self.keyNum = 0 self.keyNum = 0
def search(self,key,withpath=False):
def search(self, key, withpath=False):
nd = self.root nd = self.root
fathers = [] fathers = []
while True: while True:
i = nd.findKey(key) i = nd.findKey(key)
if i==len(nd): fathers.append((nd,i-1,i)) if i == len(nd):
else: fathers.append((nd,i,i)) fathers.append((nd, i-1, i))
if i<len(nd) and nd[i]==key: else:
if withpath:return nd,i,fathers fathers.append((nd, i, i))
else:return nd,i if i < len(nd) and nd[i] == key:
if nd.isLeafNode(): if withpath:
if withpath:return None,None,None return nd, i, fathers
else:return None,None else:
return nd, i
if nd.isLeafNode():
if withpath:
return None, None, None
else:
return None, None
nd = nd.getChd(i) nd = nd.getChd(i)
def insert(self,key):
if len(self.root)== self.degree*2-1: def insert(self, key):
self.root = self.root.split(node(isLeaf=False),self.degree) if len(self.root) == self.degree*2-1:
self.nodeNum +=2 self.root = self.root.split(node(isLeaf=False), self.degree)
self.nodeNum += 2
nd = self.root nd = self.root
while True: while True:
idx = nd.findKey(key) 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(): if nd.isLeafNode():
nd.insert(idx,key) nd.insert(idx, key)
self.keyNum+=1 self.keyNum += 1
return return
else: else:
chd = nd.getChd(idx) chd = nd.getChd(idx)
if len(chd)== self.degree*2-1: #ensure its keys won't excess when its chd split and u # ensure its keys won't excess when its chd split and u
nd = chd.split(nd,self.degree) if len(chd) == self.degree*2-1:
self.nodeNum +=1 nd = chd.split(nd, self.degree)
self.nodeNum += 1
else: else:
nd = chd 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 ''' '''search the key, delete it , and form down to up to rebalance it '''
nd,idx ,fathers= self.search(key,withpath=True) nd, idx, fathers = self.search(key, withpath=True)
if nd is None : return if nd is None:
return
del nd[idx] del nd[idx]
self.keyNum-=1 self.keyNum -= 1
if not nd.isLeafNode(): if not nd.isLeafNode():
chd = nd.getChd(idx) # find the predecessor key chd = nd.getChd(idx) # find the predecessor key
while not chd.isLeafNode(): while not chd.isLeafNode():
fathers.append((chd,len(chd)-1,len(chd))) fathers.append((chd, len(chd)-1, len(chd)))
chd = chd.getChd(-1) chd = chd.getChd(-1)
fathers.append((chd,len(chd)-1,len(chd))) fathers.append((chd, len(chd)-1, len(chd)))
nd.insert(idx,chd[-1]) nd.insert(idx, chd[-1])
del chd[-1] del chd[-1]
if len(fathers)>1:self.rebalance(fathers) if len(fathers) > 1:
def rebalance(self,fathers): self.rebalance(fathers)
nd,keyIdx,chdIdx = fathers.pop()
while len(nd)<self.degree-1: # rebalance tree from down to up def rebalance(self, fathers):
prt,keyIdx,chdIdx = fathers[-1] nd, keyIdx, chdIdx = fathers.pop()
lbro = [] if chdIdx==0 else prt.getChd(chdIdx-1) while len(nd) < self.degree-1: # rebalance tree from down to up
rbro = [] if chdIdx==len(prt) else prt.getChd(chdIdx+1) prt, keyIdx, chdIdx = fathers[-1]
if len(lbro)<self.degree and len(rbro)<self.degree: # merge two deficient nodes lbro = [] if chdIdx == 0 else prt.getChd(chdIdx-1)
beforeNode,afterNode = None,None rbro = [] if chdIdx == len(prt) else prt.getChd(chdIdx+1)
if lbro ==[]: if len(lbro) < self.degree and len(rbro) < self.degree: # merge two deficient nodes
beforeNode, afterNode = None, None
if lbro == []:
keyIdx = chdIdx keyIdx = chdIdx
beforeNode,afterNode = nd,rbro beforeNode, afterNode = nd, rbro
else: else:
beforeNode,afterNode = lbro,nd beforeNode, afterNode = lbro, nd
keyIdx = chdIdx-1 # important, when choosing keyIdx = chdIdx-1 # important, when choosing
keys = beforeNode[:]+[prt[keyIdx]]+afterNode[:] keys = beforeNode[:]+[prt[keyIdx]]+afterNode[:]
children = beforeNode.getChildren() + afterNode.getChildren() children = beforeNode.getChildren() + afterNode.getChildren()
isLeaf = beforeNode.isLeafNode() isLeaf = beforeNode.isLeafNode()
prt.delChd(keyIdx+1) prt.delChd(keyIdx+1)
del prt[keyIdx] del prt[keyIdx]
nd.update(keys,isLeaf,children) nd.update(keys, isLeaf, children)
prt.children[keyIdx]=nd prt.children[keyIdx] = nd
self.nodeNum -=1 self.nodeNum -= 1
elif len(lbro)>=self.degree: # rotate when only one sibling is deficient elif len(lbro) >= self.degree: # rotate when only one sibling is deficient
keyIdx = chdIdx-1 keyIdx = chdIdx-1
nd.insert(0,prt[keyIdx]) # rotate keys nd.insert(0, prt[keyIdx]) # rotate keys
prt[keyIdx] = lbro[-1] prt[keyIdx] = lbro[-1]
del lbro[-1] del lbro[-1]
if not nd.isLeafNode(): # if not leaf, move children 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) lbro.delChd(-1)
else: else:
keyIdx = chdIdx keyIdx = chdIdx
nd.insert(len(nd),prt[keyIdx]) # rotate keys nd.insert(len(nd), prt[keyIdx]) # rotate keys
prt[keyIdx] = rbro[0] prt[keyIdx] = rbro[0]
del rbro[0] del rbro[0]
if not nd.isLeafNode(): # if not leaf, move children if not nd.isLeafNode(): # if not leaf, move children
#note that insert(-1,ele) will make the ele be the last second one # note that insert(-1,ele) will make the ele be the last second one
nd.insert(len(nd),nd=rbro.getChd(0)) nd.insert(len(nd), nd=rbro.getChd(0))
rbro.delChd(0) rbro.delChd(0)
if len(fathers)==1: if len(fathers) == 1:
if len(self.root)==0: if len(self.root) == 0:
self.root = nd self.root = nd
self.nodeNum -=1 self.nodeNum -= 1
break break
nd,i,j = fathers.pop() nd, i, j = fathers.pop()
def __str__(self): def __str__(self):
head= '\n'+'-'*30+'B Tree'+'-'*30 head = '\n'+'-'*30+'B Tree'+'-'*30
tail= '-'*30+'the end'+'-'*30+'\n' tail = '-'*30+'the end'+'-'*30+'\n'
lst = [[head],[f'node num: {self.nodeNum}, key num: {self.keyNum}']] lst = [[head], [f'node num: {self.nodeNum}, key num: {self.keyNum}']]
cur = [] cur = []
ndNum =0 ndNum = 0
ndTotal= 1 ndTotal = 1
que = [self.root] que = [self.root]
while que!=[]: while que != []:
nd = que.pop(0) nd = que.pop(0)
cur.append(repr(nd)) cur.append(repr(nd))
ndNum+=1 ndNum += 1
que+=nd.getChildren() que += nd.getChildren()
if ndNum==ndTotal: if ndNum == ndTotal:
lst.append(cur) lst.append(cur)
cur = [] cur = []
ndNum = 0 ndNum = 0
ndTotal =len(que) ndTotal = len(que)
lst.append([tail]) lst.append([tail])
lst = [','.join(li) for li in lst] lst = [','.join(li) for li in lst]
return '\n'.join(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] que = [nd]
while que !=[]: while que != []:
nd = que.pop(0) nd = que.pop(0)
yield nd yield nd
if nd.isLeafNode():continue if nd.isLeafNode():
continue
for i in range(len(nd)+1): for i in range(len(nd)+1):
que.append(nd.getChd(i)) que.append(nd.getChd(i))
if __name__ =='__main__': if __name__ == '__main__':
bt = bTree() bt = bTree()
from random import shuffle,sample from random import shuffle, sample
n = 20 n = 20
lst = [i for i in range(n)] lst = [i for i in range(n)]
shuffle(lst) shuffle(lst)
test= sample(lst,len(lst)//4) test = sample(lst, len(lst)//4)
print(f'building b-tree with {lst}') print(f'building b-tree with {lst}')
for i in lst: for i in lst:
bt.insert(i) bt.insert(i)
#print(f'inserting {i}) # print(f'inserting {i})
#print(bt) # print(bt)
print(bt) print(bt)
print(f'serching {test}') print(f'serching {test}')
for i in test: for i in test:
nd,idx = bt.search(i) nd, idx = bt.search(i)
print(f'node: {repr(nd)}[{idx}]== {i}') print(f'node: {repr(nd)}[{idx}]== {i}')
for i in test: for i in test:
print(f'deleting {i}') print(f'deleting {i}')

View File

@ -11,106 +11,137 @@
''' '''
from collections import Iterable from collections import Iterable
class node: class node:
def __init__(self,val,freq=1): def __init__(self, val, freq=1):
self.val=val self.val = val
self.freq = freq self.freq = freq
def __eq__(self,a):
return self.val == a.val def __eq__(self, a):
def __lt__(self,a): return self.val == a.val
return self.val<a.val
def __le__(self,a): def __lt__(self, a):
return self.val<=a.val return self.val < a.val
def __gt__(self,a):
return self.val>a.val def __le__(self, a):
def __ge__(self,a): return self.val <= a.val
return self.val>=a.val
def __ne__(self,a): 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 return not self == a
class binaryHeap: class binaryHeap:
def __init__(self,s=None,sortByFrequency = False,reverse=False): def __init__(self, s=None, sortByFrequency=False, reverse=False):
self.sortByFrequency=sortByFrequency self.sortByFrequency = sortByFrequency
self.reverse = reverse self.reverse = reverse
self.data = [node(0)] # make index begin with 1 self.data = [node(0)] # make index begin with 1
if s==None:return if s == None:
if not isinstance(s,Iterable):s = [s] return
if not isinstance(s, Iterable):
s = [s]
for i in s: for i in s:
self.insert(i) self.insert(i)
def __bool__(self): def __bool__(self):
return len(self)!=1 return len(self) != 1
def _cmp(self,a,b):
def _cmp(self, a, b):
if self.sortByFrequency: if self.sortByFrequency:
if self.reverse:return a.freq>b.freq if self.reverse:
else:return a.freq<b.freq return a.freq > b.freq
else:
return a.freq < b.freq
else: else:
if self.reverse:return a>b if self.reverse:
else:return a<b return a > b
def insert(self,k): else:
if not isinstance(k,node): k = node(k) return a < b
def insert(self, k):
if not isinstance(k, node):
k = node(k)
for j in range(self.data[0].val): for j in range(self.data[0].val):
i = self.data[j+1] i = self.data[j+1]
if i==k: if i == k:
i.freq+=1 i.freq += 1
if self.sortByFrequency: if self.sortByFrequency:
idx = self.percolateDown(j+1) idx = self.percolateDown(j+1)
self.percolateUp(idx) self.percolateUp(idx)
return return
self.data.append(k) self.data.append(k)
self.data[0].val += 1 self.data[0].val += 1
self.percolateUp() 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] 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] self.data[n] = self.data[n//2]
n = n//2 n = n//2
self.data[n] = tmp self.data[n] = tmp
def deleteTop(self): def deleteTop(self):
tmp = self.data[1] tmp = self.data[1]
i = self.percolateDown(1) i = self.percolateDown(1)
self.data[i] = self.data[-1] self.data[i] = self.data[-1]
self.data[0].val-= 1 self.data[0].val -= 1
del self.data[-1] del self.data[-1]
return tmp return tmp
def percolateDown(self,i):
def percolateDown(self, i):
tmp = self.data[i] tmp = self.data[i]
while self.data[0].val>=2*i+1: while self.data[0].val >= 2*i+1:
if self._cmp(self.data[i*2],self.data[2*i+1]): if self._cmp(self.data[i*2], self.data[2*i+1]):
self.data[i] = self.data[2*i] self.data[i] = self.data[2*i]
i = 2*i i = 2*i
else: else:
self.data[i] = self.data[2*i+1] self.data[i] = self.data[2*i+1]
i = 2*i+1 i = 2*i+1
self.data[i] = tmp self.data[i] = tmp
return i return i
def __len__(self): def __len__(self):
return self.data[0].val return self.data[0].val
def Nth(self,n=1):
def Nth(self, n=1):
tmp = [] tmp = []
for i in range(n): for i in range(n):
tmp.append(self.deleteTop()) tmp.append(self.deleteTop())
for i in tmp: for i in tmp:
self.insert(i) self.insert(i)
return tmp[-1] return tmp[-1]
def display(self): def display(self):
val =self.data[0].val+1 val = self.data[0].val+1
if self.sortByFrequency: if self.sortByFrequency:
info='heapSort by Frequency:' info = 'heapSort by Frequency:'
else:info = 'heapSort by Value:' else:
info = 'heapSort by Value:'
if self.reverse: if self.reverse:
info +=' From big to small' info += ' From big to small'
else:info +=' From small to big' else:
info += ' From small to big'
print('*'*15) print('*'*15)
print(info) print(info)
print('total items:%d\nval\tfreq'%(val-1)) print('total items:%d\nval\tfreq' % (val-1))
fmt = '{}\t{}' fmt = '{}\t{}'
for i in range(1,val): for i in range(1, val):
print(fmt.format(self.data[i].val,self.data[i].freq)) print(fmt.format(self.data[i].val, self.data[i].freq))
print('*'*15) print('*'*15)
class Test: class Test:
def topKFrequent(self, words, k): def topKFrequent(self, words, k):
hp = binaryHeap(sortByFrequency = True,reverse=True) hp = binaryHeap(sortByFrequency=True, reverse=True)
for i in words: for i in words:
hp.insert(i) hp.insert(i)
hp.display() hp.display()
@ -124,15 +155,19 @@ class Test:
mp[top.freq] = [top.val] mp[top.freq] = [top.val]
for i in mp: for i in mp:
mp[i].sort() mp[i].sort()
key = sorted(mp.keys(),reverse = True) key = sorted(mp.keys(), reverse=True)
rst = [] rst = []
count = 0 count = 0
for i in key: for i in key:
for j in mp[i]: for j in mp[i]:
rst.append(j) rst.append(j)
count+=1 count += 1
if count == k:return rst if count == k:
return rst
if __name__ == '__main__': 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() test = Test()
print(test.topKFrequent(s,5)) print(test.topKFrequent(s, 5))

View File

@ -12,61 +12,86 @@
from functools import total_ordering from functools import total_ordering
@total_ordering @total_ordering
class node: class node:
def __init__(self,val,left=None,right=None,freq = 1): def __init__(self, val, left=None, right=None, freq=1):
self.val=val self.val = val
self.left=left self.left = left
self.right=right self.right = right
self.freq = freq self.freq = freq
def __lt__(self,nd):
return self.val<nd.val def __lt__(self, nd):
def __eq__(self,nd): return self.val < nd.val
return self.val==nd.val
def __eq__(self, nd):
return self.val == nd.val
def __repr__(self): def __repr__(self):
return 'node({})'.format(self.val) return 'node({})'.format(self.val)
class binaryTree: class binaryTree:
def __init__(self): def __init__(self):
self.root=None self.root = None
def add(self,val):
def _add(nd,newNode): def add(self, val):
if nd<newNode: def _add(nd, newNode):
if nd.right is None:nd.right = newNode if nd < newNode:
else:_add(nd.right,newNode) if nd.right is None:
elif nd>newNode: nd.right = newNode
if nd.left is None:nd.left = newNode else:
else : _add(nd.left,newNode) _add(nd.right, newNode)
else:nd.freq +=1 elif nd > newNode:
_add(self.root,node(val)) if nd.left is None:
def find(self,val): nd.left = newNode
prt= self._findPrt(self.root,node(val),None) else:
if prt.left and prt.left.val==val: _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 return prt.left
elif prt.right and prt.right.val==val:return prt.right elif prt.right and prt.right.val == val:
else :return None return prt.right
def _findPrt(self,nd,tgt,prt): else:
if nd==tgt or nd is None:return prt return None
elif nd<tgt:return self._findPrt(nd.right,tgt,nd)
else:return self._findPrt(nd.left,tgt,nd) def _findPrt(self, nd, tgt, prt):
def delete(self,val): if nd == tgt or nd is None:
prt= self._findPrt(self.root,node(val),None) return prt
if prt.left and prt.left.val==val: elif nd < tgt:
l=prt.left return self._findPrt(nd.right, tgt, nd)
if l.left is None:prt.left = l.right else:
elif l.right is None : prt.left = l.left 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: else:
nd = l.left 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 nd.right = l.right
prt.left = l.left prt.left = l.left
elif prt.right and prt.right.val==val: elif prt.right and prt.right.val == val:
r=prt.right r = prt.right
if r.right is None:prt.right = r.right if r.right is None:
elif r.right is None : prt.right = r.left prt.right = r.right
elif r.right is None:
prt.right = r.left
else: else:
nd = r.left 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 nd.right = r.right
prt.left = r.left prt.left = r.left
@ -77,7 +102,9 @@ class binaryTree:
_p(nd.left) _p(nd.left)
_p(nd.right) _p(nd.right)
_p(self.root) _p(self.root)
if __name__=="__main__":
if __name__ == "__main__":
t = binaryTree() t = binaryTree()
for i in range(10): for i in range(10):
t.add((i-4)**2) t.add((i-4)**2)

View File

@ -9,6 +9,8 @@
# Description: # Description:
######################################################################### #########################################################################
''' '''
class MyCircularQueue: class MyCircularQueue:
def __init__(self, k): def __init__(self, k):
@ -29,8 +31,9 @@ class MyCircularQueue:
if self.isFull(): if self.isFull():
return False return False
self.data[self.rear] = value self.data[self.rear] = value
self.rear = (self.rear+1)%self.size self.rear = (self.rear+1) % self.size
return True return True
def deQueue(self): def deQueue(self):
""" """
Delete an element from the circular queue. Return true if the operation is successful. Delete an element from the circular queue. Return true if the operation is successful.
@ -38,9 +41,9 @@ class MyCircularQueue:
""" """
if self.isEmpty(): if self.isEmpty():
return False return False
self.head = (self.head+1)%self.size self.head = (self.head+1) % self.size
return True return True
def Front(self): def Front(self):
""" """
Get the front item from the queue. Get the front item from the queue.
@ -49,7 +52,6 @@ class MyCircularQueue:
if self.isEmpty(): if self.isEmpty():
return -1 return -1
return self.data[self.head] return self.data[self.head]
def Rear(self): def Rear(self):
""" """
@ -58,23 +60,21 @@ class MyCircularQueue:
""" """
if self.isEmpty(): if self.isEmpty():
return -1 return -1
return self.data[(self.rear-1)%self.size] return self.data[(self.rear-1) % self.size]
def isEmpty(self): def isEmpty(self):
""" """
Checks whether the circular queue is empty or not. Checks whether the circular queue is empty or not.
:rtype: bool :rtype: bool
""" """
return self.head ==self.rear return self.head == self.rear
def isFull(self): def isFull(self):
""" """
Checks whether the circular queue is full or not. Checks whether the circular queue is full or not.
:rtype: bool :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: # Your MyCircularQueue object will be instantiated and called as such:

View File

@ -10,18 +10,23 @@
######################################################################### #########################################################################
''' '''
class item: class item:
def __init__(self,key,val,nextItem=None): def __init__(self, key, val, nextItem=None):
self.key = key self.key = key
self.val = val self.val = val
self.next = nextItem self.next = nextItem
def to(self,it):
def to(self, it):
self.next = it self.next = it
def __eq__(self,it):
def __eq__(self, it):
'''using keyword <in> ''' '''using keyword <in> '''
return self.key == it.key return self.key == it.key
def __bool__(self): def __bool__(self):
return self.key is not None return self.key is not None
def __str__(self): def __str__(self):
li = [] li = []
nd = self nd = self
@ -29,27 +34,33 @@ class item:
li.append(f'({nd.key}:{nd.val})') li.append(f'({nd.key}:{nd.val})')
nd = nd.next nd = nd.next
return ' -> '.join(li) return ' -> '.join(li)
def __repr__(self): def __repr__(self):
return f'item({self.key},{self.val})' return f'item({self.key},{self.val})'
class hashTable: class hashTable:
def __init__(self,size=100): def __init__(self, size=100):
self.size = size self.size = size
self.slots=[item(None,None) for i in range(self.size)] self.slots = [item(None, None) for i in range(self.size)]
def __setitem__(self,key,val):
def __setitem__(self, key, val):
nd = self.slots[self.myhash(key)] nd = self.slots[self.myhash(key)]
while nd.next: while nd.next:
if nd.key ==key: if nd.key == key:
if nd.val!=val: nd.val=val if nd.val != val:
nd.val = val
return return
nd = nd.next nd = nd.next
nd.next = item(key,val) nd.next = item(key, val)
def myhash(self,key): def myhash(self, key):
if isinstance(key,str): if isinstance(key, str):
key = sum(ord(i) for i in key) key = sum(ord(i) for i in key)
if not isinstance(key,int): if not isinstance(key, int):
key = hash(key) key = hash(key)
return key % self.size return key % self.size
def __iter__(self): def __iter__(self):
'''when using keyword <in>, such as ' if key in dic', '''when using keyword <in>, such as ' if key in dic',
the dic's __iter__ method will be called,(if hasn't, calls __getitem__ the dic's __iter__ method will be called,(if hasn't, calls __getitem__
@ -57,18 +68,20 @@ class hashTable:
''' '''
for nd in self.slots: for nd in self.slots:
nd = nd.next nd = nd.next
while nd : while nd:
yield nd.key yield nd.key
nd = nd.next 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: while nd:
if nd.key==key: if nd.key == key:
return nd.val return nd.val
nd = nd.next 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, '''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 which means you should take care of them and correctly cop with None item
especially when deleting items especially when deleting items
@ -77,31 +90,34 @@ class hashTable:
nd = self.slots[n].next nd = self.slots[n].next
if nd.key == key: if nd.key == key:
if nd.next is None: if nd.next is None:
self.slots[n] = item(None,None) # be careful self.slots[n] = item(None, None) # be careful
else:self.slots[n] = nd.next else:
self.slots[n] = nd.next
return return
while nd: while nd:
if nd.next is None: break # necessary if nd.next is None:
if nd.next.key ==key: break # necessary
if nd.next.key == key:
nd.next = nd.next.next nd.next = nd.next.next
nd = nd.next nd = nd.next
def __str__(self): def __str__(self):
li = ['\n\n'+'-'*5+'hashTable'+'-'*5] 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)) li.append(f'{i}: '+str(nd.next))
return '\n'.join(li) return '\n'.join(li)
if __name__ =='__main__':
if __name__ == '__main__':
from random import randint from random import randint
dic = hashTable(16) dic = hashTable(16)
n = 100 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}') print(f'build hashTable using {li}')
for i in li: for i in li:
dic[i] = '$'+str(i) dic[i] = '$'+str(i)
print(dic) print(dic)
for i in [1,34,45,123]: for i in [1, 34, 45, 123]:
if i in dic: if i in dic:
print(f'{i} in dic, deleting it') print(f'{i} in dic, deleting it')
del dic[i] del dic[i]

View File

@ -28,348 +28,437 @@ using namespace std;
void cat(string s) void cat(string s)
{ {
FILE* f=fopen(s.c_str(),"rb"); FILE* f = fopen(s.c_str(), "rb");
cout<<"file content"<<endl; cout << "file content" << endl;
while(!feof(f)){
cout<<fgetc(f); while (!feof(f)) {
cout << fgetc(f);
} }
cout<<endl;
cout << endl;
} }
string uniFileName(string file) string uniFileName(string file)
{ {
FILE * check = fopen(file.c_str(),"rb"); FILE * check = fopen(file.c_str(), "rb");
if(check){
if (check) {
char c; char c;
cout<<"the file "<<file<<" already exists! continue? [Y/n]:"<<flush; cout << "the file " << file << " already exists! continue? [Y/n]:" << flush;
c=cin.get(); c = cin.get();
if(c=='n')exit(0);
int p,q; if (c == 'n')exit(0);
p= file.find('(');
q=file.rfind('.'); int p, q;
if(q==string::npos)q=file.size(); p = file.find('(');
if(p==string::npos)p=q; q = file.rfind('.');
string name=file.substr(0,p),suffix=file.substr(q,file.size());
int n=0; if (q == string::npos)q = file.size();
while(true){
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]; char s[3];
n+=1; n += 1;
snprintf(s,3,"%d",n); snprintf(s, 3, "%d", n);
file=(name+"("+s+")"+suffix); file = (name + "(" + s + ")" + suffix);
FILE* f=fopen(file.c_str(),"rb"); FILE* f = fopen(file.c_str(), "rb");
if(!f)break;
if (!f)break;
else fclose(f); else fclose(f);
} }
} }
return file; return file;
} }
template<class t1, class t2> 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) for (class map<t1, t2>::iterator i = f.begin(); i != f.end(); ++i)
cout<<i->first<<") : "<<i->second<<endl; cout << i->first << ") : " << i->second << endl;
} }
template<typename ky,typename wt> template<typename ky, typename wt>
class node class node
{ {
public: public:
ky key; ky key;
wt val; wt val;
bool visited; bool visited;
node * left,*right; node * left, *right;
node(const node &a){val = a.val;key= a.key;visited = a.visited;left= a.left;right=a.right;} node(const node &a)
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;}; 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 class huffman
{ {
private: private:
node<ky,wt> root; node<ky, wt> root;
string res; string res;
public: public:
long total(){return root.val;} long total()
map<ky,string> encode_map; {
map<string,ky> decode_map; return root.val;
huffman(map<ky,wt>& mp); }
map<ky, string> encode_map;
map<string, ky> decode_map;
huffman(map<ky, wt>& mp);
void display(); void display();
string encode(string,long &); string encode(string, long &);
string decode(string,long&); string decode(string, long&);
void preOrder(node<ky,wt>*,string); void preOrder(node<ky, wt>*, string);
}; };
template<typename ky,typename wt> template<typename ky, typename wt>
huffman<ky,wt>::huffman(map<ky,wt>& mp) huffman<ky, wt>::huffman(map<ky, wt>& mp)
{ {
if(mp.empty()){ if (mp.empty()) {
cout<<"Error! No data!"<<endl; cout << "Error! No data!" << endl;
root=NULL; root = NULL;
return ; return ;
} }
priority_queue<node<ky,wt> > hp;
for(typename map<ky,wt>::iterator i=mp.begin();i!=mp.end();++i){ priority_queue<node<ky, wt> > hp;
hp.push( node<ky,wt>(i->first,i->second));
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(); root = hp.top();
return; 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(); hp.pop();
node<ky,wt> *b = new node<ky,wt>(hp.top()); node<ky, wt> *b = new node<ky, wt>(hp.top());
hp.pop(); hp.pop();
node<ky,wt> * tmp = new node<ky,wt>(0,a->val+b->val); node<ky, wt> * tmp = new node<ky, wt>(0, a->val + b->val);
tmp->left = a,tmp->right = b; tmp->left = a, tmp->right = b;
hp.push(*tmp); hp.push(*tmp);
} }
root = hp.top(); root = hp.top();
preOrder(&root,string()); preOrder(&root, string());
} }
template<typename ky,typename wt> template<typename ky, typename wt>
void huffman<ky,wt>::preOrder(node<ky, wt>* nd,string s) void huffman<ky, wt>::preOrder(node<ky, wt>* nd, string s)
{ {
if(nd->left == NULL){ if (nd->left == NULL) {
encode_map[nd->key] =s; encode_map[nd->key] = s;
decode_map[s] = nd->key; decode_map[s] = nd->key;
delete nd; delete nd;
return ; return ;
} }
preOrder(nd->left,s+'0');
preOrder(nd->right,s+'1'); preOrder(nd->left, s + '0');
preOrder(nd->right, s + '1');
delete nd; delete nd;
} }
template<typename ky,typename wt> template<typename ky, typename wt>
string huffman<ky,wt>::decode(string zipfile_name,long &charNum) string huffman<ky, wt>::decode(string zipfile_name, long &charNum)
{ {
string uniFileName(string); string uniFileName(string);
FILE * src = fopen(zipfile_name.c_str(),"rb"); FILE * src = fopen(zipfile_name.c_str(), "rb");
char file_name[nameLength]; char file_name[nameLength];
fgets(file_name,nameLength,src); fgets(file_name, nameLength, src);
int ct=-1; int ct = -1;
while(file_name[++ct]!='\n');
while (file_name[++ct] != '\n');
int pos = zipfile_name.find('.'); 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); if (pos == string::npos)pos = zipfile_name.size();
file=uniFileName(file);
cout<<"extracting compressed file :"<<zipfile_name<<endl; string name(zipfile_name.substr(0, pos)), suffix(file_name, file_name + ct), file(name + suffix);
FILE * f = fopen(file.c_str(),"wb"); file = uniFileName(file);
cout << "extracting compressed file :" << zipfile_name << endl;
FILE * f = fopen(file.c_str(), "wb");
char t[numDigit]; char t[numDigit];
fgets(t,numDigit,src); fgets(t, numDigit, src);
int sz=atoi(t); int sz = atoi(t);
char code[sz]; char code[sz];
fread(code,sz,1,src); fread(code, sz, 1, src);
int idx=0; int idx = 0;
for(int i =0;i<sz;++i ){
if(code[i]==' '){ for (int i = 0; i < sz; ++i) {
decode_map[string(code+idx,code+i)]=code[++i]; if (code[i] == ' ') {
idx=i+1; 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; char c;
long cur=charNum,gap=charNum/starNum; long cur = charNum, gap = charNum / starNum;
while(cur){
c=fgetc(src); while (cur) {
if(!((--cur)%gap))cout<<"@"<<flush; c = fgetc(src);
for(int i =0;i<8;++i){
if(c&(1<<i))res.append(1,'1'); if (!((--cur) % gap))cout << "@" << flush;
else res.append(1,'0');
if(decode_map.count(res)!=0){ for (int i = 0; i < 8; ++i) {
fputc(decode_map[res],f); 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(); res.clear();
} }
} }
} }
cout<<endl;
c=fgetc(src); cout << endl;
int dgt=fgetc(src); c = fgetc(src);
cout<<feof(f); int dgt = fgetc(src);
if((int)dgt!=-1 ){ cout << feof(f);
for(int i =0;i<dgt;++i){
if(c&(1<<i))res.append(1,'1'); if ((int)dgt != -1) {
else res.append(1,'0'); for (int i = 0; i < dgt; ++i) {
if(decode_map.count(res)!=0){ if (c & (1 << i))res.append(1, '1');
fputc(decode_map[res],f); else res.append(1, '0');
if (decode_map.count(res) != 0) {
fputc(decode_map[res], f);
res.clear(); res.clear();
break; break;
} }
} }
} }
fclose(src); fclose(src);
fclose(f); fclose(f);
cout<<"get "<<file <<" successfully"<<endl; cout << "get " << file << " successfully" << endl;
return file; return file;
} }
template<typename ky,typename wt> template<typename ky, typename wt>
string huffman<ky,wt>::encode(string file_name,long &charNum) string huffman<ky, wt>::encode(string file_name, long &charNum)
{ {
charNum=0; charNum = 0;
string uniFileName(string); string uniFileName(string);
int pos =file_name.rfind('.'); int pos = file_name.rfind('.');
if(pos==string::npos)pos=file_name.size();
string zipfile = file_name.substr(0,pos)+string(".zzip"); if (pos == string::npos)pos = file_name.size();
string zipfile = file_name.substr(0, pos) + string(".zzip");
zipfile = uniFileName(zipfile); zipfile = uniFileName(zipfile);
cout<<"generating zip file :"<<zipfile<<endl; cout << "generating zip file :" << zipfile << endl;
FILE * dst = fopen(zipfile.c_str(),"wb"); FILE * dst = fopen(zipfile.c_str(), "wb");
FILE * f = fopen(file_name.c_str(),"rb"); FILE * f = fopen(file_name.c_str(), "rb");
fputs(file_name.substr(pos).c_str(),dst); fputs(file_name.substr(pos).c_str(), dst);
fputc('\n',dst); fputc('\n', dst);
string data; 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((i->first));
data.append(" "); data.append(" ");
data+=(i->second); data += (i->second);
} }
int data_size = data.size(); // calculate the size of the code_data int data_size = data.size(); // calculate the size of the code_data
char sz[numDigit]; char sz[numDigit];
snprintf(sz,numDigit,"%d",data_size); snprintf(sz, numDigit, "%d", data_size);
int ct=0; int ct = 0;
for(;sz[ct];++ct)fputc(sz[ct],dst);
fputc('\n',dst); for (; sz[ct]; ++ct)fputc(sz[ct], dst);
fwrite(data.c_str(),data_size,1,dst);
int sum=0,digit=0,num; fputc('\n', dst);
fwrite(data.c_str(), data_size, 1, dst);
int sum = 0, digit = 0, num;
string code8; string code8;
for(int i=0;i<starNum;++i)cout<<"@";
cout<<endl; for (int i = 0; i < starNum; ++i)cout << "@";
long gap=root.val/starNum,cur=0;
while(!feof(f)){ cout << endl;
code8=encode_map[fgetc(f)]; long gap = root.val / starNum, cur = 0;
if(!((++cur)%gap))cout<<"@";
for(int i=0;i<code8.size();++i){ while (!feof(f)) {
if(code8[i]=='1')sum += 1<<(digit); //mistake if(tmp[j]) 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; ++digit;
if(digit==8){
if (digit == 8) {
++charNum; ++charNum;
fputc(sum,dst); fputc(sum, dst);
digit=sum=0; digit = sum = 0;
} }
} }
} }
cout<<endl;
if(digit!=0){ //mark cout << endl;
fputc(sum,dst);
fputc(digit,dst); if (digit != 0) { //mark
fputc(sum, dst);
fputc(digit, dst);
} }
fclose(f); fclose(f);
fclose(dst); fclose(dst);
cout<<"compress "<<file_name <<" successfully"<<endl; cout << "compress " << file_name << " successfully" << endl;
return zipfile; return zipfile;
} }
template<typename ky,typename wt> template<typename ky, typename wt>
void huffman<ky,wt>::display() void huffman<ky, wt>::display()
{ {
cout<<"the encoding map,huffman codes are as bellow:"<<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; 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(); int name_length = file_name.size();
FILE *src=fopen(file_name.c_str(),"rb"); FILE *src = fopen(file_name.c_str(), "rb");
cout<<"opening "<<file_name<<"..."<<endl; cout << "opening " << file_name << "..." << endl;
if(!src){
cout<<"Path Error! Opening "<<file_name<<" Failed"<<endl; if (!src) {
cout << "Path Error! Opening " << file_name << " Failed" << endl;
origin.push_back(0); origin.push_back(0);
compressed.push_back(0); compressed.push_back(0);
return false; return false;
} }
char cur; char cur;
map<char,long> mp; map<char, long> mp;
while(!feof(src)){
fread(&cur,sizeof(char),1,src); while (!feof(src)) {
if(mp.count(cur)){ fread(&cur, sizeof(char), 1, src);
mp[cur]+=1;
} if (mp.count(cur)) {
else mp[cur]=1; mp[cur] += 1;
} else mp[cur] = 1;
} }
fclose(src); fclose(src);
huffman<char,long> hf(mp); huffman<char, long> hf(mp);
long sz; long sz;
string s(hf.encode(file_name,sz)); string s(hf.encode(file_name, sz));
origin.push_back(hf.total()),compressed.push_back(sz); origin.push_back(hf.total()), compressed.push_back(sz);
cout<<"\ncontinue to uncompress? [Y/n]"<<endl; cout << "\ncontinue to uncompress? [Y/n]" << endl;
char c=cin.get(); char c = cin.get();
if(c=='n')return true;
hf.decode(s,sz); if (c == 'n')return true;
hf.decode(s, sz);
return true; return true;
} }
bool isSep(char c) 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; int i = 0, last = 0;
for(;s[i];++i){
if(isSep(s[i])){ for (; s[i]; ++i) {
v.push_back(string(s+last,s+i)); if (isSep(s[i])) {
while(s[++i]&&isSep(s[i])); v.push_back(string(s + last, s + i));
last=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) void go(vector<string> & names)
{ {
vector<long> originSize,compressedSize; vector<long> originSize, compressedSize;
vector<int> deltaTime; vector<int> deltaTime;
double last; double last;
vector<bool> indicator; vector<bool> indicator;
bool bl; 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; struct timeval tv;
gettimeofday(&tv,NULL); gettimeofday(&tv, NULL);
last=tv.tv_sec; last = tv.tv_sec;
bl=handle_one(*i,originSize,compressedSize); bl = handle_one(*i, originSize, compressedSize);
indicator.push_back(bl); indicator.push_back(bl);
gettimeofday(&tv,NULL); gettimeofday(&tv, NULL);
deltaTime.push_back(tv.tv_sec-last); 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); cout << "\nDealt file number " << originSize.size() << fixed << setprecision(2) << endl;
int len = p->size()+2; vector<string>::iterator p = max_element(names.begin(), names.end(), lenStr);
for(int i =0;i<names.size();++i){ int len = p->size() + 2;
if(! indicator[i]){continue;}
cout<<names[i]<<string(len-names[i].size(),' '); for (int i = 0; i < names.size(); ++i) {
cout<<deltaTime[i]<<"s "<<compressedSize[i]/1024.0<<"KB/"<<originSize[i]/1024.0<<"KB :"; if (! indicator[i]) {
cout<<compressedSize[i]*100.0/originSize[i]<<"%"<<endl; 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"); system("pause");
} }
int main(int argv,char ** argc) int main(int argv, char ** argc)
{ {
char cwd[50]; char cwd[50];
cout<<getcwd(cwd,50)<<endl; cout << getcwd(cwd, 50) << endl;
vector<string> names; vector<string> names;
string file; 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]); names.push_back(argc[i]);
} }
go(names); go(names);
names.clear(); names.clear();
} }
char mk; char mk;
while(1){
while (1) {
char s[201]; char s[201];
cout<<"Input file names separated by space "<<endl; cout << "Input file names separated by space " << endl;
if(cin.peek()=='\n')names.push_back(file);
if (cin.peek() == '\n')names.push_back(file);
else { else {
cin.getline(s,200); cin.getline(s, 200);
splitToVec(s,names); splitToVec(s, names);
} }
cout<<endl;
cout << endl;
go(names); go(names);
cout<<"Continue? [Y/n]:"<<flush; cout << "Continue? [Y/n]:" << flush;
mk= cin.get(); mk = cin.get();
if(mk=='n')break;
if (mk == 'n')break;
names.clear(); names.clear();
} }
return 0; return 0;
} }

View File

@ -13,11 +13,12 @@
####################################################################### #######################################################################
''' '''
class RandomizedCollection: class RandomizedCollection:
def __init__(self): def __init__(self):
self.vals=[] self.vals = []
self.index={} self.index = {}
def insert(self, val: int) -> bool: def insert(self, val: int) -> bool:
self.vals.append(val) self.vals.append(val)
@ -27,32 +28,35 @@ class RandomizedCollection:
else: else:
self.index[val] = {len(self.vals)-1} self.index[val] = {len(self.vals)-1}
return True return True
def removeAll(self, val: int) -> bool: def removeAll(self, val: int) -> bool:
if val not in self.index: if val not in self.index:
return False return False
begin = end = len(self.vals)-len(self.index[val]) begin = end = len(self.vals)-len(self.index[val])
for idx in self.index.pop(val): for idx in self.index.pop(val):
if idx<begin: if idx < begin:
while self.vals[end]==val: while self.vals[end] == val:
end+=1 end += 1
self.vals[idx]=self.vals[end] self.vals[idx] = self.vals[end]
self.index[self.vals[idx]].remove(end) self.index[self.vals[idx]].remove(end)
self.index[self.vals[idx]].add(idx) self.index[self.vals[idx]].add(idx)
self.vals = self.vals[:begin] self.vals = self.vals[:begin]
return True return True
def remove(self,val):
def remove(self, val):
if val not in self.index: if val not in self.index:
return False return False
last = len(self.vals)-1 last = len(self.vals)-1
idx = self.index[val].pop() idx = self.index[val].pop()
if len(self.index[val])==0: if len(self.index[val]) == 0:
del self.index[val] del self.index[val]
if idx!=last: if idx != last:
self.vals[idx] = self.vals[last] self.vals[idx] = self.vals[last]
self.index[self.vals[idx]].remove(last) self.index[self.vals[idx]].remove(last)
self.index[self.vals[idx]].add(idx) self.index[self.vals[idx]].add(idx)
self.vals.pop() self.vals.pop()
return True return True
def getRandom(self) -> int: def getRandom(self) -> int:
if self.vals: if self.vals:
return self.vals[random.randint(0,len(self.vals)-1)] return self.vals[random.randint(0, len(self.vals)-1)]

View File

@ -9,60 +9,80 @@
# Description: # Description:
######################################################################### #########################################################################
''' '''
from random import randint, shuffle
from redBlackTree import redBlackTree from redBlackTree import redBlackTree
from functools import total_ordering from functools import total_ordering
@total_ordering @total_ordering
class node: class node:
def __init__(self,low,high,left=None,right=None,isBlack=False): def __init__(self, low, high, left=None, right=None, isBlack=False):
self.val = low # self.val is the low self.val = low # self.val is the low
self.high = high self.high = high
self.max = high self.max = high
self.left = left self.left = left
self.right = right self.right = right
self.parent=None self.parent = None
self.isBlack = isBlack self.isBlack = isBlack
def __lt__(self,nd):
def __lt__(self, nd):
return self.val < nd.val return self.val < nd.val
def __eq__(self,nd):
def __eq__(self, nd):
return nd is not None and self.val == nd.val return nd is not None and self.val == nd.val
def setChild(self,nd,isLeft = True):
if isLeft: self.left = nd def setChild(self, nd, isLeft=True):
else: self.right = nd if isLeft:
if nd is not None: nd.parent = self self.left = nd
def getChild(self,isLeft): else:
if isLeft: return self.left self.right = nd
else: return self.right if nd is not None:
nd.parent = self
def getChild(self, isLeft):
if isLeft:
return self.left
else:
return self.right
def __bool__(self): def __bool__(self):
return self.val is not None return self.val is not None
def __str__(self): def __str__(self):
color = 'B' if self.isBlack else 'R' color = 'B' if self.isBlack else 'R'
return f'{color}[{self.val},{self.high}]-{self.max}' return f'{color}[{self.val},{self.high}]-{self.max}'
def __repr__(self): def __repr__(self):
return f'intervalNode({self.val},{self.high},{self.max},isBlack={self.isBlack})' 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): def setMax(self):
l = 0 if self.left is None else self.left.max l = 0 if self.left is None else self.left.max
r = 0 if self.right is None else self.right.max r = 0 if self.right is None else self.right.max
self.max = max(self.high, l, r) self.max = max(self.high, l, r)
return self.max return self.max
class intervalTree(redBlackTree): class intervalTree(redBlackTree):
def search(self,low,high): def search(self, low, high):
nd = self.root nd = self.root
while nd is not None and not nd.overlap(low,high): while nd is not None and not nd.overlap(low, high):
if nd.left is not None and nd.left.max>=low: if nd.left is not None and nd.left.max >= low:
nd = nd.left nd = nd.left
else:nd = nd.right else:
nd = nd.right
return nd 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: while nd is not None:
nd.setMax() nd.setMax()
nd = nd.parent nd = nd.parent
def delete(self,val):
def delete(self, val):
nd = self.find(val) nd = self.find(val)
if nd is not None: if nd is not None:
nd.max = 0 nd.max = 0
@ -70,56 +90,61 @@ class intervalTree(redBlackTree):
while tmp is not None: while tmp is not None:
tmp.setMax() tmp.setMax()
tmp = tmp.parent tmp = tmp.parent
super(intervalTree,self).delete(val) super(intervalTree, self).delete(val)
def rotate(self,prt,chd):
def rotate(self, prt, chd):
'''rotate prt, and return new prt, namyly the original 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() prt.setMax()
chd.setMax() chd.setMax()
def copyNode(self,src,des):
def copyNode(self, src, des):
des.val = src.val des.val = src.val
des.high = src.high des.high = src.high
des.setMax() des.setMax()
def genNum(n=10, upper=10):
from random import randint, shuffle nums = {}
def genNum(n =10,upper=10):
nums ={}
for i in range(n): for i in range(n):
while 1: while 1:
d = randint(0,100) d = randint(0, 100)
if d not in nums: if d not in nums:
nums[d] = (d,randint(d,d+upper)) nums[d] = (d, randint(d, d+upper))
break break
return nums.values() 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) #if nums is None or nums ==[]: nums = genNum(n)
tree = intervalTree() tree = intervalTree()
print(f'build a red-black tree using {nums}') print(f'build a red-black tree using {nums}')
for i in nums: for i in nums:
tree.insert(node(*i)) tree.insert(node(*i))
if visitor: if visitor:
visitor(tree,i) visitor(tree, i)
return tree,nums return tree, nums
def testInsert(nums=None): def testInsert(nums=None):
def visitor(t,val): def visitor(t, val):
print('inserting', val) print('inserting', val)
print(t) print(t)
tree,nums = buildTree(visitor = visitor,nums=nums) tree, nums = buildTree(visitor=visitor, nums=nums)
print('-'*5+ 'in-order visit' + '-'*5) print('-'*5 + 'in-order visit' + '-'*5)
for i,j in enumerate(tree.sort()): for i, j in enumerate(tree.sort()):
print(f'{i+1}: {j}') print(f'{i+1}: {j}')
return tree return tree
def testSuc(nums=None): def testSuc(nums=None):
tree,nums = buildTree(nums=nums) tree, nums = buildTree(nums=nums)
for i in tree.sort(): for i in tree.sort():
print(f'{i}\'s suc is {tree.getSuccessor(i)}') print(f'{i}\'s suc is {tree.getSuccessor(i)}')
def testDelete(nums=None): def testDelete(nums=None):
tree,nums = buildTree(nums = nums) tree, nums = buildTree(nums=nums)
print(tree) print(tree)
for i in nums: for i in nums:
print(f'deleting {i}') print(f'deleting {i}')
@ -127,14 +152,16 @@ def testDelete(nums=None):
print(tree) print(tree)
return 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 #lst = None
#testSuc(lst) # testSuc(lst)
tree = testInsert(lst) tree = testInsert(lst)
#tree,_= buildTree(lst) #tree,_= buildTree(lst)
while 1: while 1:
a =int( input('low:')) a = int(input('low:'))
b =int( input('high:')) b = int(input('high:'))
res = tree.search(a,b) res = tree.search(a, b)
print(res) print(res)

View File

@ -11,108 +11,137 @@
''' '''
from functools import total_ordering from functools import total_ordering
@total_ordering
@total_ordering
class node: class node:
def __init__(self,val,freq=1,s=1,left=None,right=None): def __init__(self, val, freq=1, s=1, left=None, right=None):
self.val=val self.val = val
self.freq=freq self.freq = freq
self.s=s self.s = s
if left is None or right is None: if left is None or right is None:
self.left = left if left is not None else right self.left = left if left is not None else right
self.right =None self.right = None
else: else:
if left.s<right.s: if left.s < right.s:
left,right =right, left left, right = right, left
self.left=left self.left = left
self.right=right self.right = right
self.s+=self.right.s self.s += self.right.s
def __eq__(self,nd):
return self.val==nd.val def __eq__(self, nd):
def __lt__(self,nd): return self.val == nd.val
return self.val<nd.val
def __lt__(self, nd):
return self.val < nd.val
def __repr__(self): 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: class leftHeap:
def __init__(self,root=None): def __init__(self, root=None):
self.root=root self.root = root
def __bool__(self): def __bool__(self):
return self.root is not None return self.root is not None
@staticmethod @staticmethod
def _merge(root,t): #-> int def _merge(root, t): # -> int
if root is None:return t if root is None:
if t is None:return root return t
if root<t: if t is None:
root,t=t,root return root
root.right = leftHeap._merge(root.right,t) if root < t:
root, t = t, root
root.right = leftHeap._merge(root.right, t)
if root.left is None or root.right is None: if root.left is None or root.right is None:
root.s=1 root.s = 1
if root.left is None: if root.left is None:
root.left,root.right = root.right,None root.left, root.right = root.right, None
else: else:
if root.left.s<root.right.s: if root.left.s < root.right.s:
root.left,root.right = root.right,root.left root.left, root.right = root.right, root.left
root.s = root.right.s+1 root.s = root.right.s+1
return root 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: if self.root is None:
self.root=nd self.root = nd
return return
if self.root==nd: if self.root == nd:
self.root.freq+=1 self.root.freq += 1
return return
prt =self. _findPrt(self.root,nd,None) prt = self. _findPrt(self.root, nd, None)
if prt is None: if prt is None:
self.root=leftHeap._merge(self.root,nd) 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)
else: 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 is not None:
if prt.left==nd: if prt.left == nd:
prt.left=leftHeap._merge(prt.left.left,prt.left.right) prt.left = leftHeap._merge(prt.left.left, prt.left.right)
else: else:
prt.right=leftHeap._merge(prt.right.left,prt.right.right) prt.right = leftHeap._merge(
def find(self,nd): prt.right.left, prt.right.right)
if not isinstance(nd,node):nd = node(nd)
prt = self._findPrt(self.root,nd,self.root) def find(self, nd):
if prt is None or prt==nd:return prt if not isinstance(nd, node):
elif prt.left==nd:return prt.left nd = node(nd)
else:return prt.right prt = self._findPrt(self.root, nd, self.root)
def _findPrt(self,root,nd,parent): if prt is None or prt == nd:
if not isinstance(nd,node):nd = node(nd) return prt
if root is None or root<nd:return None elif prt.left == nd:
if root==nd:return parent return prt.left
l=self._findPrt(root.left,nd,root) else:
return l if l is not None else self._findPrt(root.right,nd,root) 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): def getTop(self):
return self.root return self.root
def pop(self): def pop(self):
nd = self.root nd = self.root
self.remove(self.root.val) self.remove(self.root.val)
return nd return nd
def levelTraverse(self): def levelTraverse(self):
li = [(self.root,0)] li = [(self.root, 0)]
cur=0 cur = 0
while li: while li:
nd,lv = li.pop(0) nd, lv = li.pop(0)
if cur<lv: if cur < lv:
cur=lv cur = lv
print() print()
print(nd,end=' ') print(nd, end=' ')
else:print(nd,end=' ') else:
if nd.left is not None:li.append((nd.left,lv+1)) print(nd, end=' ')
if nd.right is not None:li.append((nd.right,lv+1)) 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__': if __name__ == '__main__':
lh = leftHeap() lh = leftHeap()
@ -123,7 +152,8 @@ if __name__ == '__main__':
print() print()
for i in data: for i in data:
print(lh.getTop()) 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)] data = [(i-10)**2 for i in range(20)]
node(100,freq=1,s=3) node(100,freq=1,s=3)

View File

@ -9,17 +9,21 @@
# Description: # Description:
######################################################################### #########################################################################
''' '''
class node: class node:
def __init__(self,val,follow=None): def __init__(self, val, follow=None):
self.val = val self.val = val
self.follow = follow self.follow = follow
class MyLinkedList: class MyLinkedList:
def __init__(self): def __init__(self):
""" """
Initialize your data structure here. Initialize your data structure here.
""" """
self.tail = self.head = node(None) self.tail = self.head = node(None)
def get(self, index): def get(self, index):
@ -31,7 +35,8 @@ class MyLinkedList:
nd = self.head nd = self.head
for i in range(index+1): for i in range(index+1):
nd = nd.follow nd = nd.follow
if nd is None:return -1 if nd is None:
return -1
return nd.val return nd.val
def addAtHead(self, val): def addAtHead(self, val):
@ -40,9 +45,11 @@ class MyLinkedList:
:type val: int :type val: int
:rtype: void :rtype: void
""" """
nd = node(val,self.head.follow) nd = node(val, self.head.follow)
self.head .follow = nd 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): def addAtTail(self, val):
""" """
Append a node of value val to the last element of the linked list. Append a node of value val to the last element of the linked list.
@ -51,7 +58,6 @@ class MyLinkedList:
""" """
self.tail.follow = node(val) self.tail.follow = node(val)
self.tail = self.tail.follow self.tail = self.tail.follow
def addAtIndex(self, index, val): def addAtIndex(self, index, val):
""" """
@ -65,11 +71,10 @@ class MyLinkedList:
nd = nd.follow nd = nd.follow
if nd is None: if nd is None:
return return
new = node(val,nd.follow) new = node(val, nd.follow)
nd.follow = new nd.follow = new
if self.tail == nd: if self.tail == nd:
self.tail = new self.tail = new
def deleteAtIndex(self, index): def deleteAtIndex(self, index):
""" """
@ -80,10 +85,12 @@ class MyLinkedList:
nd = self.head nd = self.head
for i in range(index): for i in range(index):
nd = nd.follow nd = nd.follow
if nd is None:return if nd is None:
if self.tail == nd.follow:self.tail = nd return
if nd.follow:nd.follow = nd.follow.follow 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: # Your MyLinkedList object will be instantiated and called as such:

View File

@ -13,138 +13,158 @@
#include<stdio.h> #include<stdio.h>
bool isZero(float a) bool isZero(float a)
{ {
return a<0.00001&&-a<0.00001; return a < 0.00001 && -a < 0.00001;
} }
template<class,class> class map; template<class, class> class map;
//notice that if you declare a class template,declare the class first like this. //notice that if you declare a class template,declare the class first like this.
template<class t1,class t2> template<class t1, class t2>
class pair class pair
{ {
friend class map<t1,t2>; friend class map<t1, t2>;
pair<t1,t2> *next; pair<t1, t2> *next;
public: public:
t1 first; t1 first;
t2 second; t2 second;
}; };
template<class t1,class t2> template<class t1, class t2>
class map class map
{ {
int n; int n;
pair<t1,t2> head; pair<t1, t2> head;
int cur; int cur;
pair<t1,t2> *last_visit; pair<t1, t2> *last_visit;
public: public:
map(); map();
~map(); ~map();
bool has(t1); bool has(t1);
void erase(t1); void erase(t1);
t2& operator[](t1); t2& operator[](t1);
pair<t1,t2> &locate(int index = -1); pair<t1, t2> &locate(int index = -1);
int size(); int size();
}; };
template<class t1,class t2> template<class t1, class t2>
map<t1,t2>::map(){ map<t1, t2>::map()
n=0; {
cur=-1; n = 0;
last_visit= &head; cur = -1;
head.next=NULL; last_visit = &head;
head.next = NULL;
head.first = head.second = 0; head.first = head.second = 0;
} }
template<class t1,class t2> template<class t1, class t2>
map<t1,t2>::~map() map<t1, t2>::~map()
{ {
pair<t1,t2> *p,*q=&head; pair<t1, t2> *p, *q = &head;
while(q!=NULL){
p=q->next; while (q != NULL) {
p = q->next;
delete q; delete q;
q=p; q = p;
} }
} }
template<class t1,class t2> template<class t1, class t2>
bool map<t1,t2>::has(t1 key) bool map<t1, t2>::has(t1 key)
{ {
pair<t1,t2> *p = head.next; pair<t1, t2> *p = head.next;
for(int i = 0;i<n&&p->first<=key;++i){
if(isZero(p->first-key)) return 1; for (int i = 0; i < n && p->first <= key; ++i) {
p=p->next; if (isZero(p->first - key)) return 1;
p = p->next;
} }
return 0; return 0;
} }
template<class t1,class t2> template<class t1, class t2>
pair<t1,t2>& map<t1,t2>::locate(int index) 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"); printf("the index is out of range\n");
return head; return head;
} }
if(cur>index){
if (cur > index) {
last_visit = &head; last_visit = &head;
cur = -1; cur = -1;
} }
while(cur<index){
while (cur < index) {
last_visit = last_visit->next; last_visit = last_visit->next;
++cur; ++cur;
} }
return *last_visit; return *last_visit;
} }
template<class t1,class t2> template<class t1, class t2>
int map<t1,t2>::size() int map<t1, t2>::size()
{ {
return n; return n;
} }
template<class t1,class t2> template<class t1, class t2>
t2& map<t1,t2>::operator[](t1 key) t2& map<t1, t2>::operator[](t1 key)
{ {
pair<t1,t2> * p=&head; pair<t1, t2> * p = &head;
while(p->next!=NULL){
if(isZero(p->next->first-key)) return p->next->second; while (p->next != NULL) {
else if(p->next->first>key){break;} if (isZero(p->next->first - key)) return p->next->second;
p=p->next; else if (p->next->first > key) {
break;
}
p = p->next;
} }
cur=-1;
last_visit= &head; cur = -1;
pair<t1,t2> *tmp = new pair<t1,t2>; last_visit = &head;
pair<t1, t2> *tmp = new pair<t1, t2>;
tmp ->next = p->next; tmp ->next = p->next;
tmp->first = key; tmp->first = key;
p->next = tmp; p->next = tmp;
++n; ++n;
return tmp->second; return tmp->second;
} }
template<class t1,class t2> template<class t1, class t2>
void map<t1,t2>::erase(t1 key) void map<t1, t2>::erase(t1 key)
{ {
pair<t1,t2> *p = &head; pair<t1, t2> *p = &head;
while(p->next!=NULL){
if(isZero(p->next->first-key)){ while (p->next != NULL) {
pair<t1,t2> *q = p->next; if (isZero(p->next->first - key)) {
pair<t1, t2> *q = p->next;
p->next = p->next->next; p->next = p->next->next;
delete q; delete q;
--n; --n;
break; break;
} }
p=p->next;
p = p->next;
} }
cur=-1;
last_visit= &head; cur = -1;
last_visit = &head;
} }
int main() int main()
{ {
map<double,float> b; map<double, float> b;
for(int i = 0;i<40;++i){
for (int i = 0; i < 40; ++i) {
b[i] = i; b[i] = i;
if(i%3){
if (i % 3) {
b[i] = 1; b[i] = 1;
} }
if(i%2){
if (i % 2) {
b.erase(i); 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; return 0;
} }

View File

@ -10,7 +10,7 @@
######################################################################### #########################################################################
*/ */
#include<cstdlib> #include<cstdlib>
#include<cstdio> #include<cstdio>
#include<cstring> #include<cstring>
#include<cmath> #include<cmath>
@ -19,16 +19,17 @@
using namespace std; using namespace std;
#if defined(__linux__) #if defined(__linux__)
#define LINUX true #define LINUX true
#elif defined(_WIN32) #elif defined(_WIN32)
#define LINUX false #define LINUX false
#endif #endif
bool isZero(double a) bool isZero(double a)
{ {
if((a<0.00001)&&-a<0.00001) if ((a < 0.00001) && -a < 0.00001)
return true; return true;
return false; return false;
} }
class node class node
@ -42,9 +43,9 @@ class polynomial
int SIZE; int SIZE;
int n; int n;
node* p; node* p;
public: public:
polynomial(int sz=50); polynomial(int sz = 50);
polynomial(const polynomial & ); polynomial(const polynomial &);
~polynomial(); ~polynomial();
double cal(double); double cal(double);
void getData(); void getData();
@ -54,10 +55,10 @@ class polynomial
polynomial operator-(const polynomial &); polynomial operator-(const 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]; p = (node*) new node[SIZE];
memset(p,0,sizeof(p)); memset(p, 0, sizeof(p));
} }
polynomial::~polynomial() polynomial::~polynomial()
{ {
@ -65,18 +66,21 @@ polynomial::~polynomial()
} }
double polynomial::cal(double x) double polynomial::cal(double x)
{ {
double rst=0; double rst = 0;
for(int i =0;i<n;++i){
rst += pow(x,p[i].index)*p[i].coefficient; for (int i = 0; i < n; ++i) {
rst += pow(x, p[i].index) * p[i].coefficient;
} }
return rst; return rst;
} }
polynomial::polynomial(const polynomial &a) polynomial::polynomial(const polynomial &a)
{ {
p = (node*) new node[50]; p = (node*) new node[50];
memset(p,0,sizeof(p)); memset(p, 0, sizeof(p));
n = a.n; 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].index = a.p[i].index;
p[i].coefficient = a.p[i].coefficient; p[i].coefficient = a.p[i].coefficient;
} }
@ -84,59 +88,72 @@ polynomial::polynomial(const polynomial &a)
polynomial polynomial::operator=(const polynomial& a) polynomial polynomial::operator=(const polynomial& a)
{ {
n = a.n; 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].index = a.p[i].index;
p[i].coefficient = a.p[i].coefficient; p[i].coefficient = a.p[i].coefficient;
} }
return *this; return *this;
} }
void polynomial::display() void polynomial::display()
{ {
node * tmp = p; node * tmp = p;
if(n == 0){
if (n == 0) {
printf("0\n"); printf("0\n");
return; 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 t = tmp[i].coefficient;
double idx = tmp[i].index; double idx = tmp[i].index;
if(isZero(idx)){
printf("%+g",t); if (isZero(idx)) {
printf("%+g", t);
continue; continue;
} }
if(isZero(t-1)) printf("+");
else if(isZero(t+1))printf("-"); if (isZero(t - 1)) printf("+");
else printf("%+g",t); else if (isZero(t + 1))printf("-");
else printf("%+g", t);
printf("x"); printf("x");
if(!isZero(idx-1)) printf("^%g",idx);
if (!isZero(idx - 1)) printf("^%g", idx);
} }
printf("\n"); printf("\n");
} }
void polynomial::getData() void polynomial::getData()
{ {
printf("Please input data . \n"); printf("Please input data . \n");
printf("For every item,Coefficient first .Use space to separate,EOF to end\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 idx;
double coef; double coef;
while(scanf("%lf%lf",&coef,&idx)!=EOF){
if(isZero(coef)) continue; while (scanf("%lf%lf", &coef, &idx) != EOF) {
if(mp.count(idx) == 0){ if (isZero(coef)) continue;
if (mp.count(idx) == 0) {
mp[idx] = coef; mp[idx] = coef;
} } else {
else{
mp[idx] += coef; mp[idx] += coef;
if(isZero(mp[idx])){
if (isZero(mp[idx])) {
mp.erase(idx); mp.erase(idx);
} }
} }
} }
if(mp.size()>SIZE){
SIZE *=2; if (mp.size() > SIZE) {
p = (node*)realloc(p,sizeof(node)*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].index = it->first;
p[n++].coefficient = it->second; p[n++].coefficient = it->second;
} }
@ -144,48 +161,52 @@ void polynomial::getData()
polynomial polynomial::operator+(const polynomial & a) polynomial polynomial::operator+(const polynomial & a)
{ {
polynomial rst ; polynomial rst ;
int p1 = 0,p2 = 0,p3 = 0; int p1 = 0, p2 = 0, p3 = 0;
double exp1 = p[p1].index; double exp1 = p[p1].index;
double exp2 = a.p[p2].index; double exp2 = a.p[p2].index;
while(p1<n && p2<a.n){
while(p1<n &&exp1<exp2){ while (p1 < n && p2 < a.n) {
rst.p[p3].index = exp1; while (p1 < n && exp1 < exp2) {
rst.p[p3].coefficient = p[p1].coefficient; rst.p[p3].index = exp1;
++p1,++p3; rst.p[p3].coefficient = p[p1].coefficient;
exp1 = p[p1].index;; ++p1, ++p3;
exp1 = p[p1].index;;
} }
while(p2<a.n &&exp1>exp2){
rst.p[p3].index = exp2; while (p2 < a.n && exp1 > exp2) {
rst.p[p3].coefficient = a.p[p2].coefficient; rst.p[p3].index = exp2;
++p2,++p3; rst.p[p3].coefficient = a.p[p2].coefficient;
exp2 = a.p[p2].index;; ++p2, ++p3;
exp2 = a.p[p2].index;;
} }
if(isZero(exp1-exp2)){
double tmp= p[p1].coefficient + a.p[p2].coefficient; if (isZero(exp1 - exp2)) {
if(isZero(tmp)){ double tmp = p[p1].coefficient + a.p[p2].coefficient;
++p1,++p2;
} if (isZero(tmp)) {
else{ ++p1, ++p2;
} else {
rst.p[p3].index = p[p1].index; rst.p[p3].index = p[p1].index;
rst.p[p3].coefficient = tmp; 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].index = a.p[p2].index;
rst.p[p3].coefficient = a.p[p2].coefficient; rst.p[p3].coefficient = a.p[p2].coefficient;
++p2,++p3; ++p2, ++p3;
} }
} } else {
else{ while (p1 < n) {
while(p1<n){
rst.p[p3].index = p[p1].index; rst.p[p3].index = p[p1].index;
rst.p[p3].coefficient = p[p1].coefficient; rst.p[p3].coefficient = p[p1].coefficient;
++p1,++p3; ++p1, ++p3;
} }
} }
rst.n = p3; rst.n = p3;
return rst; return rst;
} }
@ -193,40 +214,50 @@ polynomial polynomial::operator-(const polynomial & a)
{ {
polynomial rst(a) ; polynomial rst(a) ;
int i = 0; int i = 0;
while(i<rst.n){
while (i < rst.n) {
rst.p[i].coefficient = -rst.p[i].coefficient; rst.p[i].coefficient = -rst.p[i].coefficient;
++i; ++i;
} }
return (*this + rst); return (*this + rst);
} }
polynomial polynomial::operator*(const polynomial & a) polynomial polynomial::operator*(const polynomial & a)
{ {
map<double,double> mp; map<double, double> mp;
for(int i = 0;i<n;++i){
for (int i = 0; i < n; ++i) {
double idx = p[i].index; double idx = p[i].index;
double coef = p[i].coefficient; double coef = p[i].coefficient;
for(int j = 0;j<a.n;++j){
double index = idx+a.p[j].index; for (int j = 0; j < a.n; ++j) {
if(mp.count(index)==0){ double index = idx + a.p[j].index;
mp[index] = coef*a.p[j].coefficient;
} if (mp.count(index) == 0) {
else{ mp[index] = coef * a.p[j].coefficient;
mp[index] += coef*a.p[j].coefficient; } else {
if(isZero(mp[index])){ mp[index] += coef * a.p[j].coefficient;
if (isZero(mp[index])) {
mp.erase(index); mp.erase(index);
} }
} }
} }
} }
int sz =50;
while(mp.size()>sz){ int sz = 50;
sz *=2;
while (mp.size() > sz) {
sz *= 2;
} }
polynomial rst(sz); 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].index = it->first;
rst.p[rst.n++].coefficient = it->second; rst.p[rst.n++].coefficient = it->second;
} }
return rst; return rst;
} }
int num = 0; int num = 0;
@ -250,94 +281,94 @@ void menu()
void loop() void loop()
{ {
int op; int op;
while(scanf("%d",&op)!=EOF){
if(op == 0){ while (scanf("%d", &op) != EOF) {
pl[num].getData(); if (op == 0) {
++num; pl[num].getData();
printf("You've created polynomial %d:\n",num); ++num;
pl[num-1].display(); 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("input two nums of the two polynomial to be operated.eg: 1 2\n");
printf("Oops! you've got less two polynomial\nPlease choose another operation\n"); int t1 = 100, t2 = 100;
continue;
} while (1) {
printf("input two nums of the two polynomial to be operated.eg: 1 2\n"); scanf("%d%d", &t1, &t2);
int t1=100,t2=100;
while(1){ if (t1 > num || t2 > num || t1 < 0 || t2 < 0) {
scanf("%d%d",&t1,&t2); printf("wrong num ,please input again\n");
if(t1>num||t2>num||t1<0||t2<0){ } else break;
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();
} }
else if(op == 4){
printf("input a polynomial's num to display it\n"); printf("the rst is:\n");
int tmp; t1 -= 1, t2 -= 1;
scanf("%d",&tmp);
if(tmp>num){ if (op == 1) {
printf("wrong num"); (pl[t1] + pl[t2]).display();
} } else if (op == 2) {
else{ (pl[t1] - pl[t2]).display();
printf("info of polynomial %d\n",tmp); } else (pl[t1]*pl[t2]).display();
pl[tmp-1].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){ } else if (op == 9) {
for(int i = 0;i<num;++i){ for (int i = 0; i < num; ++i) {
printf("polynomial %d : ",i+1); printf("polynomial %d : ", i + 1);
pl[i].display(); pl[i].display();
}
} }
else if(op == 5){ } else if (op == 5) {
menu(); 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){ } else if (op == 8) {
if(LINUX) system("clear"); if (num == 0) {
else system("cls"); printf("you have'nt any polynomial tp copy\n");
menu(); continue;
} }
else if(op == 10){
double x; int n = num + 1;
int t;
printf("choose a polynomial\n"); while (n > num) {
scanf("%d",&t); printf("input the number of an existing polynomial you want to copy\n");
if(t>num||t<0){ scanf("%d", &n);
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 == 8){
if(num == 0){ (pl[num] = pl[n - 1]);
printf("you have'nt any polynomial tp copy\n"); printf("You've copyed this polynomial:\n");
continue; pl[num++].display();
} } else exit(0);
int n = num+1;
while(n>num){ printf("select an operation\n");
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");
} }
} }
int main(void) int main(void)

View File

@ -11,61 +11,71 @@
''' '''
#!/bin/python3 #!/bin/python3
# notice that creating a class's initialization won't conflict with __call__ method # notice that creating a class's initialization won't conflict with __call__ method
# because the former call class ,and the latter call instance # because the former call class ,and the latter call instance
# to be implemented # to be implemented
class polynomial: class polynomial:
pls= [] pls = []
n = 0 n = 0
def dictize(pl): def dictize(pl):
if isinstance(pl,int) or isinstance(pl,float): if isinstance(pl, int) or isinstance(pl, float):
pl = {0:pl} pl = {0: pl}
if isinstance(pl,polynomial): if isinstance(pl, polynomial):
pl = pl.polynomial.copy() pl = pl.polynomial.copy()
return pl return pl
def isZero(n): def isZero(n):
return abs(n)<0.000001 return abs(n) < 0.000001
def __init__(self,s='0 0'):
def __init__(self, s='0 0'):
polynomial.pls.append(self) polynomial.pls.append(self)
polynomial.n +=1 polynomial.n += 1
if isinstance(s,polynomial): if isinstance(s, polynomial):
self.polynomial=s.polynomial.copy() self.polynomial = s.polynomial.copy()
# don't write like this .**self.polynomial = s.polynomial**,it's ref # don't write like this .**self.polynomial = s.polynomial**,it's ref
return return
elif isinstance(s,dict): elif isinstance(s, dict):
self.polynomial = s.copy() self.polynomial = s.copy()
return return
s= s.replace(',',' ') s = s.replace(',', ' ')
s= s.replace('x',' ') s = s.replace('x', ' ')
s= s.replace('x^',' ') s = s.replace('x^', ' ')
s = s.replace(':',' ') s = s.replace(':', ' ')
s = s.replace('\n',' ') s = s.replace('\n', ' ')
s = s.split(' ') s = s.split(' ')
num = len(s) num = len(s)
i = 0 i = 0
print(s) print(s)
self.polynomial = dict() self.polynomial = dict()
li = [float(i) for i in s] li = [float(i) for i in s]
while i<num: while i < num:
if not polynomial.isZero(li[i]): if not polynomial.isZero(li[i]):
index = li[i+1] index = li[i+1]
if index in self.polynomial.keys(): if index in self.polynomial.keys():
self.polynomial[index] += li[i] self.polynomial[index] += li[i]
else:self.polynomial[index] = li[i] else:
i+=2 self.polynomial[index] = li[i]
i += 2
if not self.polynomial: if not self.polynomial:
self.polynomial = {0:0} self.polynomial = {0: 0}
def __iter__(self): def __iter__(self):
return iter(list(self.polynomial.keys())) return iter(list(self.polynomial.keys()))
def __getitem__(self,key):
def __getitem__(self, key):
return self.polynomial[key] return self.polynomial[key]
def __setitem__(self,key,val):
def __setitem__(self, key, val):
self.polynomial[key] = val self.polynomial[key] = val
def __delitem__(self,k):
def __delitem__(self, k):
del self.polynomial[k] del self.polynomial[k]
def __add__(self,pl):
def __add__(self, pl):
pl = polynomial.dictize(pl) pl = polynomial.dictize(pl)
rst = self.polynomial.copy() rst = self.polynomial.copy()
for i in pl: for i in pl:
@ -76,7 +86,8 @@ class polynomial:
if polynomial.isZero(rst[i]): if polynomial.isZero(rst[i]):
del rst[i] del rst[i]
return polynomial(rst) return polynomial(rst)
def __iadd__(self,pl):
def __iadd__(self, pl):
pl = polynomial.dictize(pl) pl = polynomial.dictize(pl)
for i in pl: for i in pl:
if i not in self: if i not in self:
@ -86,72 +97,90 @@ class polynomial:
if polynomial.isZero(self[i]): if polynomial.isZero(self[i]):
del self[i] del self[i]
return self return self
def __sub__(self,pl):
def __sub__(self, pl):
pl = polynomial.dictize(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 return self + tmp
def __mul__(self,pl):
def __mul__(self, pl):
pl = polynomial.dictize(pl) pl = polynomial.dictize(pl)
dic = dict() dic = dict()
for i in pl: for i in pl:
for j in self: for j in self:
index= i+j index = i+j
if index in dic: if index in dic:
dic[index] += pl[i]*self[j] dic[index] += pl[i]*self[j]
else:dic[index] = pl[i]*self[j] else:
return polynomial({i:j for i,j in dic.items() if not polynomial.isZero(j)}) dic[index] = pl[i]*self[j]
def __imul__(self,pl): return polynomial({i: j for i, j in dic.items() if not polynomial.isZero(j)})
def __imul__(self, pl):
self = self*pl self = self*pl
return self return self
def __pow__(self,n):
rst = polynomial({0:1}) def __pow__(self, n):
rst = polynomial({0: 1})
for i in range(n): for i in range(n):
rst*=self.polynomial rst *= self.polynomial
return rst return rst
def __repr__(self): def __repr__(self):
return self.__str__() return self.__str__()
def __str__(self): def __str__(self):
output = '' output = ''
if self.polynomial: if self.polynomial:
key = sorted(self.polynomial.keys(),reverse = True) key = sorted(self.polynomial.keys(), reverse=True)
num = len(key) num = len(key)
for j,i in enumerate(key): for j, i in enumerate(key):
if polynomial.isZero(i): if polynomial.isZero(i):
output +='%+g'%self[i] output += '%+g' % self[i]
continue continue
if not polynomial.isZero(self[i]-1): if not polynomial.isZero(self[i]-1):
if not polynomial.isZero(self[i]+1): if not polynomial.isZero(self[i]+1):
output +="%+g"%self[i] output += "%+g" % self[i]
else:output +='-' else:
else:output +='+' output += '-'
if not polynomial.isZero(i): output +='x' else:
if not polynomial.isZero(i-1):output +='^%g'%i output += '+'
if not polynomial.isZero(i):
output += 'x'
if not polynomial.isZero(i-1):
output += '^%g' % i
if output[0] == '+': if output[0] == '+':
return output[1:] return output[1:]
return output return output
def iterPolynomial(self,s):
rst = polynomial({0:0}) def iterPolynomial(self, s):
rst = polynomial({0: 0})
for i in self: for i in self:
rst += s**int(i)*self[i] rst += s**int(i)*self[i]
return rst return rst
def __call__(self,s):
if isinstance(s,polynomial): def __call__(self, s):
return self.iterPolynomial(s) if isinstance(s, polynomial):
return self.iterPolynomial(s)
sum = 0 sum = 0
for i in self: for i in self:
sum += self[i] * s**i sum += self[i] * s**i
return sum return sum
def __xor__(self,n):
def __xor__(self, n):
tmp = polynomial(self) tmp = polynomial(self)
for i in range(n): for i in range(n):
self = self.iterPolynomial(tmp) self = self.iterPolynomial(tmp)
return self return self
def save(self): def save(self):
polynomial.pls.append(self) polynomial.pls.append(self)
polynomial.n +=1 polynomial.n += 1
def delPlynomial(self,n):
def delPlynomial(self, n):
return polynomial.pls.pop(n-1) return polynomial.pls.pop(n-1)
def menu(): def menu():
print('polynomial operations') print('polynomial operations')
print('1.create') print('1.create')
@ -166,5 +195,6 @@ def menu():
print('10.menu') print('10.menu')
print('11.exit') print('11.exit')
if __name__ == '__main__': if __name__ == '__main__':
pass pass

View File

@ -12,36 +12,50 @@
from functools import total_ordering from functools import total_ordering
from random import randint, shuffle from random import randint, shuffle
@total_ordering @total_ordering
class node: class node:
def __init__(self,val,left=None,right=None,isBlack=False): def __init__(self, val, left=None, right=None, isBlack=False):
self.val =val self.val = val
self.left = left self.left = left
self.right = right self.right = right
self.parent= None self.parent = None
self.isBlack = isBlack self.isBlack = isBlack
def __lt__(self,nd):
return self.val < nd.val def __lt__(self, nd):
def __eq__(self,nd): return self.val < nd.val
return nd is not None and self.val == nd.val
def setChild(self,nd,isLeft): def __eq__(self, nd):
if isLeft: self.left = nd return nd is not None and self.val == nd.val
else: self.right = nd
if nd is not None: nd.parent = self 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): def __bool__(self):
return self.val is not None return self.val is not None
def __str__(self): def __str__(self):
color = 'B' if self.isBlack else 'R' 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}' return f'{color}-{self.val}'
def __repr__(self): def __repr__(self):
return f'node({self.val},isBlack={self.isBlack})' return f'node({self.val},isBlack={self.isBlack})'
class redBlackTree: 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''' '''if unique is True, all node'vals are unique, else there may be equal vals'''
self.root = None self.root = None
self.unique = unique self.unique = unique
@ -49,23 +63,29 @@ class redBlackTree:
@staticmethod @staticmethod
def checkBlack(nd): def checkBlack(nd):
return nd is None or nd.isBlack return nd is None or nd.isBlack
@staticmethod @staticmethod
def setBlack(nd,isBlack): def setBlack(nd, isBlack):
if nd is not None: if nd is not None:
if isBlack is None or isBlack: if isBlack is None or isBlack:
nd.isBlack = True nd.isBlack = True
else:nd.isBlack = False else:
def setRoot(self,nd): nd.isBlack = False
if nd is not None: nd.parent=None
self.root= nd def setRoot(self, nd):
def find(self,val): if nd is not None:
nd.parent = None
self.root = nd
def find(self, val):
nd = self.root nd = self.root
while nd: while nd:
if nd.val ==val: if nd.val == val:
return nd return nd
else: else:
nd = nd.getChild(nd.val>val) nd = nd.getChild(nd.val > val)
def getSuccessor(self,nd):
def getSuccessor(self, nd):
if nd: if nd:
if nd.right: if nd.right:
nd = nd.right nd = nd.right
@ -76,18 +96,20 @@ class redBlackTree:
while nd.parent is not None and nd.parent.right is nd: while nd.parent is not None and nd.parent.right is nd:
nd = nd.parent nd = nd.parent
return None if nd is self.root else nd.parent return None if nd is self.root else nd.parent
def rotate(self,prt,chd):
'''rotate prt with the center of chd''' def rotate(self, prt, chd):
'''rotate prt with the center of chd'''
if self.root is prt: if self.root is prt:
self.setRoot(chd) self.setRoot(chd)
else: else:
prt.parent.setChild(chd, prt.parent.left is prt) prt.parent.setChild(chd, prt.parent.left is prt)
isLeftChd = prt.left is chd isLeftChd = prt.left is chd
prt.setChild(chd.getChild(not isLeftChd), isLeftChd) prt.setChild(chd.getChild(not isLeftChd), isLeftChd)
chd.setChild(prt,not isLeftChd) chd.setChild(prt, not isLeftChd)
def insert(self,nd): def insert(self, nd):
if nd.isBlack: nd.isBlack = False if nd.isBlack:
nd.isBlack = False
if self.root is None: if self.root is None:
self.setRoot(nd) self.setRoot(nd)
@ -95,16 +117,18 @@ class redBlackTree:
else: else:
parent = self.root parent = self.root
while parent: while parent:
if parent == nd : return None if parent == nd:
return None
isLeft = parent > nd isLeft = parent > nd
chd = parent.getChild(isLeft) chd = parent.getChild(isLeft)
if chd is None: if chd is None:
parent.setChild(nd,isLeft) parent.setChild(nd, isLeft)
break break
else: else:
parent = chd parent = chd
self.fixUpInsert(parent,nd) self.fixUpInsert(parent, nd)
def fixUpInsert(self,parent,nd):
def fixUpInsert(self, parent, nd):
''' adjust color and level, there are two red nodes: the new one and its parent''' ''' adjust color and level, there are two red nodes: the new one and its parent'''
while not self.checkBlack(parent): while not self.checkBlack(parent):
grand = parent.parent grand = parent.parent
@ -125,8 +149,8 @@ class redBlackTree:
# grand grand # grand grand
# parent or parent # parent or parent
# nd nd # nd nd
self.rotate(parent,nd) #parent rotate self.rotate(parent, nd) # parent rotate
nd,parent = parent,nd nd, parent = parent, nd
# case 3 (case 2.2) the new node is inserted in left-left or right-right form # case 3 (case 2.2) the new node is inserted in left-left or right-right form
# grand grand # grand grand
# parent or parent # parent or parent
@ -134,25 +158,29 @@ class redBlackTree:
self.setBlack(grand, False) self.setBlack(grand, False)
self.setBlack(parent, True) self.setBlack(parent, True)
self.rotate(grand,parent) self.rotate(grand, parent)
self.setBlack(self.root,True) self.setBlack(self.root, True)
def copyNode(self,src,des): def copyNode(self, src, des):
'''when deleting a node which has two kids, '''when deleting a node which has two kids,
copy its succesor's data to his position copy its succesor's data to his position
data exclude left, right , isBlack data exclude left, right , isBlack
''' '''
des.val = src.val des.val = src.val
def delete(self,val):
def delete(self, val):
'''delete node in a binary search tree''' '''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) nd = self.find(val)
if nd is None: return if nd is None:
return
self._delete(nd) self._delete(nd)
def _delete(self,nd):
def _delete(self, nd):
y = None y = None
if nd.left and nd.right: if nd.left and nd.right:
y= self.getSuccessor(nd) y = self.getSuccessor(nd)
else: else:
y = nd y = nd
py = y.parent py = y.parent
@ -160,58 +188,60 @@ class redBlackTree:
if py is None: if py is None:
self.setRoot(x) self.setRoot(x)
else: else:
py.setChild(x,py.left is y) py.setChild(x, py.left is y)
if y != nd: if y != nd:
self.copyNode(y,nd) self.copyNode(y, nd)
if self.checkBlack(y): self.fixUpDel(py,x) if self.checkBlack(y):
self.fixUpDel(py, x)
def fixUpDel(self,prt,chd):
def fixUpDel(self, prt, chd):
''' adjust colors and rotate ''' ''' adjust colors and rotate '''
while self.root != chd and self.checkBlack(chd): while self.root != chd and self.checkBlack(chd):
isLeft =prt.left is chd isLeft = prt.left is chd
brother = prt.getChild(not isLeft) brother = prt.getChild(not isLeft)
# brother is black # brother is black
lb = self.checkBlack(brother.getChild(isLeft)) lb = self.checkBlack(brother.getChild(isLeft))
rb = self.checkBlack(brother.getChild(not 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 # case 1: brother is red. converted to case 2,3,4
self.setBlack(prt,False) self.setBlack(prt, False)
self.setBlack(brother,True) self.setBlack(brother, True)
self.rotate(prt,brother) self.rotate(prt, brother)
elif lb and rb: elif lb and rb:
# case 2: brother is black and two kids are black. # case 2: brother is black and two kids are black.
# conveted to the begin case # conveted to the begin case
self.setBlack(brother,False) self.setBlack(brother, False)
chd = prt chd = prt
prt= chd.parent prt = chd.parent
else: else:
if rb: if rb:
# case 3: brother is black and left kid is red and right child is black # 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 # rotate bro to make g w wl wr in one line
# uncle's son is nephew, and niece for uncle's daughter # uncle's son is nephew, and niece for uncle's daughter
nephew = brother.getChild(isLeft) nephew = brother.getChild(isLeft)
self.setBlack(nephew,True) self.setBlack(nephew, True)
self.setBlack(brother,False) self.setBlack(brother, False)
# brother (not isLeft) rotate # brother (not isLeft) rotate
self.rotate(brother,nephew) self.rotate(brother, nephew)
brother = nephew brother = nephew
# case 4: brother is black and right child is red # case 4: brother is black and right child is red
brother.isBlack = prt.isBlack brother.isBlack = prt.isBlack
self.setBlack(prt,True) self.setBlack(prt, True)
self.setBlack(brother.getChild(not isLeft),True) self.setBlack(brother.getChild(not isLeft), True)
self.rotate(prt,brother) self.rotate(prt, brother)
chd = self.root 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''' ''' return a generator of sorted data'''
def inOrder(root): def inOrder(root):
if root is None:return if root is None:
return
if reverse: if reverse:
yield from inOrder(root.right) yield from inOrder(root.right)
else: else:
@ -225,8 +255,10 @@ class redBlackTree:
def display(self): def display(self):
def getHeight(nd): def getHeight(nd):
if nd is None:return 0 if nd is None:
return max(getHeight(nd.left),getHeight(nd.right)) +1 return 0
return max(getHeight(nd.left), getHeight(nd.right)) + 1
def levelVisit(root): def levelVisit(root):
from collections import deque from collections import deque
lst = deque([root]) lst = deque([root])
@ -234,24 +266,26 @@ class redBlackTree:
h = getHeight(root) h = getHeight(root)
ct = lv = 0 ct = lv = 0
while 1: while 1:
ct+=1 ct += 1
nd = lst.popleft() nd = lst.popleft()
if ct >= 2**lv: if ct >= 2**lv:
lv+=1 lv += 1
if lv>h:break if lv > h:
break
level.append([]) level.append([])
level[-1].append(str(nd)) level[-1].append(str(nd))
if nd is not None: if nd is not None:
lst += [nd.left,nd.right] lst += [nd.left, nd.right]
else: else:
lst +=[None,None] lst += [None, None]
return level return level
def addBlank(lines): def addBlank(lines):
width = 1+len(str(self.root)) width = 1+len(str(self.root))
sep = ' '*width sep = ' '*width
n = len(lines) n = len(lines)
for i,oneline in enumerate(lines): for i, oneline in enumerate(lines):
k = 2**(n-i) -1 k = 2**(n-i) - 1
new = [sep*((k-1)//2)] new = [sep*((k-1)//2)]
for s in oneline: for s in oneline:
new.append(s.ljust(width)) new.append(s.ljust(width))
@ -262,59 +296,67 @@ class redBlackTree:
lines = levelVisit(self.root) lines = levelVisit(self.root)
lines = addBlank(lines) lines = addBlank(lines)
li = [''.join(line) for line in lines] li = [''.join(line) for line in lines]
length = 10 if li==[] else max(len(i) for i in li)//2 length = 10 if li == [] else max(len(i) for i in li)//2
begin ='\n'+ 'red-black-tree'.rjust(length+14,'-') + '-'*(length) begin = '\n' + 'red-black-tree'.rjust(length+14, '-') + '-'*(length)
end = '-'*(length*2+14)+'\n' end = '-'*(length*2+14)+'\n'
return '\n'.join([begin,*li,end]) return '\n'.join([begin, *li, end])
def __str__(self): def __str__(self):
return self.display() return self.display()
def genNum(n =10): def genNum(n=10):
nums =[] nums = []
for i in range(n): for i in range(n):
while 1: while 1:
d = randint(0,100) d = randint(0, 100)
if d not in nums: if d not in nums:
nums.append(d) nums.append(d)
break break
return nums 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() rbtree = redBlackTree()
print(f'build a red-black tree using {nums}') print(f'build a red-black tree using {nums}')
for i in nums: for i in nums:
rbtree.insert(node(i)) rbtree.insert(node(i))
print(rbtree) print(rbtree)
if visitor: if visitor:
visitor(rbtree,i) visitor(rbtree, i)
return rbtree,nums return rbtree, nums
def testInsert(nums=None): def testInsert(nums=None):
def visitor(t,val): def visitor(t, val):
print('inserting', val) print('inserting', val)
print(t) print(t)
rbtree,nums = buildTree(visitor = visitor,nums=nums) rbtree, nums = buildTree(visitor=visitor, nums=nums)
print('-'*5+ 'in-order visit' + '-'*5) print('-'*5 + 'in-order visit' + '-'*5)
for i,j in enumerate(rbtree.sort()): for i, j in enumerate(rbtree.sort()):
print(f'{i+1}: {j}') print(f'{i+1}: {j}')
def testSuc(nums=None): def testSuc(nums=None):
rbtree,nums = buildTree(nums=nums) rbtree, nums = buildTree(nums=nums)
for i in rbtree.sort(): for i in rbtree.sort():
print(f'{i}\'s suc is {rbtree.getSuccessor(i)}') print(f'{i}\'s suc is {rbtree.getSuccessor(i)}')
def testDelete(nums=None): def testDelete(nums=None):
rbtree,nums = buildTree(nums = nums) rbtree, nums = buildTree(nums=nums)
print(rbtree) print(rbtree)
for i in sorted(nums): for i in sorted(nums):
print(f'deleting {i}') print(f'deleting {i}')
rbtree.delete(i) rbtree.delete(i)
print(rbtree) print(rbtree)
if __name__=='__main__':
lst =[45, 30, 64, 36, 95, 38, 76, 34, 50, 1] if __name__ == '__main__':
lst = [0,3,5,6,26,25,8,19,15,16,17] lst = [45, 30, 64, 36, 95, 38, 76, 34, 50, 1]
#testSuc(lst) lst = [0, 3, 5, 6, 26, 25, 8, 19, 15, 16, 17]
#testInsert(lst) # testSuc(lst)
# testInsert(lst)
testDelete() testDelete()

View File

@ -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 # use isinstance(obj,Iterable) to judge if an obj is iterable
class node: 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 self.val = val
if val :self.freq = 1 if val:
else :self.freq = 0 self.freq = 1
else:
self.freq = 0
self.left = left self.left = left
self.right = right self.right = right
self.parent = parent 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 last = self
for i in s: for i in s:
if not last:return None if not last:
if i == 0: last = last.left return None
else:last = last.right if i == 0:
last = last.left
else:
last = last.right
return last 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] i = s[0]
del s[0] del s[0]
if i == 0:self.left.setChild(child,s) if i == 0:
else:self.right.setChild(child,s) self.left.setChild(child, s)
elif s:self.right = child else:
else:self.left = child self.right.setChild(child, s)
elif s:
self.right = child
else:
self.left = child
class splayTree: class splayTree:
def __init__(self,s=[]): def __init__(self, s=[]):
s = list(s) s = list(s)
self.root = None self.root = None
s = sorted(s,reverse = True) s = sorted(s, reverse=True)
for i in s: for i in s:
self.insert(self.root,i) self.insert(self.root, i)
def insert(self,k):
if not self.root :self.root = node(k) def insert(self, k):
else:self._insert(self.root,k) if not self.root:
def _insert(self,root,k): self.root = node(k)
if root.val == k : else:
root.freq +=1 self._insert(self.root, k)
elif root.val<k:
def _insert(self, root, k):
if root.val == k:
root.freq += 1
elif root.val < k:
if not root.right: if not root.right:
root.right = node(k) root.right = node(k)
root.right.parent = root root.right.parent = root
else:self._insert(root.right,k) else:
self._insert(root.right, k)
else: else:
if not root.left: if not root.left:
root.left = node(k) root.left = node(k)
root.left.parent = root root.left.parent = root
else:self._insert(root.left,k) else:
def _zigzagRotate(self,i,j,root,parent,grand): self._insert(root.left, k)
parent.setChild(root.getChild(i),j)
root.setChild(parent,i) def _zigzagRotate(self, i, j, root, parent, grand):
grand.setChild(root.getChild(j),i) parent.setChild(root.getChild(i), j)
root.setChild(grand,j) root.setChild(parent, i)
if root.parent:root.parent = grand.parent grand.setChild(root.getChild(j), i)
root.setChild(grand, j)
if root.parent:
root.parent = grand.parent
parent.parent = root parent.parent = root
grand.parent = root grand.parent = root
def _lineRotate(self,i,root,parent,grand):
grand.setChild(parent.getChild(i^1),i) def _lineRotate(self, i, root, parent, grand):
parent.setChild(grand,i^1) grand.setChild(parent.getChild(i ^ 1), i)
parent.setChild(root.getChild(i^1),i) parent.setChild(grand, i ^ 1)
root.setChild(parent,i^1) parent.setChild(root.getChild(i ^ 1), i)
if root.parent:root.parent = grand.parent root.setChild(parent, i ^ 1)
parent.parent = root if root.parent:
root.parent = grand.parent
parent.parent = root
grand.parent = parent 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: if root.parent == self.root:
for i in range(2): for i in range(2):
if root.parent.getChild(i) == root: if root.parent.getChild(i) == root:
root.parent.parent = 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.parent = None
root.setChild(self.root,i^1) root.setChild(self.root, i ^ 1)
self.root = root self.root = root
else: else:
grand = root.parent.parent grand = root.parent.parent
parent = root.parent parent = root.parent
if grand == self.root: if grand == self.root:
self.root = root self.root = root
root.parent = None root.parent = None
else: else:
for i in range(2): for i in range(2):
if grand.parent.getChild(i) == grand: if grand.parent.getChild(i) == grand:
grand.parent.setChild(root,i) grand.parent.setChild(root, i)
for i in range(2): for i in range(2):
for j in range(2): for j in range(2):
if i!=j and grand.getChild([i,j]) == root: if i != j and grand.getChild([i, j]) == root:
self._zigzagRotate(i,j,root,parent,grand) self._zigzagRotate(i, j, root, parent, grand)
elif i==j and grand.getChild([i,i]) == root: elif i == j and grand.getChild([i, i]) == root:
self._lineRotate(i,root,parent,grand) self._lineRotate(i, root, parent, grand)
self._rotate(root) 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: if root.val > k:
return self._find(root.left,k) return self._find(root.left, k)
elif root.val<k: elif root.val < k:
return self._find(root.right,k) return self._find(root.right, k)
else: else:
self._rotate(root) self._rotate(root)
return root.freq 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): if root.getChild(i):
return self._maxmin(root.getChild(i)) return self._maxmin(root.getChild(i))
return root return root
def Max(self): def Max(self):
return self._maxmin(self.root,1) return self._maxmin(self.root, 1)
def Min(self): def Min(self):
return self._maxmin(self.root,0) return self._maxmin(self.root, 0)
def remove(self,k):
def remove(self, k):
tmp = self.find(k) tmp = self.find(k)
if not tmp:raise ValueError if not tmp:
raise ValueError
else: else:
if self.root.left: if self.root.left:
r = self.root.right r = self.root.right
self.root = self.root.left self.root = self.root.left
self.root.parent = None self.root.parent = None
Max = self.Max() Max = self.Max()
Max.right= r Max.right = r
if r: if r:
r.parent = Max r.parent = Max
else: else:
self.root = self.root.right 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): def levelTraverse(self):
q = deque() q = deque()
q.append((self.root,0)) q.append((self.root, 0))
rst = [] rst = []
while q: while q:
tmp,n= q.popleft() tmp, n = q.popleft()
rst.append(tmp) rst.append(tmp)
if tmp.left:q.append((tmp.left,n+1)) if tmp.left:
if tmp.right:q.append((tmp.right,n+1)) q.append((tmp.left, n+1))
if tmp.right:
q.append((tmp.right, n+1))
return rst return rst
def display(self): def display(self):
data = self.levelTraverse() data = self.levelTraverse()
for i in data: for i in data:
print (i.val,end=' ') print(i.val, end=' ')
print('') print('')
if __name__ == '__main__': if __name__ == '__main__':
a = splayTree() a = splayTree()
a.insert(5) a.insert(5)
@ -165,7 +207,7 @@ if __name__ == '__main__':
print('initial:5,1,4,2,7,8,2') print('initial:5,1,4,2,7,8,2')
a.display() a.display()
tmp = a.find(2) tmp = a.find(2)
print("after find(2):%d"%tmp) print("after find(2):%d" % tmp)
a.display() a.display()
print("remove(4)") print("remove(4)")
a.remove(4) a.remove(4)

View File

@ -0,0 +1,12 @@
class unionFindSet:
def __init__(self, S):
self.S = {i: i for i in S}
def find(self, x):
if x != self.S[x]:
self.S[x] = self.find(self.S[x])
return self.S[x]
def union(self, a, b, key=lambda x: x):
x, y = sorted((self.find(a), self.find(b)), key=key)
self.S[a] = self.S[b] = self.S[y] = x

View File

@ -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]

View File

@ -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]

View File

@ -10,6 +10,7 @@
######################################################################### #########################################################################
''' '''
class winnerTree: class winnerTree:
'''if i<lowExt p = (i+offset)//2 '''if i<lowExt p = (i+offset)//2
else p = (i+n-1-lowExt)//2 else p = (i+n-1-lowExt)//2
@ -18,79 +19,92 @@ class winnerTree:
i is the index of players i is the index of players
lowExt is the double node num of the lowest layer of the tree 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 self.tree = [0]*self.n
players.insert(0,0) players.insert(0, 0)
self.players=players self.players = players
self.reverse=reverse self.reverse = reverse
self.getNum() self.getNum()
self.initTree(1) self.initTree(1)
def getNum(self): def getNum(self):
i=1 i = 1
while 2*i< self.n:i=i*2 while 2*i < self.n:
if 2*i ==self. n: i = i*2
self.lowExt=0 if 2*i == self. n:
self.lowExt = 0
self.s = 2*i-1 self.s = 2*i-1
else: else:
self.lowExt = (self.n-i)*2 self.lowExt = (self.n-i)*2
self.s = i-1 self.s = i-1
self.offset = 2*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 treeToArray(self, p):
def arrayToTree(self,i): return 2*p-self.offset if p > self.s else 2*p+self.lowExt-self.n+1
return (i+self.offset)//2 if i<=self.lowExt else (i-self.lowExt+ self.n-1)//2
def win(self,a,b): def arrayToTree(self, i):
return a<b if self.reverse else a>b return (i+self.offset)//2 if i <= self.lowExt else (i-self.lowExt + self.n-1)//2
def initTree(self,p):
if p>=self.n: def win(self, a, b):
delta = p%2 #!!! good job notice delta mark the lchild or rchlid 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] return self.players[self.treeToArray(p//2)+delta]
l = self.initTree(2*p) l = self.initTree(2*p)
r = self.initTree(2*p+1) 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] return self.tree[p]
def winner(self): def winner(self):
idx = 1 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 idx = 2*idx if self.tree[2*idx] == self.tree[idx] else idx*2+1
num = self.treeToArray(idx) num = self.treeToArray(idx)
num = num+1 if self.players[num] !=self.tree[1] else num num = num+1 if self.players[num] != self.tree[1] else num
return self.tree[1],num return self.tree[1], num
def getOppo(self,i,x,p):
oppo=None def getOppo(self, i, x, p):
if 2*p<self.n:oppo=self.tree[2*p] oppo = None
elif i<=self.lowExt:oppo=self.players[i-1+i%2*2] if 2*p < self.n:
oppo = self.tree[2*p]
elif i <= self.lowExt:
oppo = self.players[i-1+i % 2*2]
else: else:
lpl= self.players[2*p+self.lowExt-self.n+1] 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] oppo = lpl if lpl != x else self.players[2*p+self.lowExt-self.n+2]
return oppo return oppo
def update(self,i,x):
def update(self, i, x):
''' i is 1-indexed which is the num of player ''' i is 1-indexed which is the num of player
and x is the new val of the player ''' and x is the new val of the player '''
self.players[i]=x self.players[i] = x
p = self.arrayToTree(i) p = self.arrayToTree(i)
oppo =self.getOppo(i,x,p) oppo = self.getOppo(i, x, p)
self.tree[p] = x if self.win(x,oppo) else oppo self.tree[p] = x if self.win(x, oppo) else oppo
p=p//2 p = p//2
while p: while p:
l = self.tree[p*2] l = self.tree[p*2]
r = None r = None
if 2*p+1<self.n:r=self.tree[p*2+1] #notice this !!! if 2*p+1 < self.n:
else:r = self.players[2*p+self.lowExt-self.n+1] r = self.tree[p*2+1] # notice this !!!
self.tree[p] = l if self.win(l,r) else r else:
p=p//2 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) t = winnerTree(s)
print(t.players,t.tree) print(t.players, t.tree)
for i in s: for i in s:
val,idx=t.winner() val, idx = t.winner()
print(val,idx) print(val, idx)
t.update(idx,-1) t.update(idx, -1)
''' '''

View File

@ -13,123 +13,146 @@ from random import randint
from time import time from time import time
from functools import total_ordering from functools import total_ordering
@total_ordering @total_ordering
class point: class point:
def __init__(self,x,y): def __init__(self, x, y):
self.x=x self.x = x
self.y=y self.y = y
def __neg__(self): def __neg__(self):
return pont(-self.x, -self.y) return pont(-self.x, -self.y)
def __len__(self): def __len__(self):
return self.norm(2) return self.norm(2)
def __lt__(self,p):
return self.x<p.x or (self.x==p.x and self.y<p.y) def __lt__(self, p):
def __eq__(self,p): return self.x < p.x or (self.x == p.x and self.y < p.y)
return 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): def __hash__(self):
return hash((self.x,self.y)) return hash((self.x, self.y))
def __repr__(self): def __repr__(self):
return 'point({},{})'.format(self.x,self.y) return 'point({},{})'.format(self.x, self.y)
def __str__(self): def __str__(self):
return self.__repr__() 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) 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 return ((self.x-p.x)**2+(self.y-p.y)**2)**0.5
def minDistance_n2(points): def minDistance_n2(points):
n = len(points) n = len(points)
if n<=1: return 0 if n <= 1:
p,q=points[:2] return 0
p, q = points[:2]
minD = points[0].distance(points[1]) minD = points[0].distance(points[1])
for i in range(n-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]) d = points[i].distance(points[j])
if d<minD: if d < minD:
minD = d minD = d
p = points[i] p = points[i]
q= points[j] q = points[j]
return minD, p,q return minD, p, q
def findif(points, f,reverse = False):
def findif(points, f, reverse=False):
n = len(points) 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: for i in rg:
if not f(points[i]): if not f(points[i]):
return points[i+1:] if reverse else 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 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 minDistance_nlogn(n_points):
def _min(pts): def _min(pts):
n = len(pts) n = len(pts)
if n==2: return pts[0].distance(pts[1]) , pts[0],pts[1] if n == 2:
if n==3: return pts[0].distance(pts[1]), pts[0], pts[1]
if n == 3:
minD = pts[0].distance(pts[1]) minD = pts[0].distance(pts[1])
p,q = pts[0],pts[1] p, q = pts[0], pts[1]
d2 = pts[2].distance(pts[1]) d2 = pts[2].distance(pts[1])
if minD>d2: if minD > d2:
minD = d2 minD = d2
p,q = pts[1], pts[2] p, q = pts[1], pts[2]
d2 = pts[0].distance(pts[2]) d2 = pts[0].distance(pts[2])
if minD>d2: return d2, pts[0],pts[2] if minD > d2:
else : return minD, p,q return d2, pts[0], pts[2]
else:
return minD, p, q
n2 = n//2 n2 = n//2
mid = (pts[n2].x +pts[n2-1].x)/2 mid = (pts[n2].x + pts[n2-1].x)/2
s1 = pts[:n2] s1 = pts[:n2]
s2 = pts[n2:] s2 = pts[n2:]
minD ,p,q = _min(s1) minD, p, q = _min(s1)
d2, p2, q2 = _min(s2) d2, p2, q2 = _min(s2)
#print('\n\n',minD,p,q,s1) # print('\n\n',minD,p,q,s1)
#print(d2,p2,q2,s2) # print(d2,p2,q2,s2)
if minD> d2: if minD > d2:
minD,p,q = d2, p2, q2 minD, p, q = d2, p2, q2
linePoints = findif(s1,lambda pt:floatEql(pt.x,mid),reverse=True) linePoints = findif(s1, lambda pt: floatEql(pt.x, mid), reverse=True)
linePoints += findif(s2,lambda pt:floatEql(pt.x,mid)) linePoints += findif(s2, lambda pt: floatEql(pt.x, mid))
n = len(linePoints) n = len(linePoints)
if n>1: if n > 1:
for i in range(1,n): for i in range(1, n):
dis = linePoints[i].y -linePoints[i-1].y dis = linePoints[i].y - linePoints[i-1].y
if dis<minD: if dis < minD:
minD = dis minD = dis
p,q = linePoints[i-1], linePoints[i] p, q = linePoints[i-1], linePoints[i]
leftPoints = findif(s1,lambda pt:pt.x>= mid-minD,reverse=True) leftPoints = findif(s1, lambda pt: pt.x >= mid-minD, reverse=True)
rightPoints = findif(s2,lambda pt:pt.x<= mid+minD) rightPoints = findif(s2, lambda pt: pt.x <= mid+minD)
for lp in leftPoints: for lp in leftPoints:
y1,y2 = lp.y-minD, lp.y+minD y1, y2 = lp.y-minD, lp.y+minD
for rp in rightPoints: for rp in rightPoints:
if y1< rp.y <y2: if y1 < rp.y < y2:
dis = lp.distance(rp) dis = lp.distance(rp)
if dis< minD: if dis < minD:
minD = dis minD = dis
p,q = lp,rp p, q = lp, rp
return minD, p,q return minD, p, q
return _min(sorted(n_points)) return _min(sorted(n_points))
def test(f=minDistance_n2): def test(f=minDistance_n2):
print('\ntest : ', f.__name__) print('\ntest : ', f.__name__)
begin = time() begin = time()
minD, p, q = f(points) minD, p, q = f(points)
print('time : {:.6f} s'.format(time()-begin)) 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 upper = 1000000
if unique: if unique:
points = set() points = set()
for i in range(n): 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) 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 n = 1000
points = genData(n, unique=True) points = genData(n, unique=True)
print('min distance of {} points'.format(n)) print('min distance of {} points'.format(n))
#print(sorted(points)) # print(sorted(points))
test(minDistance_n2) test(minDistance_n2)
test(minDistance_nlogn) test(minDistance_nlogn)

View File

@ -21,12 +21,13 @@ leetcode 1049: https://leetcode-cn.com/problems/last-stone-weight-ii/
####################################################################### #######################################################################
''' '''
class Solution: class Solution:
def lastStoneWeightII(self, stones: List[int]) -> int: def lastStoneWeightII(self, stones: List[int]) -> int:
sm = sum(stones) sm = sum(stones)
ans = sm//2 ans = sm//2
dp = [0]*(ans+1) dp = [0]*(ans+1)
for x in stones: for x in stones:
for j in range(ans,x-1,-1): for j in range(ans, x-1, -1):
dp[j] = max(dp[j],dp[j-x]+x) dp[j] = max(dp[j], dp[j-x]+x)
return sm-2*dp[ans] return sm-2*dp[ans]

View File

@ -10,41 +10,44 @@
######################################################################### #########################################################################
''' '''
def lcs(a,b):
def lcs(a, b):
'''time: O(mn); space: O(mn)''' '''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)] board = [[[] for i in range(n+1)] for i in range(m+1)]
for i in range(m): for i in range(m):
for j in range(n): for j in range(n):
if a[i]==b[j]: if a[i] == b[j]:
board[i+1][j+1] =board[i][j]+[a[i]] board[i+1][j+1] = board[i][j]+[a[i]]
elif len(board[i][j+1]) < len(board[i+1][j]): elif len(board[i][j+1]) < len(board[i+1][j]):
board[i+1][j+1] = board[i+1][j] board[i+1][j+1] = board[i+1][j]
else : else:
board[i+1][j+1] = board[i][1+j] board[i+1][j+1] = board[i][1+j]
return board[m][n] return board[m][n]
def lcs2(a,b):
def lcs2(a, b):
'''time: O(mn); space: O(m)''' '''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)] board = [[] for i in range(n+1)]
for i in range(m): for i in range(m):
upperLevel = board[0].copy() upperLevel = board[0].copy()
for j in range(n): for j in range(n):
tmp = board[j+1].copy() tmp = board[j+1].copy()
if a[i]==b[j]: if a[i] == b[j]:
board[j+1] = upperLevel+[a[i]] board[j+1] = upperLevel+[a[i]]
elif len(board[j+1]) < len(board[j]): 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 upperLevel = tmp
return board[n] return board[n]
if __name__ =='__main__':
if __name__ == '__main__':
a = 'ABCBDAB' a = 'ABCBDAB'
b = 'BDCABA' b = 'BDCABA'
print('s1:',a) print('s1:', a)
print('s2:',b) print('s2:', b)
while 1: while 1:
print('lcs:',lcs2(a,b)) print('lcs:', lcs2(a, b))
a = input('s1: ') a = input('s1: ')
b = input('s2: ') b = input('s2: ')

View File

@ -11,11 +11,13 @@
给两个整数数组 A B 返回两个数组中公共的长度最长的子数组的长度 给两个整数数组 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)] dp = [[0]*(m+1) for i in range(n+1)]
for i in range(1,n+1): for i in range(1, n+1):
for j in range(1,m+1): for j in range(1, m+1):
if A[i-1]==B[j-1]: if A[i-1] == B[j-1]:
dp[i][j]=dp[i-1][j-1]+1 dp[i][j] = dp[i-1][j-1]+1
return max(max(row) for row in dp) return max(max(row) for row in dp)

View File

@ -16,33 +16,36 @@
then find the maximum price to split the stripe in different shorter stripes then find the maximum price to split the stripe in different shorter stripes
( including the original length if possible) ( including the original length if possible)
''' '''
def count(n,prices):
def best(cur): def count(n, prices):
def best(cur):
# note that copying the list or create a new list in the following new_stripes codes # 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 maxPrice = 0
new_stripes=[] new_stripes = []
for i,j in prices.items(): for i, j in prices.items():
if i<=cur: if i <= cur:
p, tmp = best(cur-i) p, tmp = best(cur-i)
if maxPrice<p+j: if maxPrice < p+j:
new_stripes = tmp+[i] # if the list is not copyed, create a new list, don't use append # if the list is not copyed, create a new list, don't use append
maxPrice =p+j new_stripes = tmp+[i]
maxPrice = p+j
values[cur] = maxPrice values[cur] = maxPrice
stripes[cur] = new_stripes stripes[cur] = new_stripes
return maxPrice,new_stripes return maxPrice, new_stripes
values = {0:0} values = {0: 0}
stripes = {0:[]} stripes = {0: []}
return best(n) return best(n)
if __name__ == '__main__':
if __name__=='__main__': li = [(1, 1), (2, 5), (3, 8), (4, 9), (5, 10),
li = [(1,1),(2,5),(3,8),(4,9),(5,10),(6,17),(7,17),(8,20),(9,24),(10,30)] (6, 17), (7, 17), (8, 20), (9, 24), (10, 30)]
prices = {i:j for i,j in li} prices = {i: j for i, j in li}
n = 40 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): for i in range(n+1):
print(i,d[i]) print(i, d[i])

View File

@ -1,4 +1,4 @@
#coding: utf-8 # coding: utf-8
''' mbinary ''' mbinary
####################################################################### #######################################################################
# File : stoneGame.py # File : stoneGame.py
@ -14,6 +14,8 @@
leetcode-cn 877: https://leetcode-cn.com/problems/stone-game/ leetcode-cn 877: https://leetcode-cn.com/problems/stone-game/
####################################################################### #######################################################################
''' '''
def stoneGame(li): def stoneGame(li):
'''li: list, len(li)%2==0, sum(li)%2==1''' '''li: list, len(li)%2==0, sum(li)%2==1'''
def f(p,q): 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)) n2 = li[q] + min(-li[p]+f(p+1,q-1),-li[q-1]+f(p,q-2))
ret = max(n1,n2) ret = max(n1,n2)
dp[p][q] = ret dp[p][q] = ret
#print(li[p:q+1],ret) # print(li[p:q+1],ret)
return ret return ret
n = len(li) n = len(li)
dp = [[None for i in range(n)] for i in range(n)] dp = [[None for i in range(n)] for i in range(n)]

View File

@ -9,18 +9,23 @@
# Description: # Description:
######################################################################### #########################################################################
*/ */
class Solution { class Solution
{
public: public:
map<Node*,Node*> st; map<Node*, Node*> st;
Node *cloneGraph(Node *node){ Node *cloneGraph(Node *node)
Node* ret = new Node(node->val,vector<Node*>()); {
st[node]=ret; Node* ret = new Node(node->val, vector<Node*>());
for(auto x:node->neighbors){ st[node] = ret;
for (auto x : node->neighbors) {
auto p = st.find(x); auto p = st.find(x);
if(p==st.end()){
if (p == st.end()) {
ret->neighbors.push_back(cloneGraph(x)); ret->neighbors.push_back(cloneGraph(x));
}else ret->neighbors.push_back(p->second); } else ret->neighbors.push_back(p->second);
} }
return ret; return ret;
} }
}; };

View File

@ -20,36 +20,37 @@
####################################################################### #######################################################################
''' '''
class Solution: class Solution:
def longestStrChain(self, words: List[str]) -> int: def longestStrChain(self, words: List[str]) -> int:
def isAdj(s1,s2): def isAdj(s1, s2):
if len(s1)>len(s2): if len(s1) > len(s2):
s1,s2 = s2,s1 s1, s2 = s2, s1
n1,n2 = len(s1),len(s2) n1, n2 = len(s1), len(s2)
if n2-n1!=1: if n2-n1 != 1:
return False return False
i=j=0 i = j = 0
flag = False flag = False
while i<n1 and j<n2: while i < n1 and j < n2:
if s1[i]!=s2[j]: if s1[i] != s2[j]:
if flag: if flag:
return False return False
flag = True flag = True
j+=1 j += 1
else: else:
i+=1 i += 1
j+=1 j += 1
return True return True
def dfs(begin): def dfs(begin):
ans = 1 ans = 1
w = words[begin] w = words[begin]
n = len(w) n = len(w)
if n+1 in lenDic: if n+1 in lenDic:
for nd in lenDic[n+1]: for nd in lenDic[n+1]:
#print(w,words[nd],isAdj(w,words[nd])) # print(w,words[nd],isAdj(w,words[nd]))
if isAdj(w,words[nd]): if isAdj(w, words[nd]):
ans = max(ans,1+dfs(nd)) ans = max(ans, 1+dfs(nd))
return ans return ans
lenDic = {} lenDic = {}
for i in range(len(words)): for i in range(len(words)):
@ -57,14 +58,13 @@ class Solution:
if n in lenDic: if n in lenDic:
lenDic[n].add(i) lenDic[n].add(i)
else: else:
lenDic[n]={i} lenDic[n] = {i}
lens = sorted(lenDic) lens = sorted(lenDic)
n = len(lens) n = len(lens)
ans = 0 ans = 0
for i in range(n): for i in range(n):
if ans < n-i: if ans < n-i:
for nd in lenDic[lens[i]]: for nd in lenDic[lens[i]]:
ans = max(ans,dfs(nd)) ans = max(ans, dfs(nd))
return ans return ans

View File

@ -21,10 +21,13 @@ def isBipartite(self, graph):
""" """
n = len(graph) n = len(graph)
self.node = graph self.node = graph
self.color = {i:None for i in range(n)} 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) return all(self.dfs(i, True) for i in range(n) if self.color[i] is None)
def dfs(self,n,col=True):
def dfs(self, n, col=True):
if self.color[n] is None: if self.color[n] is None:
self.color[n]=col self.color[n] = col
return all(self.dfs(i,not col) for i in self.node[n]) return all(self.dfs(i, not col) for i in self.node[n])
else:return col==self.color[n] else:
return col == self.color[n]

View File

@ -54,7 +54,7 @@ def _fft2(a, invert=False):
N = len(a) N = len(a)
if N & (N - 1) == 0: # O(nlogn), 2^k if N & (N - 1) == 0: # O(nlogn), 2^k
r = int(np.log(N)) r = int(np.log(N))
c = np.array(a,dtype='complex') c = np.array(a, dtype='complex')
i = 2j if invert else -2j i = 2j if invert else -2j
w = np.exp(i * np.pi / N) w = np.exp(i * np.pi / N)
for h in range(r - 1, -1, -1): for h in range(r - 1, -1, -1):

View File

@ -11,21 +11,23 @@
####################################################################### #######################################################################
''' '''
def fastPow(a,n):
def fastPow(a, n):
'''a^n''' '''a^n'''
rst = 1 rst = 1
while n: while n:
if n%2: if n % 2:
rst *=a rst *= a
n>>=1 n >>= 1
a*=a a *= a
return rst return rst
def fastMul(a,b):
def fastMul(a, b):
'''a*b''' '''a*b'''
rst = 0 rst = 0
while b: while b:
if b&1: if b & 1:
rst +=a rst += a
b>>=1 b >>= 1
a*=2 a *= 2

View File

@ -11,27 +11,31 @@
####################################################################### #######################################################################
''' '''
def fib(n): def fib(n):
"""Calculates the nth Fibonacci number""" """Calculates the nth Fibonacci number"""
mat,p = (1,1,1,0),n-2 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 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 mat = (0, 1, 1, -1), 2-n
li = matrix_pow((0,1,1,-1),1-n) li = matrix_pow((0, 1, 1, -1), 1-n)
return li[0]+li[1] return li[0]+li[1]
def matrix_pow(mat,n):
ans = (1,0,0,1) # element matrix
while n>0: def matrix_pow(mat, n):
if n%2==1: ans = (1, 0, 0, 1) # element matrix
ans = matrix_mul(ans,mat) while n > 0:
n>>=1 if n % 2 == 1:
mat = matrix_mul(mat,mat) ans = matrix_mul(ans, mat)
n >>= 1
mat = matrix_mul(mat, mat)
return ans 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]]]''' '''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__': if __name__ == '__main__':
for i in range(-5,5): for i in range(-5, 5):
print(i,fib(i)) print(i, fib(i))

View File

@ -23,6 +23,7 @@ eg
''' '''
from nega import nega from nega import nega
def addNegaBin(arr1: list, arr2: list) -> list: def addNegaBin(arr1: list, arr2: list) -> list:
if len(arr1) < len(arr2): if len(arr1) < len(arr2):
arr1, arr2 = arr2, arr1 arr1, arr2 = arr2, arr1
@ -42,19 +43,20 @@ def addNegaBin(arr1: list, arr2: list) -> list:
elif arr1[i] == 0 and arr2[i] == 1: elif arr1[i] == 0 and arr2[i] == 1:
arr1[i] = arr2[i] arr1[i] = arr2[i]
#print(arr1,arr2,i) # print(arr1,arr2,i)
while len(arr1) > 1 and arr1[0] == 0: while len(arr1) > 1 and arr1[0] == 0:
arr1.pop(0) arr1.pop(0)
return arr1 return arr1
if __name__=='__main__':
if __name__ == '__main__':
while 1: while 1:
print("input q to quit or input x1 x2: ") print("input q to quit or input x1 x2: ")
s = input() s = input()
if s=='q': if s == 'q':
break break
n1,n2 =[int(i) for i in s.split()] n1, n2 = [int(i) for i in s.split()]
l1,l2 = nega(n1),nega(n2) l1, l2 = nega(n1), nega(n2)
print(n1,l1) print(n1, l1)
print(n2,l2) print(n2, l2)
print(f'{n1}+{n2}={n1+n2}: {addNegaBin(l1,l2)}') print(f'{n1}+{n2}={n1+n2}: {addNegaBin(l1,l2)}')

View File

@ -10,34 +10,37 @@
######################################################################### #########################################################################
''' '''
def covert(s,basefrom=10,baseto=2):
return d2n(n2d(s,basefrom),baseto) def covert(s, basefrom=10, baseto=2):
def n2d(s,base=16): return d2n(n2d(s, basefrom), baseto)
def n2d(s, base=16):
''' num of base_n(n<36) to decimal''' ''' num of base_n(n<36) to decimal'''
dic = {chr(i+ord('0')):i for i in range(10)} dic = {chr(i+ord('0')): i for i in range(10)}
s=s.upper() s = s.upper()
if base>10: if base > 10:
dic.update({chr(i+ord('A')):i+10 for i in range(26)}) dic.update({chr(i+ord('A')): i+10 for i in range(26)})
#if base in [16,8,2] : # if base in [16,8,2] :
# p=max(map(s.find,'OBX')) # p=max(map(s.find,'OBX'))
# s=s[p+1:] #remove prefix of hex or bin or oct # s=s[p+1:] #remove prefix of hex or bin or oct
rst=0 rst = 0
for i in s: for i in s:
rst=dic[i]+rst*base rst = dic[i]+rst*base
return rst 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])
''' '''

View File

@ -9,15 +9,18 @@
# Description: # 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''' '''return list of num, the first is the highest digit'''
if base>-2: if base > -2:
raise Exception(f"[Error]: invalid base: {base}, base should be no more than -2") raise Exception(
f"[Error]: invalid base: {base}, base should be no more than -2")
ans = [] ans = []
while n: while n:
k = n%base k = n % base
if k<0: if k < 0:
k-=base k -= base
ans.append(k) ans.append(k)
n = (n-k)//base n = (n-k)//base
return ans[::-1] return ans[::-1]

View File

@ -17,17 +17,20 @@ from factor import factor
from collections import Counter from collections import Counter
from functools import reduce from functools import reduce
from operator import mul from operator import mul
def phi(n): def phi(n):
st = set(factor(n)) st = set(factor(n))
return round(reduce(mul,(1-1/p for p in st),n)) return round(reduce(mul, (1-1/p for p in st), n))
def sigma(n): def sigma(n):
ct = Counter(factor(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: while 1:
n = int(input('n: ')) n = int(input('n: '))
print('phi(n):',phi(n)) print('phi(n):', phi(n))
print('sigma(n):',sigma(n)) print('sigma(n):', sigma(n))

View File

@ -13,41 +13,49 @@
from random import randint from random import randint
from isPrime import isPrime from isPrime import isPrime
from gcd import gcd from gcd import gcd
def factor(n): def factor(n):
'''pollard's rho algorithm''' '''pollard's rho algorithm'''
if n<1:raise Exception('[Error]: {} is less than 1'.format(n)) if n < 1:
if n==1: return [] raise Exception('[Error]: {} is less than 1'.format(n))
if isPrime(n):return [n] if n == 1:
fact=1 return []
cycle_size=2 if isPrime(n):
return [n]
fact = 1
cycle_size = 2
x = x_fixed = 2 x = x_fixed = 2
c = randint(1,n) c = randint(1, n)
while fact==1: while fact == 1:
for i in range(cycle_size): for i in range(cycle_size):
if fact>1:break if fact > 1:
x=(x*x+c)%n break
if x==x_fixed: x = (x*x+c) % n
c = randint(1,n) if x == x_fixed:
c = randint(1, n)
continue continue
fact = gcd(x-x_fixed,n) fact = gcd(x-x_fixed, n)
cycle_size *=2 cycle_size *= 2
x_fixed = x x_fixed = x
return factor(fact)+factor(n//fact) return factor(fact)+factor(n//fact)
def fact(n): def fact(n):
f=2 f = 2
ret = [] ret = []
while f*f<=n: while f*f <= n:
while not n%f: while not n % f:
ret.append(f) ret.append(f)
n//f n//f
f+=1 f += 1
if n>1:ret.append(n) if n > 1:
ret.append(n)
return ret return ret
if __name__=='__main__': if __name__ == '__main__':
while 1: while 1:
n = int(input('n: ')) n = int(input('n: '))
print(factor(n)) print(factor(n))

View File

@ -11,23 +11,28 @@
####################################################################### #######################################################################
''' '''
def gcd(a,b):
while b!=0: def gcd(a, b):
a,b=b,a%b while b != 0:
a, b = b, a % b
return a 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: while 1:
a = int(input('a: ')) a = int(input('a: '))
b = int(input('b: ')) b = int(input('b: '))
print('gcd :',gcd(a,b)) print('gcd :', gcd(a, b))
print('xgcd:',xgcd(a,b)) print('xgcd:', xgcd(a, b))

View File

@ -13,48 +13,51 @@
####################################################################### #######################################################################
''' '''
def hammingDistance(a,b):
if isinstance(a,int): def hammingDistance(a, b):
n = a^b if isinstance(a, int):
n = a ^ b
ct = 0 ct = 0
while n: while n:
ct+=n%2 ct += n % 2
n>>=1 n >>= 1
return ct return ct
else: else:
n,m = len(a),len(b) n, m = len(a), len(b)
ret = 0 ret = 0
for i,j in zip(a,b): for i, j in zip(a, b):
ret+= i==j ret += i == j
return ret+abs(n-m) return ret+abs(n-m)
def totalHammingDistance(lst): def totalHammingDistance(lst):
'''return sum of any two items(num or lst( str)) in lst''' '''return sum of any two items(num or lst( str)) in lst'''
length = len(lst) length = len(lst)
if length ==0:return 0 if length == 0:
if isinstance(lst[0],int): return 0
if isinstance(lst[0], int):
bits = [0] * len(bin(max(lst))) bits = [0] * len(bin(max(lst)))
for n in lst: for n in lst:
ct = 0 ct = 0
while n: while n:
if n%2==1: if n % 2 == 1:
bits[ct]+=1 bits[ct] += 1
ct+=1 ct += 1
n>>=1 n >>= 1
return sum(i*(length-i) for i in bits) return sum(i*(length-i) for i in bits)
else: else:
mx = len(max(lst,key=len)) mx = len(max(lst, key=len))
position = [dict() for i in range(mx)] position = [dict() for i in range(mx)]
for li in lst: for li in lst:
for i,x in enumerate(li): for i, x in enumerate(li):
if x in position[i]: if x in position[i]:
position[i][x] +=1 position[i][x] += 1
else: else:
position[i][x] =1 position[i][x] = 1
ret = 0 ret = 0
for dic in position: for dic in position:
left = length left = length
for i in dic.values(): for i in dic.values():
ret+=i*(left-i) # key step ret += i*(left-i) # key step
left -=i # key step left -= i # key step
return ret return ret

View File

@ -12,56 +12,61 @@
from random import randint from random import randint
def quickMulMod(a,b,m): def quickMulMod(a, b, m):
'''a*b%m, quick''' '''a*b%m, quick'''
ret = 0 ret = 0
while b: while b:
if b&1: if b & 1:
ret = (a+ret)%m ret = (a+ret) % m
b//=2 b //= 2
a = (a+a)%m a = (a+a) % m
return ret return ret
def quickPowMod(a,b,m):
def quickPowMod(a, b, m):
'''a^b %m, quick, O(logn)''' '''a^b %m, quick, O(logn)'''
ret =1 ret = 1
while b: while b:
if b&1: if b & 1:
ret =quickMulMod(ret,a,m) ret = quickMulMod(ret, a, m)
b//=2 b //= 2
a = quickMulMod(a,a,m) a = quickMulMod(a, a, m)
return ret return ret
def isPrime(n,t=5): def isPrime(n, t=5):
'''miller rabin primality test, a probability result '''miller rabin primality test, a probability result
t is the number of iteration(witness) t is the number of iteration(witness)
''' '''
t = min(n-3,t) t = min(n-3, t)
if n<2: if n < 2:
print('[Error]: {} can\'t be classed with prime or composite'.format(n)) print('[Error]: {} can\'t be classed with prime or composite'.format(n))
return return
if n==2: return True if n == 2:
return True
d = n-1 d = n-1
r = 0 r = 0
while d%2==0: while d % 2 == 0:
r+=1 r += 1
d//=2 d //= 2
tested=set() tested = set()
for i in range(t): for i in range(t):
a = randint(2,n-2) a = randint(2, n-2)
while a in tested: while a in tested:
a = randint(2,n-2) a = randint(2, n-2)
tested.add(a) tested.add(a)
x= quickPowMod(a,d,n) x = quickPowMod(a, d, n)
if x==1 or x==n-1: continue #success, if x == 1 or x == n-1:
continue # success,
for j in range(r-1): for j in range(r-1):
x= quickMulMod(x,x,n) x = quickMulMod(x, x, n)
if x==n-1:break if x == n-1:
break
else: else:
return False return False
return True return True
''' '''
we shouldn't use Fermat's little theory we shouldn't use Fermat's little theory
Namyly: 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 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): def twoDivideFind(x, li):
a,b = 0, len(li) a, b = 0, len(li)
while a<=b: while a <= b:
mid = (a+b)//2 mid = (a+b)//2
if li[mid]<x:a=mid+1 if li[mid] < x:
elif li[mid]>x: b= mid-1 a = mid+1
else:return mid elif li[mid] > x:
b = mid-1
else:
return mid
return -1 return -1
if __name__=='__main__':
if __name__ == '__main__':
n = 100 n = 100
print('prime numbers below',n) print('prime numbers below', n)
print([i for i in range(n) if isPrime(i)]) print([i for i in range(n) if isPrime(i)])
while 1: while 1:
n = int(input('n: ')) n = int(input('n: '))

View File

@ -18,110 +18,124 @@ from euler import phi
from isPrime import isPrime from isPrime import isPrime
from factor import factor 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):
'''return list of m's primary roots below num''' ''' 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) p = phi(m)
mp = factor(p) mp = factor(p)
checkLst = [p//i for i in mp] 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): def minG(m):
p = phi(m) p = phi(m)
mp = factor(p) mp = factor(p)
checkLst = [p//i for i in mp] checkLst = [p//i for i in mp]
i=2 i = 2
while 1: while 1:
if all((i**n-1)%m !=0 for n in checkLst):return i if all((i**n-1) % m != 0 for n in checkLst):
i+=1 return i
i += 1
class solve: class solve:
def __init__(self,equ=None): def __init__(self, equ=None):
self.linearPat= re.compile(r'\s*(\d+)\s*--\s*(\d+)[\s\(]*mod\s*(\d+)') self.linearPat = re.compile(r'\s*(\d+)\s*--\s*(\d+)[\s\(]*mod\s*(\d+)')
self.sol = [] self.sol = []
#self.m = m #self.m = m
#self.ind_mp = ind(m,minG(m)) #self.ind_mp = ind(m,minG(m))
def noSol(self): def noSol(self):
print('equation {equ} has no solution'.format(equ=self.equ)) print('equation {equ} has no solution'.format(equ=self.equ))
def error(self): def error(self):
print("Error! The divisor m must be postive integer") 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 '''ax--b(mod m): solve linear equation with one unknown
return ([x1,x2,...],m) return ([x1,x2,...],m)
''' '''
a,b,m = self.check(a,b,m) a, b, m = self.check(a, b, m)
g,x,y=xgcd(a,m) g, x, y = xgcd(a, m)
if a*b%g!=0: if a*b % g != 0:
self.noSol() self.noSol()
return None return None
sol=x*b//g sol = x*b//g
m0 = m//g m0 = m//g
sols = [(sol+i*m0)%m for i in range(g)] sols = [(sol+i*m0) % m for i in range(g)]
print('{}x--{}(mod {}), solution: {} mod {}'.format(a,b,m,sols,m)) print('{}x--{}(mod {}), solution: {} mod {}'.format(a, b, m, sols, m))
return (sols,m) return (sols, m)
def check(self,a,b,m):
if m<=0: def check(self, a, b, m):
if m <= 0:
self.error() self.error()
return None return None
if a<0:a,b=-a,-b ## important if a < 0:
if b<0:b+= -b//m * m a, b = -a, -b # important
return a,b,m 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}''' ''' 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] tmp = ind_mp[b] - ind_mp[a]
if tmp < 0:tmp+=m if tmp < 0:
sol = self.solveLinear(n,tmp,phi(m)) tmp += m
re_mp = {j:i for i ,j in ind_mp.items()} 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]] sols = [re_mp[i] for i in sol[0]]
print('{}x^{}--{}(mod {}), solution: {} mod {}'.format(a,n,b,m,sols,m)) print('{}x^{}--{}(mod {}), solution: {} mod {}'.format(a, n, b, m, sols, m))
return sols,m return sols, m
def solveGroup(self,tups): def solveGroup(self, tups):
'''tups is a list of tongyu equation groups, like '''tups is a list of tongyu equation groups, like
[(a1,b1,m1),(a2,b2,m2)...] [(a1,b1,m1),(a2,b2,m2)...]
and, m1,m2... are all primes and, m1,m2... are all primes
''' '''
mp = {} mp = {}
print('solving group of equations: ') print('solving group of equations: ')
for a,b,m in tups: for a, b, m in tups:
print('{}x--{}(mod {})'.format(a,b,m)) print('{}x--{}(mod {})'.format(a, b, m))
if m in mp: if m in mp:
if mp[m][0]*b!=mp[m][1]*a: if mp[m][0]*b != mp[m][1]*a:
self.noSol() self.noSol()
return return
else:mp[m] = (a,b) else:
mp[m] = (a, b)
product = 1 product = 1
for i in mp.keys(): for i in mp.keys():
product *=i product *= i
sol = [0] sol = [0]
for i in mp: 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 = [] new = []
for x in xs: for x in xs:
cur = x*product//i*mp[i][1] cur = x*product//i*mp[i][1]
for old in sol: for old in sol:
new.append(old+cur) new.append(old+cur)
sol = new sol = new
sol= [i%product for i in sol] sol = [i % product for i in sol]
print('final solution: {} mod {}'.format(sol,product)) print('final solution: {} mod {}'.format(sol, product))
return sol,product return sol, product
def __call__(self): def __call__(self):
s=input('输入同余方程,用--代表同于号形如3--5(mod 7)代表3x模7同余于5') s = input('输入同余方程,用--代表同于号形如3--5(mod 7)代表3x模7同余于5')
li= self.linearPat.findall(s) li = self.linearPat.findall(s)
li = [(int(a),int(b),int(m)) for a,b,m in li] li = [(int(a), int(b), int(m)) for a, b, m in li]
print(self.solveLinear(li[0])) print(self.solveLinear(li[0]))
if __name__ == '__main__': if __name__ == '__main__':
solver = solve() solver = solve()
res = solver.solveLinear(3,6,9) res = solver.solveLinear(3, 6, 9)
print() print()
res = solver.solveHigh(1,8,3,11) res = solver.solveHigh(1, 8, 3, 11)
print() 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)])

View File

@ -1,3 +1,3 @@
genPrimes 2= [2] genPrimes 2= [2]
genPrimes n = let li = genPrimes $n-1 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

View File

@ -0,0 +1,56 @@
def sievePrime(n):
if n < 2:
return 0
prime = [1] * (n + 1)
prime[0] = prime[1] = 0
for i in range(2, int(n**0.5) + 1):
if prime[i] == 1:
prime[i*i:n + 1:i] = [0]*len(prime[i*i:n + 1:i])
return [i for i in range(n+1) if prime[i] == 1]
class primeSiever:
'''sieve of Eratosthenes, It will be more efficient when judging many times'''
primes = [2, 3, 5, 7, 11, 13]
def isPrime(self, x):
if x <= primes[-1]:
return twoDivideFind(x, self.primes)
while x > self.primes[-1]:
left = self.primes[-1]
right = (left+1)**2
lst = []
for i in range(left, right):
for j in self.primes:
if i % j == 0:
break
else:
lst.append(i)
self.primes += lst
return twoDivideFind(x, lst)
def nPrime(n):
'''return the n-th prime'''
i = n-len(self.primes)
last = self.primes[-1]
for _ in range(i):
while 1:
last += 2
for p in self.primes:
if last % p == 0:
break
else:
self.primes.append(last)
break
return self.primes[n-1]
if __name__ == "__main__":
import sys
if len(sys.argv) < 2:
n = 100
else:
n = int(sys.argv[1])
ans = sievePrime(n)
print(f'primes <= {n}, nums: {len(ans)}')
print(ans)

View File

@ -26,58 +26,65 @@ from collections import namedtuple
from functools import reduce from functools import reduce
from operator import mul from operator import mul
X = sympy.Symbol ('x') X = sympy.Symbol('x')
point = namedtuple('point',['x','y']) point = namedtuple('point', ['x', 'y'])
class interplotion: class interplotion:
def __init__(self,points): def __init__(self, points):
self.points = [point(x,y) for x,y in points] self.points = [point(x, y) for x, y in points]
self.xs= [i for i,j in points] self.xs = [i for i, j in points]
self.poly,self.rem = self.newton(self.points,0,len(self.points)-1) 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))...]''' '''li:[(x,f(x))...]'''
qs = [li[0].y] qs = [li[0].y]
def quoDiff(begin,end): def quoDiff(begin, end):
if begin == end:return li[begin].y if begin == end:
q = (quoDiff(begin+1,end)-quoDiff(begin,end-1))/(li[end].x-li[begin].x) return li[begin].y
if begin == a:qs.append(q) q = (quoDiff(begin+1, end)-quoDiff(begin, end-1)) / \
(li[end].x-li[begin].x)
if begin == a:
qs.append(q)
return q return q
quoDiff(a,b) quoDiff(a, b)
poly ,base = 0, 1 poly, base = 0, 1
for i,q in enumerate(qs): for i, q in enumerate(qs):
poly += q*base poly += q*base
base*= X-li[i].x base *= X-li[i].x
return poly, base*qs[-1] return poly, base*qs[-1]
def lagrange(self,points=None):
def lagrange(self, points=None):
xs = None xs = None
if points is None: if points is None:
xs = self.xs xs = self.xs
points = self.points points = self.points
else: xs =[x for x,y in points] else:
product = reduce(mul,[X-x for x in xs],1) xs = [x for x, y in points]
product = reduce(mul, [X-x for x in xs], 1)
poly = 0 poly = 0
for x,y in points: for x, y in points:
tmp = product/(X-x) tmp = product/(X-x)
coef = y/(tmp.subs(X,x)) coef = y/(tmp.subs(X, x))
poly+= coef *tmp poly += coef * tmp
return poly return poly
def predict(self,val,poly = None): def predict(self, val, poly=None):
if poly is None:poly = self.poly if poly is None:
return poly.subs(X,val) # note the func subs poly = self.poly
return poly.subs(X, val) # note the func subs
if __name__ == '__main__': if __name__ == '__main__':
f = interplotion([(81,9),(100,10),(121,11)]) f = interplotion([(81, 9), (100, 10), (121, 11)])
p = f.lagrange() p = f.lagrange()
print(p.subs(X,105)) print(p.subs(X, 105))
print(p) 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() p = intor.lagrange()
print(p) print(p)
res = intor.predict(0.08) res = intor.predict(0.08)

View File

@ -15,94 +15,98 @@ import numpy as np
from math import sqrt 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 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 y is the func, x0 is the init x val: int float epsilon is the accurrency
''' '''
if epsilon <0:epsilon = -epsilon if epsilon < 0:
ct =0 epsilon = -epsilon
t = y.free_symbols ct = 0
varsymbol = 'x' if len(t)==0 else t.pop() t = y.free_symbols
x0= float(x0) varsymbol = 'x' if len(t) == 0 else t.pop()
x0 = float(x0)
y_diff = y.diff() y_diff = y.diff()
li = [x0] li = [x0]
vals = [] vals = []
while 1: while 1:
val = y.subs(varsymbol,x0) val = y.subs(varsymbol, x0)
vals.append(val) vals.append(val)
x = x0- val/y_diff.subs(varsymbol,x0) x = x0 - val/y_diff.subs(varsymbol, x0)
li.append(x) li.append(x)
ct+=1 ct += 1
if ct>maxtime: if ct > maxtime:
print("after iteration for {} times, I still havn't reach the accurrency.\ print("after iteration for {} times, I still havn't reach the accurrency.\
Maybe this function havsn't zeropoint\n".format(ct)) Maybe this function havsn't zeropoint\n".format(ct))
return li ,val return li, val
if abs(x-x0)<epsilon:return li,vals if abs(x-x0) < epsilon:
return li, vals
x0 = x 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) 弦截法, 使用newton 差商计算,每次只需计算一次f(x)
secant method for finding a zeropoint of a func secant method for finding a zeropoint of a func
y is the func , x0 is the init x val, epsilon is the accurrency y is the func , x0 is the init x val, epsilon is the accurrency
''' '''
if epsilon <0:epsilon = -epsilon if epsilon < 0:
ct =0 epsilon = -epsilon
x0,x1 = float(x0),float(x1) ct = 0
li = [x0,x1] x0, x1 = float(x0), float(x1)
t = y.free_symbols li = [x0, x1]
varsymbol = 'x' if len(t)==0 else t.pop() t = y.free_symbols
last = y.subs(varsymbol,x0) varsymbol = 'x' if len(t) == 0 else t.pop()
last = y.subs(varsymbol, x0)
vals = [last] vals = [last]
while 1: while 1:
cur = y.subs(varsymbol,x1) cur = y.subs(varsymbol, x1)
vals.append(cur) vals.append(cur)
x = x1-cur*(x1-x0)/(cur-last) x = x1-cur*(x1-x0)/(cur-last)
x0 ,x1= x1,x x0, x1 = x1, x
last = cur last = cur
li.append(x) li.append(x)
ct+=1 ct += 1
if ct>maxtime: if ct > maxtime:
print("after iteration for {} times, I still havn't reach the accurrency.\ print("after iteration for {} times, I still havn't reach the accurrency.\
Maybe this function havsn't zeropoint\n".format(ct)) Maybe this function havsn't zeropoint\n".format(ct))
return li,vals return li, vals
if abs(x0-x1)<epsilon:return li,vals if abs(x0-x1) < epsilon:
return li, vals
x0 = x 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:''' '''solve nonlinear equations:'''
li = list(init_dic.keys()) li = list(init_dic.keys())
delta = {i:0 for i in li} delta = {i: 0 for i in li}
ct = 0 ct = 0
while 1: while 1:
ys = np.array([f.subs(init_dic) for f in funcs],dtype = 'float') 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') mat = np.matrix([[i.diff(x).subs(init_dic) for x in li]
delt = np.linalg.solve(mat,-ys) for i in funcs], dtype='float')
for i,j in enumerate(delt): delt = np.linalg.solve(mat, -ys)
init_dic[li[i]] +=j for i, j in enumerate(delt):
init_dic[li[i]] += j
delta[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.\ print("after iteration for {} times, I still havn't reach the accurrency.\
Maybe this function havsn't zeropoint\n".format(ct)) Maybe this function havsn't zeropoint\n".format(ct))
return init_dic 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__': if __name__ == '__main__':
x,y,z = sympy.symbols('x y z') 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) res, res2 = secant(x**3-3*x-2, 1, 3, 1e-3)
print(res,res2) print(res, res2)
funcs = [x**2+y**2-1, x**3-y]
funcs=[x**2+y**2-1,x**3-y] init = {x: 0.8, y: 0.6}
init = {x:0.8,y:0.6} res_dic = solveNonlinearEquations(funcs, init, 0.001)
res_dic = solveNonlinearEquations(funcs,init,0.001)
print(res_dic) print(res_dic)

View File

@ -20,12 +20,11 @@
************************************************************************''' ************************************************************************'''
import re import re
import numpy as np import numpy as np
def solveConflitEqualtion(A, y):
def solveConflitEqualtion(A,y):
'''solve equation like this: Av = y, '''solve equation like this: Av = y,
A:m*n v:n*1 y:m*1 A:m*n v:n*1 y:m*1
return vector v return vector v
@ -35,43 +34,49 @@ def solveConflitEqualtion(A,y):
ata = A.T*A ata = A.T*A
print('AtA') print('AtA')
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] y = [[i[1]] for i in point]
x = [[i[0]] for i in point] x = [[i[0]] for i in point]
A = [] A = []
for i in x: for i in x:
A.append([i[0]**j for j in index]) A.append([i[0]**j for j in index])
res = solveConflitEqualtion(A,y) res = solveConflitEqualtion(A, y)
print('the solution is : \n',res) print('the solution is : \n', res)
print('namely: ') print('namely: ')
items = ['{:.4f}x^{}'.format(res[i,0],j) for i, j in enumerate(index)] items = ['{:.4f}x^{}'.format(res[i, 0], j) for i, j in enumerate(index)]
print('phi(x) = ',' + '.join(items)) 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+') # numPt = re.compile (r'\d*\.{0,1}\d+')
if not s: s = input('input matrix A:m*n //m>=n\n') if not s:
s = s.replace(' ','') s = input('input matrix A:m*n //m>=n\n')
li = re.findall(r'(\[(\d+)(,(\d+))+\])',s) s = s.replace(' ', '')
li = [parseLst(i[0]) for i in li] li = re.findall(r'(\[(\d+)(,(\d+))+\])', s)
if not y:y = input('input a vector y:n*1\n') li = [parseLst(i[0]) for i in li]
if not y:
y = input('input a vector y:n*1\n')
y = parseLst(y) y = parseLst(y)
print('Equation: Av = y:') print('Equation: Av = y:')
print('y is as follows: ') print('y is as follows: ')
print(y) print(y)
print('A is as follows: ') print('A is as follows: ')
for i in li: for i in li:
for j in i: for j in i:
print('{}'.format(j).rjust(5),end='') print('{}'.format(j).rjust(5), end='')
print('') print('')
print('result v is as follows: ') print('result v is as follows: ')
res = solveConflitEqualtion(li,y) res = solveConflitEqualtion(li, y)
print(res) print(res)
def parseLst(s): def parseLst(s):
s = s.strip('[]') s = s.strip('[]')
li = s.split(',') li = s.split(',')
li = [float(j) for j in li] li = [float(j) for j in li]
return li return li
@ -86,19 +91,19 @@ if __name__ == '__main__':
s = input('input y to continue, n for exit') s = input('input y to continue, n for exit')
if s!='y':break if s!='y':break
''' '''
point = [(-3,14.3),(-2,8.3),(-1,4.7),(2,-8.3),(4,-22.7)] point = [(-3, 14.3), (-2, 8.3), (-1, 4.7), (2, -8.3), (4, -22.7)]
lst = [0,3] lst = [0, 3]
solveLinear(point,lst) solveLinear(point, lst)
point = [(-3, 14.3), (-2, 8.3), (-1, 4.7), (2, 8.3), (4, 22.7)]
lst = [0, 2]
solveLinear(point, lst)
A = [[1, 2], [2, 1], [1, 1]]
y = [[5], [6], [4]]
res = solveConflitEqualtion(A, y)
point= [(-3,14.3),(-2,8.3),(-1,4.7),(2,8.3),(4,22.7)]
lst = [0,2]
solveLinear(point,lst)
A = [[1,2],[2,1],[1,1]]
y = [[5],[6],[4]]
res = solveConflitEqualtion(A,y)
print(res) print(res)
A = [[1,-2],[1,5],[2,1],[1,1]] A = [[1, -2], [1, 5], [2, 1], [1, 1]]
y = [[1],[13.1],[7.9],[5.1]] y = [[1], [13.1], [7.9], [5.1]]
print(solveConflitEqualtion(A,y)) print(solveConflitEqualtion(A, y))

View File

@ -19,86 +19,105 @@
> Created Time: 2018-04-20 08:32 > Created Time: 2018-04-20 08:32
************************************************************************''' ************************************************************************'''
import numpy as np import numpy as np
def getLU(A): def getLU(A):
'''doolittle : A = LU, '''doolittle : A = LU,
L is in down-triangle form, L is in down-triangle form,
U is in up-triangle form U is in up-triangle form
''' '''
m,n = A.shape m, n = A.shape
if m!=n:raise Exception("this matrix is not inversable") if m != n:
raise Exception("this matrix is not inversable")
L = np.zeros([m,m]) L = np.zeros([m, m])
U = np.zeros([m,m]) U = np.zeros([m, m])
L = np.matrix(L) L = np.matrix(L)
U = np. matrix(U) U = np. matrix(U)
U[0] = A[0] U[0] = A[0]
L[:,0] = A[:,0] / A[0,0] L[:, 0] = A[:, 0] / A[0, 0]
for i in range(1,m): for i in range(1, m):
for j in range(i,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)) 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[j, i] = (A[j, i] - sum(L[j, k]*U[k, i]
for k in range(i)))/U[i, i]
print(L) print(L)
print(U) print(U)
return L,U return L, U
def gauss_prior_elimination(A): def gauss_prior_elimination(A):
'''using guass elimination,get up_trianglge form of A''' '''using guass elimination,get up_trianglge form of A'''
m,n = A.shape m, n = A.shape
if m!=n:raise Exception("[Error]: matrix is not inversable") if m != n:
B = np.matrix(A,dtype=float) # necessary,otherwise when the dtype of A is int, then it will be wrong raise Exception("[Error]: matrix is not inversable")
for i in range(m-1): # necessary,otherwise when the dtype of A is int, then it will be wrong
col = abs(B[i:,i]) # note using abs value, return a matrix in (m-i)x1 form 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() 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() pos = i+col.argmax()
if pos != i : B[[pos,i],:] = B[[i,pos],:] # note how to swap cols/rows if pos != i:
B[i,:] = 1/mx*B[i,:] B[[pos, i], :] = B[[i, pos], :] # note how to swap cols/rows
for j in range(i+1,m): B[i, :] = 1/mx*B[i, :]
#print(B) for j in range(i+1, m):
B[j,:] -= B[j,i] * B[i,:] # print(B)
B[j, :] -= B[j, i] * B[i, :]
print(B) print(B)
return B return B
def solveDown(A,b):
def solveDown(A, b):
'''A is a matrix in down-triangle form''' '''A is a matrix in down-triangle form'''
sol = np.zeros(b.shape) sol = np.zeros(b.shape)
for i in range(b.shape[0]): 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 return sol
def solveUp(A,b):
def solveUp(A, b):
'''A is a matrix in up-triangle form''' '''A is a matrix in up-triangle form'''
sol = np.zeros(b.shape) sol = np.zeros(b.shape)
n = b.shape[0] n = b.shape[0]
for i in range(n-1,-1,-1): 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] 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 return sol
def doolittle(A,b):
L,U = getLU(A)
y = solveDown(L,b) def doolittle(A, b):
x = solveUp(U,y) L, U = getLU(A)
y = solveDown(L, b)
x = solveUp(U, y)
print(y) print(y)
print(x) print(x)
return 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)) D = np.diag(np.diag(U))
print(D,"D") print(D, "D")
z = np.linalg.solve(L,b) z = np.linalg.solve(L, b)
print(z,"z") print(z, "z")
y = np.linalg.solve(D,z) y = np.linalg.solve(D, z)
print(y,"y") print(y, "y")
x = np.linalg.solve(L.T,y) x = np.linalg.solve(L.T, y)
print(x,"x") print(x, "x")
return x return x
if __name__ == '__main__': if __name__ == '__main__':
A = np.matrix([[10,5,0,0], A = np.matrix([[10, 5, 0, 0],
[2,2,1,0], [2, 2, 1, 0],
[0,10,0,5], [0, 10, 0, 5],
[0,0,2,1]]) [0, 0, 2, 1]])
b = np.matrix([[5],[3],[27],[6]]) b = np.matrix([[5], [3], [27], [6]])
gauss_prior_elimination(A) gauss_prior_elimination(A)
'''ldlt '''ldlt
@ -115,4 +134,3 @@ if __name__ == '__main__':
b = np.matrix([[4],[6],[5]]) b = np.matrix([[4],[6],[5]])
doolittle(A,b) doolittle(A,b)
''' '''

View File

@ -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:
#########################################################################
'''

View File

@ -18,53 +18,56 @@
# Blog: https://mbinary.xyz # Blog: https://mbinary.xyz
# Github: https://github.com/mbinary # Github: https://github.com/mbinary
# Created Time: 2018-05-11 08:58 # Created Time: 2018-05-11 08:58
# Description: # Description:
# numerical intergration: using Newton-Cotes integration, and Simpson # numerical intergration: using Newton-Cotes integration, and Simpson
# 数值积分, 使用 牛顿-科特斯积分, 辛普森 # 数值积分, 使用 牛顿-科特斯积分, 辛普森
######################################################################### #########################################################################
import numpy as np 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) print(xs)
ret = h*(sum(fs)-fs[0]/2 - fs[-1]/2) ret = h*(sum(fs)-fs[0]/2 - fs[-1]/2)
print(ret) print(ret)
return 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) 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) print(ret)
return ret return ret
def romberg(a,b,f,epcilon): def romberg(a, b, f, epcilon):
'''romberg(龙贝格) 数值积分''' '''romberg(龙贝格) 数值积分'''
h = b-a h = b-a
lst1=[h*(f(a)+f(b))/2] lst1 = [h*(f(a)+f(b))/2]
print(lst1) print(lst1)
delta = epcilon delta = epcilon
k=1 k = 1
while delta >= epcilon: while delta >= epcilon:
h/=2 h /= 2
k+=1 k += 1
lst2=[] lst2 = []
lst2.append((lst1[0]+h*2*sum(f(a+(2*i-1)*h) for i in range(1,2**(k-2)+1)))/2) lst2.append((lst1[0]+h*2*sum(f(a+(2*i-1)*h)
for j in range(0,k-1): 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)) lst2.append(lst2[j]+(lst2[j]-lst1[j])/(4**(j+1)-1))
delta = abs(lst2[-1]-lst1[-1]) delta = abs(lst2[-1]-lst1[-1])
lst1=lst2 lst1 = lst2
print(lst1) print(lst1)
if __name__=='__main__':
a,b,h = 0.6,1.8,0.2 if __name__ == '__main__':
fs=[5.7,4.6,3.5,3.7,4.9,5.2,5.5] a, b, h = 0.6, 1.8, 0.2
trapezoidal(a,b,h,fs) fs = [5.7, 4.6, 3.5, 3.7, 4.9, 5.2, 5.5]
simpson(a,b,h,fs) trapezoidal(a, b, h, fs)
romberg(1,2,lambda x:sin(x**4),1e-4) simpson(a, b, h, fs)
romberg(1, 2, lambda x: sin(x**4), 1e-4)

View File

@ -21,46 +21,59 @@
# Description: # 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''' ''' 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) A, b, x = np.matrix(A), np.matrix(b), np.matrix(x)
n,m = A.shape n, m = A.shape
if n!=m:raise Exception("Not square matrix: {A}".format(A=A)) if n != m:
if b.shape !=( n,1) : raise Exception('Error: {b} must be {n} x1 in dimension'.format(b = b,n=n)) 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)) D = np.diag(np.diag(A))
DI = np.zeros([n,n]) DI = np.zeros([n, n])
for i in range(n):DI[i,i]= 1/D[i,i] for i in range(n):
DI[i, i] = 1/D[i, i]
R = np.eye(n) - DI * A R = np.eye(n) - DI * A
g = DI * b g = DI * b
print('R =\n{}'.format(R)) print('R =\n{}'.format(R))
print('g =\n{}'.format(g)) print('g =\n{}'.format(g))
last = -x last = -x
if accuracy != None: if accuracy != None:
ct=0 ct = 0
while 1: while 1:
ct+=1 ct += 1
tmp = x-last tmp = x-last
last = x last = x
mx = max ( abs(i) for i in tmp) mx = max(abs(i) for i in tmp)
if mx<accuracy:return x if mx < accuracy:
return x
x = R*x+g 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: else:
for i in range(times): for i in range(times):
x = R*x+g 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))) print('isLimitd: {}'.format(isLimited(A)))
return x 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''' ''' 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) A, b, x = np.matrix(A), np.matrix(b), np.matrix(x)
n,m = A.shape n, m = A.shape
if n!=m:raise Exception("Not square matrix: {A}".format(A=A)) if n != m:
if b.shape !=( n,1) : raise Exception('Error: {b} must be {n} x1 in dimension'.format(b = b,n=n)) raise Exception("Not square matrix: {A}".format(A=A))
D =np. matrix(np.diag(np.diag(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 L = np.tril(A) - D # L = np.triu(D.T) - D
U = np.triu(A) - D U = np.triu(A) - D
DLI = (D+L).I DLI = (D+L).I
@ -70,61 +83,69 @@ def gauss_seidel(A,b,x,accuracy=None,times=6):
print('f =\n{}'.format(f)) print('f =\n{}'.format(f))
last = -x last = -x
if accuracy != None: if accuracy != None:
ct=0 ct = 0
while 1: while 1:
ct+=1 ct += 1
tmp = x-last tmp = x-last
last = x last = x
mx = max ( abs(i) for i in tmp) mx = max(abs(i) for i in tmp)
if mx<accuracy:return x if mx < accuracy:
return x
x = S*x+f 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: else:
for i in range(times): for i in range(times):
x = S*x+f 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))) print('isLimitd: {}'.format(isLimited(A)))
return x return x
def isLimited(A,strict=False): def isLimited(A, strict=False):
'''通过检查A是否是[严格]对角优来判断迭代是否收敛, 即对角线上的值是否都大于对应行(或者列)的值''' '''通过检查A是否是[严格]对角优来判断迭代是否收敛, 即对角线上的值是否都大于对应行(或者列)的值'''
diag = np.diag(A) diag = np.diag(A)
op = lt if strict else le op = lt if strict else le
if op(A.max(axis=0),diag).all(): return True if op(A.max(axis=0), diag).all():
if op(A.max(axis=1), diag).all(): return True return True
if op(A.max(axis=1), diag).all():
return True
return False return False
testcase=[]
testcase = []
def test(): def test():
for func,A,b,x,*args in testcase: for func, A, b, x, *args in testcase:
acc =None acc = None
times = 6 times = 6
if args !=[] : if args != []:
if isinstance(args[0],int):times = args[0] if isinstance(args[0], int):
else : acc = args[0] times = args[0]
return func(A,b,x,acc,times) else:
acc = args[0]
return func(A, b, x, acc, times)
if __name__ =='__main__': if __name__ == '__main__':
A = [[2,-1,-1], A = [[2, -1, -1],
[1,5,-1], [1, 5, -1],
[1,1,10] [1, 1, 10]
] ]
b = [[-5],[8],[11]] b = [[-5], [8], [11]]
x = [[1],[1],[1]] x = [[1], [1], [1]]
#testcase.append([gauss_seidel,A,b,x]) # testcase.append([gauss_seidel,A,b,x])
A = [[2,-1,1],[3,3,9],[3,3,5]] A = [[2, -1, 1], [3, 3, 9], [3, 3, 5]]
b = [[-1],[0],[4]] b = [[-1], [0], [4]]
x = [[0],[0],[0]] x = [[0], [0], [0]]
#testcase.append([jacob,A,b,x]) # testcase.append([jacob,A,b,x])
A = [[5,-1,-1], A = [[5, -1, -1],
[3,6,2], [3, 6, 2],
[1,-1,2] [1, -1, 2]
] ]
b= [[16],[11],[-2]] b = [[16], [11], [-2]]
x = [[1],[1],[-1]] x = [[1], [1], [-1]]
testcase.append([gauss_seidel,A,b,x,0.001]) testcase.append([gauss_seidel, A, b, x, 0.001])
test() test()

View File

@ -10,35 +10,43 @@
######################################################################### #########################################################################
''' '''
from random import randint,random from random import randint, random
import numpy as np import numpy as np
from operator import neg,and_ from operator import neg, and_
from functools import reduce from functools import reduce
class obj(): class obj():
def __init__(self,data): def __init__(self, data):
self.data=np.array(data) self.data = np.array(data)
def __add__(self,x):
data = x.data if self.__class__ == x.__class__ else x def __add__(self, x):
data = x.data if self.__class__ == x.__class__ else x
return self.__class__(self.data + data) return self.__class__(self.data + data)
def __radd__(self,x):
data = x.data if self.__class__ == x.__class__ else x def __radd__(self, x):
return self.__class__(data +self.data) data = x.data if self.__class__ == x.__class__ else x
def __iadd__(self,x): return self.__class__(data + self.data)
data = x.data if self.__class__ == x.__class__ else x
def __iadd__(self, x):
data = x.data if self.__class__ == x.__class__ else x
self.data += data 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) 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 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) return self.__class__(data * self.data)
def __neg__(self): def __neg__(self):
return neg(self) return neg(self)
def __abs__(self): def __abs__(self):
return abs(self.data) return abs(self.data)
''' '''
@ -49,42 +57,49 @@ class obj():
def data(self,s): def data(self,s):
self.data = s self.data = s
''' '''
def norm(self,n=0):
def norm(self, n=0):
'''the default is +oo norm''' '''the default is +oo norm'''
absolute = abs(self.data) absolute = abs(self.data)
if n < 1 :return max(absolute) if n < 1:
return max(absolute)
return (sum(absolute**n))**(1/n) return (sum(absolute**n))**(1/n)
def hasNorm(self): def hasNorm(self):
'''check norm's three necessary conditions: '''check norm's three necessary conditions:
1. not neg 1. not neg
2. homogenious (qici) 2. homogenious (qici)
3. triangle inequlity 3. triangle inequlity
there is much probably wrong 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: if bl:
n = randint(2,100) n = randint(2, 100)
bl = reduce(and_,[n*(self.norm(i))==(n*self).norm(i) for i in range(3)]) bl = reduce(and_, [n*(self.norm(i)) == (n*self).norm(i)
for i in range(3)])
if bl: if bl:
another = self*randint(2,10)-randint(1,100) 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 reduce(and_, [(another+self).norm(i) <= another.norm(i)+self.norm(i) for i in range(3)])
return False return False
class vector(obj): class vector(obj):
def __init__(self,arr): def __init__(self, arr):
''' arr: iterable''' ''' arr: iterable'''
self.data =np.array(arr) self.data = np.array(arr)
def innerProduct(self,x):
def innerProduct(self, x):
return sum(self.data*x) return sum(self.data*x)
def outerProduct(self,x):
def outerProduct(self, x):
pass pass
class matrix(obj): class matrix(obj):
def __init__(self,s): def __init__(self, s):
'''s is a list of lists''' '''s is a list of lists'''
self.data=np.mat(s) self.data = np.mat(s)
self.T = None self.T = None
self. I = None self. I = None
''' '''
@ -104,31 +119,38 @@ class matrix(obj):
def I(self,s): def I(self,s):
self.I = 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) return np.eye(n)
def norm(self,n=0): def norm(self, n=0):
absolute = abs(self.data) absolute = abs(self.data)
if n < 1: if n < 1:
# max of one row sum # max of one row sum
return max([sum(i) for i in absolute]) return max([sum(i) for i in absolute])
if n==1:return self.norm1() if n == 1:
elif n==2:return self.norm2() return self.norm1()
elif n == 2:
return self.norm2()
def norm1(self): def norm1(self):
''' max of sum of cols''' ''' max of sum of cols'''
absolute = abs(self.data) absolute = abs(self.data)
return max(absolute.sum(axis=0)) return max(absolute.sum(axis=0))
def norm2(self): def norm2(self):
''' max of sum of rows''' ''' max of sum of rows'''
absolute = abs(self.data) absolute = abs(self.data)
return max(absolute.sum(axis=1)) return max(absolute.sum(axis=1))
def norm_f(self): def norm_f(self):
return sum((self.data**2).sum(axis=1))**0.5 return sum((self.data**2).sum(axis=1))**0.5
if __name__ =='__main__':
v1 = vector([1,-2,3,4]) if __name__ == '__main__':
v2 = vector([0,2,0,5]) v1 = vector([1, -2, 3, 4])
m1 = matrix([v1,v2,v2,v1]) v2 = vector([0, 2, 0, 5])
m1 = matrix([v1, v2, v2, v1])
print([v1.norm(i) for i in range(3)]) print([v1.norm(i) for i in range(3)])

View File

@ -12,56 +12,64 @@
#include<stdio.h> #include<stdio.h>
//使用康托展开计算全排列, 下面存储的是0!,1!,2!...(n-1)! //使用康托展开计算全排列, 下面存储的是0!,1!,2!...(n-1)!
long long int fac[100]={}; long long int fac[100] = {};
void calFac(int n) void calFac(int n)
{ {
int i; int i;
fac[0]=1; fac[0] = 1;
for(i=1;i<=n;i++){
fac[i]=i*fac[i-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 中*/ /*sum表示全排列由小到大排序后的名次,从0 开始计数, 由名次求出 n位的排列存储到 arr 中*/
int i,j,ct=0,k, ct2; int i, j, ct = 0, k, ct2;
int flag[n]; int flag[n];
for(i=0;i<n;i++)flag[i]=1;
for(i=n-1;i>=0;i--){ for (i = 0; i < n; i++)flag[i] = 1;
for(j=i;j>=0;j--){
if(j*fac[i]<=sum){ for (i = n - 1; i >= 0; i--) {
ct2=0; for (j = i; j >= 0; j--) {
for(k=0;k<n;++k){ if (j * fac[i] <= sum) {
ct2 = 0;
for (k = 0; k < n; ++k) {
//printf("i%d j%d k%d\n",i,j,k); //printf("i%d j%d k%d\n",i,j,k);
if(flag[k]==1)ct2++; if (flag[k] == 1)ct2++;
if(ct2>j)break;
if (ct2 > j)break;
} }
arr[ct++] = k; arr[ct++] = k;
flag[k]=0; flag[k] = 0;
sum -=j*fac[i]; sum -= j * fac[i];
break; 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"); printf("\n");
} }
int main() int main()
{ {
int n = 5,arr[n]; int n = 5, arr[n];
calFac(n); calFac(n);
for(int i=0;i<5;++i)arr[i]=i;
for(int i=0;i<fac[n];++i){ for (int i = 0; i < 5; ++i)arr[i] = i;
printArr(arr,n);
permute(arr,n,i); for (int i = 0; i < fac[n]; ++i) {
printArr(arr, n);
permute(arr, n, i);
} }
return 0; return 0;
} }

View File

@ -1,6 +1,6 @@
''' mbinary ''' mbinary
######################################################################### #########################################################################
# File : 8Astar.py # File : Astar.py
# Author: mbinary # Author: mbinary
# Mail: zhuheqin1@gmail.com # Mail: zhuheqin1@gmail.com
# Blog: https://mbinary.xyz # Blog: https://mbinary.xyz
@ -10,53 +10,62 @@
######################################################################### #########################################################################
''' '''
isVisited = [0]*362880 # 0 for not visited,1 for occured,2 for visited from random import shuffle
fac = [1,1,2,6,24,120,720,5040,40320] isVisited = [0]*362880 # 0 for not visited,1 for occured,2 for visited
fac = [1, 1, 2, 6, 24, 120, 720, 5040, 40320]
lf = len(fac) lf = len(fac)
h = [[0,1,2,1,2,3,2,3,4], h = [[0, 1, 2, 1, 2, 3, 2, 3, 4],
[1,0,1,2,1,2,3,2,3], [1, 0, 1, 2, 1, 2, 3, 2, 3],
[2,1,0,3,2,1,4,3,2], [2, 1, 0, 3, 2, 1, 4, 3, 2],
[1,2,3,0,1,2,1,2,3], [1, 2, 3, 0, 1, 2, 1, 2, 3],
[2,1,2,1,0,1,2,1,2], [2, 1, 2, 1, 0, 1, 2, 1, 2],
[3,2,1,2,1,0,3,2,1], [3, 2, 1, 2, 1, 0, 3, 2, 1],
[2,3,4,1,2,3,0,1,2], [2, 3, 4, 1, 2, 3, 0, 1, 2],
[3,2,3,2,1,2,1,0,1], [3, 2, 3, 2, 1, 2, 1, 0, 1],
[4,3,2,3,2,1,2,1,0]] [4, 3, 2, 3, 2, 1, 2, 1, 0]]
def cantor(s): def cantor(s):
sum = 0 sum = 0
ls = len(s) ls = len(s)
for i in range(ls): for i in range(ls):
count = 0 count = 0
for j in range(i+1,ls): for j in range(i+1, ls):
if s[i] > s[j]: count +=1 if s[i] > s[j]:
count += 1
sum += count*fac[lf-i-1] sum += count*fac[lf-i-1]
return sum return sum
que = [] que = []
dir = {-3:'u',1:'r',3:'d',-1:'l'} dir = {-3: 'u', 1: 'r', 3: 'd', -1: 'l'}
class state: class state:
flag = True 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.x = x
self.s = list(s) self.s = list(s)
self.step = step self.step = step
self.path = [] self.path = []
self.last = last self.last = last
self.f = f self.f = f
def can(self): def can(self):
cans = [-1,1,3,-3] cans = [-1, 1, 3, -3]
if self.last in cans : if self.last in cans:
cans.remove(-self.last) cans.remove(-self.last)
if self.x<3: if self.x < 3:
cans.remove(-3) cans.remove(-3)
if self.x>5: if self.x > 5:
cans.remove(3) cans.remove(3)
if self.x%3 is 0: if self.x % 3 is 0:
cans.remove(-1) cans.remove(-1)
if self.x%3 is 2: if self.x % 3 is 2:
cans.remove(1) cans.remove(1)
return cans return cans
def move(self): def move(self):
cans = self.can() cans = self.can()
for i in cans: for i in cans:
@ -65,36 +74,46 @@ class state:
s[self.x] = s[tmp] s[self.x] = s[tmp]
s[tmp] = '9' s[tmp] = '9'
ct = cantor(s) ct = cantor(s)
if isVisited[ct] != 2 : if isVisited[ct] != 2:
val = int(s[self.x]) 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 f = h[8][tmp] + h[val-1][self.x] - \
new = state(s,tmp,f,self.step +1,i) 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]] new.path = self.path + [dir[i]]
if isVisited[ct] == 1: if isVisited[ct] == 1:
for i,node in enumerate(que): for i, node in enumerate(que):
if mew.s == node.s: if mew.s == node.s:
del que[i] del que[i]
break break
else:isVisited[ct] = 1 else:
isVisited[ct] = 1
if que == []: if que == []:
que.append(new) que.append(new)
continue continue
for i,node in enumerate(que): for i, node in enumerate(que):
if new.f<=node.f: if new.f <= node.f:
que.insert(i,new) que.insert(i, new)
def solvable(s): def solvable(s):
reverse = 0 reverse = 0
for i in range(8): for i in range(8):
if s[i] is '9':continue if s[i] is '9':
for j in range(i+1,9): continue
if s[i]>s[j]:reverse +=1 for j in range(i+1, 9):
if reverse % 2 is 0:return True if s[i] > s[j]:
else:return False reverse += 1
def getPath(s,index): if reverse % 2 is 0:
return True
else:
return False
def getPath(s, index):
f = 0 f = 0
for i,j in enumerate(s): for i, j in enumerate(s):
f+=h[int(j)-1][i] f += h[int(j)-1][i]
que.append(state(s,index,f,0,0)) que.append(state(s, index, f, 0, 0))
while que != []: while que != []:
cur = que.pop(0) cur = que.pop(0)
ct = cantor(cur.s) ct = cantor(cur.s)
@ -102,28 +121,34 @@ def getPath(s,index):
if ct is 0: if ct is 0:
return cur.path return cur.path
cur.move() cur.move()
def info(): def info():
print('input a 3x3 matrix in one line') print('input a 3x3 matrix in one line')
print('from left to right,from up to down') print('from left to right,from up to down')
print('such as 56831247x represent matrix as follow') print('such as 56831247x represent matrix as follow')
print('5 6 8\n3 1 2\n4 7 x') print('5 6 8\n3 1 2\n4 7 x')
print('then, if it has, I will print the path of moving x to reach state as follows') print('then, if it has, I will print the path of moving x to reach state as follows')
print('1 2 3\n4 5 6\n7 8 x') print('1 2 3\n4 5 6\n7 8 x')
print('print q to quit') print('print q to quit')
from random import shuffle
case = list('12345678x') case = list('12345678x')
def genCase(): def genCase():
tmp = case.copy() tmp = case.copy()
shuffle(tmp) shuffle(tmp)
print(f'Using random data: {tmp}') print(f'Using random data: {tmp}')
index = -1 index = -1
for i,j in enumerate(tmp): for i, j in enumerate(tmp):
if j=='x': if j == 'x':
index = i index = i
break break
tmp[index] = '9' tmp[index] = '9'
return tmp,index return tmp, index
def isValid(li): def isValid(li):
for i in '123456789': for i in '123456789':
if not i in li: if not i in li:
@ -131,12 +156,13 @@ def isValid(li):
return False return False
return True return True
def run(): def run():
while 1: while 1:
print('\n\n'+'-'*10+'Game Begins'+ '-'*10) print('\n\n'+'-'*10+'Game Begins' + '-'*10)
info() info()
s=input('input: ') s = input('input: ')
if s=='q' or s=='Q' or s=='quit': if s == 'q' or s == 'Q' or s == 'quit':
break break
index = s.find('x') index = s.find('x')
li = list(s) li = list(s)
@ -145,8 +171,9 @@ def run():
if not isValid(li): if not isValid(li):
li, index = genCase() li, index = genCase()
if solvable(li): if solvable(li):
print(''.join(getPath(li,index))) print(''.join(getPath(li, index)))
else:print('unsolvable') else:
print('unsolvable')
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -13,22 +13,27 @@ from bitarray import bitarray
import mmh3 import mmh3
class bloomFilter(set): class bloomFilter(set):
def __init__(self,size,hash_count): def __init__(self, size, hash_count):
super(bloomFilter,self).__init__() super(bloomFilter, self).__init__()
self.bits = bitarray(size) self.bits = bitarray(size)
self.bits.setall(0) self.bits.setall(0)
self.size = size self.size = size
self.hash_count = hash_count self.hash_count = hash_count
def __len__(self): def __len__(self):
return self.size return self.size
def __iter__(self): def __iter__(self):
return iter(self.bits) return iter(self.bits)
def add(self,item):
def add(self, item):
for i in range(self.hash_count): for i in range(self.hash_count):
idx = mmh3.hash(item,i) % self.size idx = mmh3.hash(item, i) % self.size
self.bits[idx]=1 self.bits[idx] = 1
return self return self
def __contains__(self,item):
idxs = [mmh3.hash(item,i)%self.size for i in range(self.hash_count)] def __contains__(self, item):
return all([self.bits[i]==1 for i in idxs]) idxs = [mmh3.hash(item, i) % self.size for i in range(self.hash_count)]
return all([self.bits[i] == 1 for i in idxs])

View File

@ -15,89 +15,105 @@
设有n个任务由k个可并行工作的机器来完成完成任务i需要时间为 试设计一个算法找出完成这n个任务的最佳调度使完成全部任务的时间最早 设有n个任务由k个可并行工作的机器来完成完成任务i需要时间为 试设计一个算法找出完成这n个任务的最佳调度使完成全部任务的时间最早
''' '''
from time import time from time import time
from functools import total_ordering from functools import total_ordering
@total_ordering @total_ordering
class record: class record:
def __init__(self,nums=None): def __init__(self, nums=None):
if nums is None: if nums is None:
nums=[] nums = []
self.nums=nums self.nums = nums
self.sum = sum(nums) self.sum = sum(nums)
def append(self,x):
def append(self, x):
self.nums.append(x) self.nums.append(x)
self.sum+=x self.sum += x
def pop(self): def pop(self):
x = self.nums.pop() x = self.nums.pop()
self.sum-=x self.sum -= x
return x return x
def __repr__(self): def __repr__(self):
return repr(self.nums) return repr(self.nums)
def __lt__(self,r):
return self.sum<r.sum def __lt__(self, r):
def __eq__(self,r): return self.sum < r.sum
return self.sum==r.sum
def __eq__(self, r):
return self.sum == r.sum
def tolist(self): def tolist(self):
return self.nums.copy() return self.nums.copy()
def __hash__(self): def __hash__(self):
return self.sum return self.sum
def schedule(works,k):
def backtrackSearch(i,lsts):
nonlocal best,rst def schedule(works, k):
if i==n: def backtrackSearch(i, lsts):
cost = max(r.sum for r in lsts ) nonlocal best, rst
if best>cost: if i == n:
best= cost cost = max(r.sum for r in lsts)
if best > cost:
best = cost
rst = [st.tolist() for st in lsts] rst = [st.tolist() for st in lsts]
else: else:
for cur in set(lsts): for cur in set(lsts):
if best>cur.sum+works[i]: if best > cur.sum+works[i]:
cur.append(works[i]) cur.append(works[i])
backtrackSearch(i+1,lsts) backtrackSearch(i+1, lsts)
cur.pop() cur.pop()
def findInitial(i,lst):
def findInitial(i, lst):
nonlocal best nonlocal best
if i==n: if i == n:
cost = max(lst) cost = max(lst)
if best>cost:best = cost if best > cost:
best = cost
else: else:
mn = lst[0] mn = lst[0]
idx = 0 idx = 0
visited=set() visited = set()
for j,cur in enumerate(lst): for j, cur in enumerate(lst):
if cur not in visited: if cur not in visited:
visited.add(cur) visited.add(cur)
if mn>cur: if mn > cur:
mn = cur mn = cur
idx = j idx = j
lst[idx]+=works[i] lst[idx] += works[i]
findInitial(i+1,lst) findInitial(i+1, lst)
lst[idx]-=works[i] lst[idx] -= works[i]
n = len(works) n = len(works)
print() print()
print('machine Num:',n) print('machine Num:', n)
print('works :',works) print('works :', works)
rst = None rst = None
works.sort(reverse=True) # key step works.sort(reverse=True) # key step
best = sum(works[:n-k+1]) best = sum(works[:n-k+1])
t = time() t = time()
findInitial(0,[0]*k) # key step findInitial(0, [0]*k) # key step
t1 = time()-t 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() t = time()
backtrackSearch(0,[record() for i in range(k)]) backtrackSearch(0, [record() for i in range(k)])
t2 = time()-t t2 = time()-t
print('final solution: {} cost time {:.6f}s'.format(best,t2)) print('final solution: {} cost time {:.6f}s'.format(best, t2))
print('schedule plan:',rst) print('schedule plan:', rst)
return best,rst return best, rst
if __name__=='__main__':
if __name__ == '__main__':
from random import randint from random import randint
schedule([47,20,28,44,21,45,30,39,28,33],3) 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([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([39, 39, 23, 45, 100, 69, 21, 81, 39, 55,
20, 86, 34, 53, 58, 99, 36, 45, 46], 8)
''' '''
machine Num: 19 machine Num: 19

View File

@ -12,37 +12,39 @@
''' '''
设有n件工作要分配给n个人去完成将工作i分配给第j个人所需费用为c_ij 试设计一个算法为每个人分配1件不同的工作并使总费用达到最小 设有n件工作要分配给n个人去完成将工作i分配给第j个人所需费用为c_ij 试设计一个算法为每个人分配1件不同的工作并使总费用达到最小
''' '''
import random
def dispatch(mat): def dispatch(mat):
'''mat: matrix of c_ij''' '''mat: matrix of c_ij'''
def _util(i,arrange,cost): def _util(i, arrange, cost):
''' for i-th work''' ''' for i-th work'''
nonlocal total,used,rst nonlocal total, used, rst
if i==n: if i == n:
total=cost total = cost
rst = arrange.copy() # copy is needed rst = arrange.copy() # copy is needed
else: else:
for j in range(n): for j in range(n):
if not used[j] and( total is None or cost+mat[i][j]<total): if not used[j] and(total is None or cost+mat[i][j] < total):
used[j]=True used[j] = True
arrange[i] = j arrange[i] = j
_util(i+1,arrange,cost+mat[i][j]) _util(i+1, arrange, cost+mat[i][j])
used[j]=False used[j] = False
total = None total = None
rst = None rst = None
n = len(mat) n = len(mat)
used = [False for i in range(n)] used = [False for i in range(n)]
_util(0,[-1]*n,0) _util(0, [-1]*n, 0)
return total,rst return total, rst
import random if __name__ == '__main__':
if __name__=='__main__':
n = 10 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') print('work matrix: c_ij: work_i and person_j')
for i in range(n): for i in range(n):
print(mat[i]) print(mat[i])
print('result: ',end='') print('result: ', end='')
print(dispatch(mat)) print(dispatch(mat))

View File

@ -12,57 +12,69 @@
from functools import total_ordering from functools import total_ordering
@total_ordering @total_ordering
class node: class node:
def __init__(self,val,left=None,right=None): def __init__(self, val, left=None, right=None):
self.val=val self.val = val
self.frequency = 1 self.frequency = 1
self.left=left self.left = left
self.right=right self.right = right
def __lt__(self,x):
return self.val<x.val def __lt__(self, x):
def __eq__(self,x): return self.val < x.val
return self.val==x.val
def __eq__(self, x):
return self.val == x.val
def inc(self): def inc(self):
self.val+=1 self.val += 1
def dec(self): def dec(self):
self.val-=1 self.val -= 1
def incFreq(self): def incFreq(self):
self.frequency +=1 self.frequency += 1
def decFreq(self): def decFreq(self):
self.frequency -=1 self.frequency -= 1
class binaryTree: class binaryTree:
def __init__(self,reverse = True): def __init__(self, reverse=True):
self.reverse = reverse self.reverse = reverse
self.data=None self.data = None
def cmp(self,n1,n2):
ret=0 def cmp(self, n1, n2):
if n1 < n2: ret=-1 ret = 0
if n1 > n2: ret= 1 if n1 < n2:
ret = -1
if n1 > n2:
ret = 1
return ret * -1 if self.reverse else ret return ret * -1 if self.reverse else ret
def addNode(self,nd):
def _add(prt,chd): def addNode(self, nd):
if self.cmp(prt,chd)==0: def _add(prt, chd):
if self.cmp(prt, chd) == 0:
prt.incFreq() prt.incFreq()
return return
if self.cmp(prt,chd)<0: if self.cmp(prt, chd) < 0:
if not isinstance(nd,node):nd=node(nd) if not isinstance(nd, node):
if not self.root : nd = node(nd)
self.root=node(val) if not self.root:
self.root = node(val)
else: else:
if self.root == val: if self.root == val:
self.root.incfreq() self.root.incfreq()
else: else:
cur = self.root cur = self.root
def build(self,lst):
def build(self, lst):
dic = {} dic = {}
for i in lst: for i in lst:
if i in dic: if i in dic:
dic[i].incFreq() dic[i].incFreq()
else: else:
dic[i] = node(i) dic[i] = node(i)
self.data =list( dic.values()) self.data = list(dic.values())

View File

@ -11,62 +11,76 @@
''' '''
from functools import partial from functools import partial
class heap: class heap:
def __init__(self,lst,reverse = False): def __init__(self, lst, reverse=False):
self.data= heapify(lst,reverse) self.data = heapify(lst, reverse)
self.cmp = partial(lambda i,j,r:cmp(self.data[i],self.data[j],r),r= reverse) self.cmp = partial(lambda i, j, r: cmp(
self.data[i], self.data[j], r), r=reverse)
def getTop(self): def getTop(self):
return self.data[0] return self.data[0]
def __getitem__(self,idx):
def __getitem__(self, idx):
return self.data[idx] return self.data[idx]
def __bool__(self): def __bool__(self):
return self.data != [] return self.data != []
def popTop(self): def popTop(self):
ret = self.data[0] ret = self.data[0]
n = len(self.data) n = len(self.data)
cur = 1 cur = 1
while cur * 2<=n: while cur * 2 <= n:
chd = cur-1 chd = cur-1
r_idx = cur*2 r_idx = cur*2
l_idx = r_idx-1 l_idx = r_idx-1
if r_idx==n: if r_idx == n:
self.data[chd] = self.data[l_idx] self.data[chd] = self.data[l_idx]
break 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] self.data[chd] = self.data[j]
cur = j+1 cur = j+1
self.data[cur-1] = self.data[-1] self.data[cur-1] = self.data[-1]
self.data.pop() self.data.pop()
return ret return ret
def addNode(self,val): def addNode(self, val):
self.data.append(val) self.data.append(val)
self.data = one_heapify(len(self.data)-1) 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 fac = -1 if reverse else 1
if n1 < n2: return -fac if n1 < n2:
elif n1 > n2: return fac return -fac
elif n1 > n2:
return fac
return 0 return 0
def heapify(lst,reverse = False):
def heapify(lst, reverse=False):
for i in range(len(lst)): for i in range(len(lst)):
lst = one_heapify(lst,i,reverse) lst = one_heapify(lst, i, reverse)
return lst 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 chd = cur-1
prt = cur//2-1 prt = cur//2-1
if cmp(lst[prt],lst[chd],reverse)<0: if cmp(lst[prt], lst[chd], reverse) < 0:
break break
lst[prt],lst[chd] = lst[chd], lst[prt] lst[prt], lst[chd] = lst[chd], lst[prt]
cur = prt+1 cur = prt+1
return lst return lst
def heapSort(lst,reverse = False):
def heapSort(lst, reverse=False):
lst = lst.copy() lst = lst.copy()
hp = heap(lst,reverse) hp = heap(lst, reverse)
ret = [] ret = []
while hp: while hp:
ret.append(hp.popTop()) ret.append(hp.popTop())
@ -75,10 +89,10 @@ def heapSort(lst,reverse = False):
if __name__ == '__main__': if __name__ == '__main__':
from random import randint from random import randint
n = randint(10,20) n = randint(10, 20)
lst = [randint(0,100) for i in range(n)] lst = [randint(0, 100) for i in range(n)]
print('random : ', lst) print('random : ', lst)
print('small-heap: ', heapify(lst)) print('small-heap: ', heapify(lst))
print('big-heap : ', heapify(lst,True)) print('big-heap : ', heapify(lst, True))
print('ascend : ', heapSort(lst)) print('ascend : ', heapSort(lst))
print('descend : ', heapSort(lst,True)) print('descend : ', heapSort(lst, True))

View File

@ -9,23 +9,28 @@
# Description: # 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; int pivot = arr[j], p = i, q = j;
while(p<q){
while(p<q && arr[p]<=pivot)++p; while (p < q) {
if(p<q)arr[q--]=arr[p]; while (p < q && arr[p] <= pivot)++p;
while(p<q && arr[q]>pivot)--q;
if(p<q)arr[p++]=arr[q]; 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; return p;
} }
void quickSort(int *arr,int i,int j) void quickSort(int *arr, int i, int j)
{ {
if(i<j){ if (i < j) {
int p = partition(arr,i,j); int p = partition(arr, i, j);
quickSort(arr,i,p-1); quickSort(arr, i, p - 1);
quickSort(arr,p+1,j); quickSort(arr, p + 1, j);
} }
} }

View File

@ -11,6 +11,9 @@
''' '''
from time import time
def quickSort(lst): def quickSort(lst):
'''A optimized version of Hoare partition''' '''A optimized version of Hoare partition'''
@ -31,7 +34,8 @@ def quickSort(lst):
return a return a
def _sort(a, b): def _sort(a, b):
if a >= b: return if a >= b:
return
mid = (a + b) // 2 mid = (a + b) // 2
# 三数取中值置于第一个作为 pivot # 三数取中值置于第一个作为 pivot
if (lst[a] < lst[mid]) ^ (lst[b] < lst[mid]): if (lst[a] < lst[mid]) ^ (lst[b] < lst[mid]):
@ -55,12 +59,14 @@ def quickSort2(lst):
for i in range(a, b): for i in range(a, b):
if lst[i] <= pivot: if lst[i] <= pivot:
j += 1 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] lst[j + 1], lst[b] = lst[b], lst[j + 1]
return j + 1 return j + 1
def _sort(a, b): def _sort(a, b):
if a >= b: return if a >= b:
return
mid = (a + b) // 2 mid = (a + b) // 2
# 三数取中值置于第一个作为 pivot # 三数取中值置于第一个作为 pivot
if (lst[a] < lst[mid]) ^ (lst[b] < lst[mid]): if (lst[a] < lst[mid]) ^ (lst[b] < lst[mid]):
@ -84,7 +90,8 @@ def quickSort3(lst):
for i in range(a, b): for i in range(a, b):
if lst[i] <= pivot: if lst[i] <= pivot:
j += 1 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] lst[j + 1], lst[b] = lst[b], lst[j + 1]
return j + 1 return j + 1
@ -104,9 +111,6 @@ def quickSort3(lst):
return lst return lst
from time import time
def timer(func, lst, n=100): def timer(func, lst, n=100):
t = time() t = time()
for i in range(n): for i in range(n):

View File

@ -10,43 +10,47 @@
######################################################################### #########################################################################
''' '''
def radixSort(lst,radix=10): from random import randint
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 quickSort import quickSort from quickSort import quickSort
from time import time from time import time
from random import randint
def timer(funcs,span,num=1000000):
lst = [randint(0,span) for i in range(num)] def radixSort(lst, radix=10):
print('range({}), {} items'.format(span,num)) 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: for func in funcs:
data = lst.copy() data = lst.copy()
t = time() t = time()
func(data) func(data)
t = time()-t t = time()-t
print('{}: {}s'.format(func.__name__,t)) print('{}: {}s'.format(func.__name__, t))
if __name__ == '__main__': if __name__ == '__main__':
timer([quickSort,radixSort,sorted],1000000000000,1000) timer([quickSort, radixSort, sorted], 1000000000000, 1000)
timer([quickSort,radixSort,sorted],10000,100000) timer([quickSort, radixSort, sorted], 10000, 100000)
lst = [randint(0,100) for i in range(1000)] lst = [randint(0, 100) for i in range(1000)]
print(countSort(lst,0,100)==sorted(lst)) print(countSort(lst, 0, 100) == sorted(lst))

View File

@ -11,39 +11,47 @@
''' '''
from random import randint from random import randint
def select(lst,i):
def select(lst, i):
lst = lst.copy() lst = lst.copy()
def partition(a,b):
def partition(a, b):
pivot = lst[a] pivot = lst[a]
while a<b: while a < b:
while a<b and lst[b]>pivot: b-=1 while a < b and lst[b] > pivot:
if a<b: b -= 1
if a < b:
lst[a] = lst[b] lst[a] = lst[b]
a+=1 a += 1
while a<b and lst[a]<pivot: a+=1 while a < b and lst[a] < pivot:
if a<b: a += 1
if a < b:
lst[b] = lst[a] lst[b] = lst[a]
b-=1 b -= 1
lst[a]= pivot lst[a] = pivot
return a return a
def _select(a,b): def _select(a, b):
if a>=b: return lst[a] if a >= b:
return lst[a]
# randomized select # randomized select
n = randint(a,b) n = randint(a, b)
lst[a],lst[n] = lst[n],lst[a] lst[a], lst[n] = lst[n], lst[a]
pos = partition(a,b) pos = partition(a, b)
if pos>i: if pos > i:
return _select(a,pos-1) return _select(a, pos-1)
elif pos<i: elif pos < i:
return _select(pos+1,b) return _select(pos+1, b)
else:return lst[pos] else:
return _select(0,len(lst)-1) return lst[pos]
return _select(0, len(lst)-1)
if __name__ =='__main__': if __name__ == '__main__':
lst = [randint(0,1000) for i in range(100)] lst = [randint(0, 1000) for i in range(100)]
st = sorted(lst) st = sorted(lst)
for i in range(10): for i in range(10):
n = randint(0,99) n = randint(0, 99)
print('select {}th: \nexpect: {}\ngot: {}'.format(n,st[n],select(lst,n))) print('select {}th: \nexpect: {}\ngot: {}'.format(
n, st[n], select(lst, n)))

View File

@ -10,26 +10,28 @@
######################################################################### #########################################################################
''' '''
def shellSort(s,gaps=None):
def shellSort(s, gaps=None):
if gaps is None: if gaps is None:
gaps = [127,63,31,15,7,3,1] gaps = [127, 63, 31, 15, 7, 3, 1]
n = len(s) n = len(s)
for gap in gaps: for gap in gaps:
for j in range(gap,n): for j in range(gap, n):
cur = j cur = j
num = s[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] s[cur] = s[cur-gap]
cur-=gap cur -= gap
s[cur] = num s[cur] = num
return s return s
if __name__=='__main__':
if __name__ == '__main__':
from random import randint from random import randint
import sys import sys
n = 20 n = 20
if len(sys.argv)>1: if len(sys.argv) > 1:
n = int(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(nums)
print(shellSort(nums)) print(shellSort(nums))

View File

@ -11,48 +11,55 @@
######################################################################### #########################################################################
''' '''
def getPrefixFunc(s): def getPrefixFunc(s):
'''return the list of prefix function of s''' '''return the list of prefix function of s'''
length = 0 length = 0
i = 1 i = 1
n = len(s) n = len(s)
ret = [0] ret = [0]
while i<n: while i < n:
if s[i]==s[length]: if s[i] == s[length]:
length +=1 length += 1
ret.append(length) ret.append(length)
i+=1 i += 1
else: else:
if length==0: if length == 0:
ret.append(0) ret.append(0)
i+=1 i += 1
else: else:
length = ret[length-1] length = ret[length-1]
return ret 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 from random import randint
s = randStr(50) s = randStr(50)
p = randStr(1) p = randStr(1)
print(s) print(s)
print(p) print(p)
print(findAll(s,p)) print(findAll(s, p))

View File

@ -10,6 +10,7 @@
######################################################################### #########################################################################
''' '''
class Solution: class Solution:
def longestPalindrome(self, s): def longestPalindrome(self, s):
""" """
@ -17,22 +18,23 @@ class Solution:
:rtype: str :rtype: str
""" """
n = len(s) n = len(s)
s2='$#'+'#'.join(s)+'#@' s2 = '$#'+'#'.join(s)+'#@'
ct =[0]*(2*n+4) ct = [0]*(2*n+4)
mid=1 mid = 1
for cur in range(1,2*n+2): for cur in range(1, 2*n+2):
if cur<mid+ct[mid]: if cur < mid+ct[mid]:
ct[cur] = min(ct[2*mid-cur],mid+ct[mid]-cur) ct[cur] = min(ct[2*mid-cur], mid+ct[mid]-cur)
else: else:
ct[cur]=1 ct[cur] = 1
while s2[cur-ct[cur]]==s2[cur+ct[cur]]: while s2[cur-ct[cur]] == s2[cur+ct[cur]]:
ct[cur]+=1 ct[cur] += 1
if cur+ct[cur] > mid+ct[mid]:mid = cur if cur+ct[cur] > mid+ct[mid]:
mid = cur
mx = max(ct) 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] p = idxs[0]
for i in idxs: for i in idxs:
if s2[i]=='#':p = i if s2[i] == '#':
rst =s2[p-mx+1:p+mx].replace('#','') p = i
return rst rst = s2[p-mx+1:p+mx].replace('#', '')
return rst

View File

@ -15,44 +15,50 @@ import re
class markov: class markov:
def __init__(self,txt): def __init__(self, txt):
self.words= self.clean(txt) self.words = self.clean(txt)
self.dic = self.getDic(self.words) self.dic = self.getDic(self.words)
def clean(self,text):
text = text.replace("\n", " "); def clean(self, text):
text = text.replace("\"", ""); text = text.replace("\n", " ")
text = text.replace("\"", "")
# 保证每个标点符号都和前面的单词在一起
# 这样不会被剔除,保留在马尔可夫链中 # 保证每个标点符号都和前面的单词在一起
punctuation = [',', '.', ';',':'] # 这样不会被剔除,保留在马尔可夫链中
for symbol in punctuation: punctuation = [',', '.', ';', ':']
text = text.replace(symbol, symbol+" "); for symbol in punctuation:
text = text.replace(symbol, symbol+" ")
return re.split(' +',text)
return re.split(' +', text)
def getDic(self,words):
dic = {} def getDic(self, words):
end = len(words) dic = {}
for i in range(1,end): end = len(words)
if words[i-1] not in dic: for i in range(1, end):
dic[words[i-1]] = {words[i]:1} if words[i-1] not in dic:
elif words[i] not in dic[words[i-1]]: dic[words[i-1]] = {words[i]: 1}
dic[words[i-1]][words[i]] = 1 elif words[i] not in dic[words[i-1]]:
else: dic[words[i-1]][words[i]] +=1 dic[words[i-1]][words[i]] = 1
return dic else:
def getSum(self,dic): dic[words[i-1]][words[i]] += 1
if '%size' not in dic: return dic
dic['%size'] = sum(list(dic.values()))
return dic['%size'] def getSum(self, dic):
def nextWord(self,word): if '%size' not in dic:
k = randint(1,self.getSum(self.dic[word])) dic['%size'] = sum(list(dic.values()))
for i,j in self.dic[word].items(): return dic['%size']
k-=j
if k<=0:return i def nextWord(self, word):
def genSentence(self,begin = 'I',length = 30): k = randint(1, self.getSum(self.dic[word]))
li = [begin] for i, j in self.dic[word].items():
nextWord= begin k -= j
for i in range(1,length): if k <= 0:
nextWord= self.nextWord(nextWord) return i
li.append(nextWord)
return ' '.join(li) 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)

View File

@ -27,34 +27,37 @@ When the window is no longer valid, start expanding again using the right pointe
''' '''
from collections import defaultdict from collections import defaultdict
class Solution: class Solution:
def minWindow(self, s: str, t: str) -> str: def minWindow(self, s: str, t: str) -> str:
def expand(j,lacked,dic): def expand(j, lacked, dic):
while j<n and lacked: while j < n and lacked:
if s[j] in lacked: if s[j] in lacked:
lacked[s[j]]-=1 lacked[s[j]] -= 1
if lacked[s[j]]==0: if lacked[s[j]] == 0:
del lacked[s[j]] del lacked[s[j]]
dic[s[j]]+=1 dic[s[j]] += 1
j+=1 j += 1
return j return j
def contract(left,right):
for i in range(left,right): def contract(left, right):
dic[s[i]]-=1 for i in range(left, right):
if dic[s[i]]==0: dic[s[i]] -= 1
if dic[s[i]] == 0:
del dic[s[i]] del dic[s[i]]
if s[i] in chars and (s[i] not in dic or dic[s[i]]<chars[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} return i+1, {s[i]: 1}
n ,i, j= len(s),0,0 n, i, j = len(s), 0, 0
ans = '' ans = ''
dic,lacked = defaultdict(int), defaultdict(int) dic, lacked = defaultdict(int), defaultdict(int)
for c in t: for c in t:
lacked[c]+=1 lacked[c] += 1
chars = lacked.copy() chars = lacked.copy()
while j<n and lacked: while j < n and lacked:
j = expand(j,lacked,dic) j = expand(j, lacked, dic)
if not lacked: if not lacked:
i,lacked=contract(i,j) i, lacked = contract(i, j)
if ans=='' or len(ans)>j-i+1: if ans == '' or len(ans) > j-i+1:
ans = s[i-1:j] ans = s[i-1:j]
return ans return ans

View File

@ -11,50 +11,62 @@
######################################################################### #########################################################################
''' '''
def isPrime(x): def isPrime(x):
for i in range(2,int(x**0.5)+1): for i in range(2, int(x**0.5)+1):
if x%i==0:return False if x % i == 0:
return False
return True return True
def getPrime(x): def getPrime(x):
'''return a prime which is bigger than x''' '''return a prime which is bigger than x'''
for i in range(x,2*x): for i in range(x, 2*x):
if isPrime(i):return i if isPrime(i):
def findAll(s,p): return i
def findAll(s, p):
'''s: string p: pattern''' '''s: string p: pattern'''
dic={} dic = {}
n,m = len(s),len(p) n, m = len(s), len(p)
d=0 #radix d = 0 # radix
for c in s: for c in s:
if c not in dic: if c not in dic:
dic[c]=d dic[c] = d
d+=1 d += 1
sm = 0 sm = 0
for c in p: for c in p:
if c not in dic:return [] if c not in dic:
return []
sm = sm*d+dic[c] sm = sm*d+dic[c]
ret = [] ret = []
cur = 0 cur = 0
for i in range(m): cur=cur*d + dic[s[i]] for i in range(m):
if cur==sm:ret.append(0) cur = cur*d + dic[s[i]]
if cur == sm:
ret.append(0)
tmp = n-m tmp = n-m
q = getPrime(m) q = getPrime(m)
cur = cur%q cur = cur % q
sm = sm%q sm = sm % q
exp = d**(m-1) % 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 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) ret.append(i-m+1)
return ret 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 from random import randint
s = randStr(50) s = randStr(50)
p = randStr(1) p = randStr(1)
print(s) print(s)
print(p) print(p)
print(findAll(s,p)) print(findAll(s, p))

View File

@ -17,77 +17,80 @@
######################################################################### #########################################################################
''' '''
def rotate(s,k,right=False):
def reverse(a,b): def rotate(s, k, right=False):
while a<b: def reverse(a, b):
s[a],s[b]=s[b],s[a] while a < b:
a+=1 s[a], s[b] = s[b], s[a]
b-=1 a += 1
n=len(s) b -= 1
k = k%n if not right else n-k%n n = len(s)
reverse(0,k-1) k = k % n if not right else n-k % n
reverse(k,n-1) reverse(0, k-1)
reverse(0,n-1) reverse(k, n-1)
reverse(0, n-1)
return s return s
def rotate2(s, k, right=False):
def rotate2(s,k,right=False): def swap(a, b, c):
def swap(a,b,c):
for i in range(c): for i in range(c):
s[a+i],s[b+i] = s[b+i],s[a+i] s[a+i], s[b+i] = s[b+i], s[a+i]
def _rot(pl,pr):
def _rot(pl, pr):
''' swap s[pl,pr) , s[pr:]''' ''' swap s[pl,pr) , s[pr:]'''
if pr==n:return if pr == n:
if pr-pl<=n-pr: return
swap(pl,pr,pr-pl) if pr-pl <= n-pr:
_rot(pr,2*pr-pl) swap(pl, pr, pr-pl)
_rot(pr, 2*pr-pl)
else: else:
swap(pl,pr,n-pr) swap(pl, pr, n-pr)
_rot(n-pr+pl,pr) _rot(n-pr+pl, pr)
n=len(s) n = len(s)
k = k%n if not right else n-k%n k = k % n if not right else n-k % n
_rot(0,k) _rot(0, k)
return s 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): n = len(s)
def gcd(a,b): k = k % n if not right else n-k % n
if b==0:return a r = gcd(n, k)
return gcd(b,a%b)
n=len(s)
k = k%n if not right else n-k%n
r=gcd(n,k)
for i in range(r): for i in range(r):
tmp = s[i] tmp = s[i]
j = (i+k)%n j = (i+k) % n
while j!=i: while j != i:
s[j-k] = s[j] s[j-k] = s[j]
j = (j+k)%n j = (j+k) % n
s[(j-k+n)%n] = tmp s[(j-k+n) % n] = tmp
return s return s
def test(): def test():
def f(func,*args,right=False): def f(func, *args, right=False):
print(' '.join(['testing:',func.__name__,str(args),'right=',str(right)])) print(' '.join(['testing:', func.__name__,
rst = func(*args,right=right) str(args), 'right=', str(right)]))
print('result',rst) rst = func(*args, right=right)
print('result', rst)
print() print()
return f return f
if __name__=='__main__': if __name__ == '__main__':
s=[i for i in range(10)] s = [i for i in range(10)]
tester= test() tester = test()
tester(rotate,s,4,right=True) tester(rotate, s, 4, right=True)
tester(rotate,s,4) tester(rotate, s, 4)
tester(rotate2,s,2,right=True) tester(rotate2, s, 2, right=True)
tester(rotate2,s,2) tester(rotate2, s, 2)
tester(rotate3,s,132,right=True) tester(rotate3, s, 132, right=True)
tester(rotate3,s,132) tester(rotate3, s, 132)
''' '''

View File

@ -12,66 +12,74 @@
''' '''
def getPos(pattern): def getPos(pattern):
dic = {} dic = {}
for i,j in enumerate(pattern[::-1]): for i, j in enumerate(pattern[::-1]):
if j not in dic: if j not in dic:
dic[j]= i dic[j] = i
return dic return dic
def find(s,p):
def find(s, p):
dic = getPos(p) dic = getPos(p)
ps = pp = 0 ps = pp = 0
ns = len(s) ns = len(s)
np = len(p) np = len(p)
while ps<ns and pp<np: while ps < ns and pp < np:
if s[ps] == p[pp]: if s[ps] == p[pp]:
ps,pp = ps+1,pp+1 ps, pp = ps+1, pp+1
else: else:
idx = ps+ np-pp idx = ps + np-pp
if idx >=ns:return -1 if idx >= ns:
return -1
ch = s[idx] ch = s[idx]
if ch in dic: if ch in dic:
ps += dic[ch]+1-pp ps += dic[ch]+1-pp
else: else:
ps = idx+1 ps = idx+1
pp = 0 pp = 0
if pp==np:return ps-np if pp == np:
return ps-np
else: else:
return -1 return -1
def findAll(s,p):
def findAll(s, p):
ns = len(s) ns = len(s)
np = len(p) np = len(p)
i = 0 i = 0
ret = [] ret = []
while s: while s:
print(s,p) print(s, p)
tmp = find(s,p) tmp = find(s, p)
if tmp==-1: break if tmp == -1:
break
ret.append(i+tmp) ret.append(i+tmp)
end = tmp+np end = tmp+np
i +=end i += end
s = s[end:] s = s[end:]
return ret return ret
def randStr(n=3): 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): def test(n):
s = randStr(n) s = randStr(n)
p = randStr(3) p = randStr(3)
str_s = ''.join((chr(i) for i in s)) str_s = ''.join((chr(i) for i in s))
str_p = ''.join((chr(i) for i in p)) str_p = ''.join((chr(i) for i in p))
n1 = find(s,p) n1 = find(s, p)
n2 = str_s.find(str_p) # 利用已有的 str find 算法检验 n2 = str_s.find(str_p) # 利用已有的 str find 算法检验
if n1!=n2: if n1 != n2:
print(n1,n2,str_p,str_s) print(n1, n2, str_p, str_s)
return False return False
return True return True
if __name__ =='__main__':
if __name__ == '__main__':
from random import randint from random import randint
n = 1000 n = 1000
suc = sum(test(n) for i in range(n)) 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))

View File

@ -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/ # leetcode: q44 https://leetcode.com/problems/wildcard-matching/description/
def isMatch(self, s, p): def isMatch(self, s, p):
""" """
:type s: str :type s: str
:type p: str pattern str including wildcard :type p: str pattern str including wildcard
:rtype: bool :rtype: bool
""" """
n,m = len(s),len(p) n, m = len(s), len(p)
last = [False]*(n+1) last = [False]*(n+1)
last[0] = True last[0] = True
for j in range(m): for j in range(m):
if p[j]=='*': if p[j] == '*':
for i in range(n): for i in range(n):
last[i+1] = last[i+1] or last[i] last[i+1] = last[i+1] or last[i]
elif p[j]=='?': elif p[j] == '?':
last.pop() last.pop()
last.insert(0,False) last.insert(0, False)
else: else:
li = [False] li = [False]
for i in range(n): 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 last = li
return last[-1] return last[-1]

View File

@ -14,39 +14,47 @@ import re
import sys import sys
from translate import Translator as TR 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]+)") Chinese = re.compile(u"(?P<chinese>[\u4e00-\u9fa5]+)")
API = 'https://latex.codecogs.com/gif.latex?' API = 'https://latex.codecogs.com/gif.latex?'
def codecog(f): def codecog(f):
if os.path.exists(f) and f.endswith('.md'): if os.path.exists(f) and f.endswith('.md'):
with open(f) as fp: with open(f) as fp:
txt = fp.read() txt = fp.read()
with open(f,'w') as fp: with open(f, 'w') as fp:
fp.write(re.sub(FORMULA,covert,txt)) fp.write(re.sub(FORMULA, covert, txt))
else: else:
s = re.sub(FORMULA,covert,f) s = re.sub(FORMULA, covert, f)
print(s) print(s)
def covert(matched): def covert(matched):
s = matched.group('formula').strip('$ ') s = matched.group('formula').strip('$ ')
s = re.sub(Chinese,zh2en,s) s = re.sub(Chinese, zh2en, s)
s = re.sub(r'\r+|\n+|\\n',' ',s) s = re.sub(r'\r+|\n+|\\n', ' ', s)
s = re.sub(' +','&space;',s) s = re.sub(' +', '&space;', s)
return '![]({})'.format(API+s) return '![]({})'.format(API+s)
def zh2en(txt): def zh2en(txt):
s = txt.group('chinese').strip() 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) en = tran.translate(s)
return re.sub(' +','-',en) return re.sub(' +', '-', en)
def handle(path): def handle(path):
if os.path.isdir(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: for f in fs:
if f.endswith('.md'): if f.endswith('.md'):
codecog(os.path.join(p,f)) codecog(os.path.join(p, f))
else: else:
codecog(path) codecog(path)
if __name__ == '__main__': if __name__ == '__main__':
args = sys.argv[1:] args = sys.argv[1:]
if not args: if not args:

View File

@ -16,17 +16,18 @@ from config import README
parser = ArgumentParser() parser = ArgumentParser()
parser.add_argument('-p','--path',default='.',help='path to walk') 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('-f', '--fileinclude', action='store_true',
parser.add_argument('-d','--depth', type = int, default = 2) 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() args = parser.parse_args()
FILE = args.fileinclude FILE = args.fileinclude
PATH = args.path PATH = args.path
DEPTH = args.depth DEPTH = args.depth
idxs = tree(PATH,DEPTH,FILE) idxs = tree(PATH, DEPTH, FILE)
s = README.format(index='\n'.join(idxs)) s = README.format(index='\n'.join(idxs))
with open('README.md','w') as f: with open('README.md', 'w') as f:
f.write(s) f.write(s)

View File

@ -15,44 +15,55 @@ import sys
import time import time
from config import HEAD from config import HEAD
count = 0 count = 0
def handleFile(path): def handleFile(path):
global count global count
head = getHead(path) head = getHead(path)
if head =='': return if head == '':
with open(path,'r',encoding='utf8',errors='ignore') as f: return
with open(path, 'r', encoding='utf8', errors='ignore') as f:
s = f.read() s = f.read()
if 'mbinary' in s: if 'mbinary' in s:
return return
count +=1 count += 1
name = os.path.basename(path) name = os.path.basename(path)
print('[{count}]: Adding head info to {name}'.format(count=count,name=name)) print('[{count}]: Adding head info to {name}'.format(count=count, name=name))
with open(path,'w') as f: with open(path, 'w') as f:
f.write(head+s) f.write(head+s)
def getHead(path): def getHead(path):
name = os.path.basename(path) name = os.path.basename(path)
# skip self or hidden file # skip self or hidden file
if name == os.path.basename(__file__) or name[0]=='.': return '' if name == os.path.basename(__file__) or name[0] == '.':
suf = name[name.rfind('.')+1 :] return ''
begin = end ='' suf = name[name.rfind('.')+1:]
begin = end = ''
if suf == 'py': if suf == 'py':
begin = end = "'''" begin = end = "'''"
elif suf in ['c','cc','cpp','java']: elif suf in ['c', 'cc', 'cpp', 'java']:
begin,end = '/*','*/' begin, end = '/*', '*/'
elif suf == 'sh': elif suf == 'sh':
begin = end = '#' begin = end = '#'
else:return '' else:
return ''
timeStamp = time.localtime(os.stat(path).st_ctime) timeStamp = time.localtime(os.stat(path).st_ctime)
ctime = time.strftime('%Y-%m-%d %H:%M',timeStamp) ctime = time.strftime('%Y-%m-%d %H:%M', timeStamp)
return HEAD.format(begin=begin,end=end,ctime=ctime,name = name) return HEAD.format(begin=begin, end=end, ctime=ctime, name=name)
def handleDir(dirPath): def handleDir(dirPath):
gen = os.walk(dirPath) gen = os.walk(dirPath)
for path,dirs,files in gen: for path, dirs, files in gen:
for f in files: handleFile(os.path.join(path,f)) for f in files:
handleFile(os.path.join(path, f))
if __name__ == '__main__': if __name__ == '__main__':
works = sys.argv[1:] works = sys.argv[1:]
if works==[] : works = ['.'] if works == []:
works = ['.']
for one in works: for one in works:
if not os.path.exists(one): if not os.path.exists(one):
print('[PathError]: {one} not exists'.format(one=one)) print('[PathError]: {one} not exists'.format(one=one))

View File

@ -13,42 +13,51 @@
import os import os
from argparse import ArgumentParser from argparse import ArgumentParser
#命令行输入参数处理 # 命令行输入参数处理
parser = ArgumentParser() parser = ArgumentParser()
parser.add_argument('-p','--path',default='.',help='path to walk') 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('-f', '--fileinclude', action='store_true',
parser.add_argument('-d','--depth', type = int, default = 2) help='if has, list files and dirs, else only dirs')
#获取参数 parser.add_argument('-d', '--depth', type=int, default=2)
# 获取参数
args = parser.parse_args() args = parser.parse_args()
FILE = args.fileinclude FILE = args.fileinclude
PATH = args.path PATH = args.path
DEPTH = args.depth DEPTH = args.depth
def mklink(path): 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): def clean(paths):
ret = [] ret = []
for path in paths: for path in paths:
name = os.path.basename(path) name = os.path.basename(path)
if not ( name.startswith('.') or name.startswith('__')): if not (name.startswith('.') or name.startswith('__')):
ret.append(path) ret.append(path)
return ret return ret
def tree(path='.',depth=2,showfile=False):
def tree(path='.', depth=2, showfile=False):
li = [] li = []
if os.path.isdir(path):li = os.listdir(path) if os.path.isdir(path):
else:li=[path] li = os.listdir(path)
items = [os.path.join(path,i) for i in li if not i.startswith('.')] else:
li = [path]
items = [os.path.join(path, i) for i in li if not i.startswith('.')]
items = clean(items) items = clean(items)
items = sorted(items) items = sorted(items)
if not showfile: items = [i for i in items if os.path.isdir(i)] if not showfile:
if depth==1: items = [i for i in items if os.path.isdir(i)]
if depth == 1:
return [mklink(path)] + [' '*4 + mklink(i) for i in items] return [mklink(path)] + [' '*4 + mklink(i) for i in items]
else: 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] 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)))