From ab86fa483a5c194044b18b33f90fd7be1a1ccc01 Mon Sep 17 00:00:00 2001 From: mbinary Date: Wed, 15 Apr 2020 12:28:20 +0800 Subject: [PATCH] Format codes --- README.md | 10 +- dataStructure/bTree.py | 260 +++++---- dataStructure/binaryHeap.py | 149 ++++-- dataStructure/binaryTree.py | 111 ++-- dataStructure/circularQueue.py | 18 +- dataStructure/hashTable.py | 72 ++- dataStructure/huffman/huffman.cc | 497 +++++++++++------- dataStructure/insert_remove_getRandom.py | 26 +- dataStructure/intervalTree.py | 119 +++-- dataStructure/leftHeap.py | 172 +++--- dataStructure/linkedList.py | 31 +- dataStructure/map.cc | 146 ++--- dataStructure/polynomial.cpp | 345 ++++++------ dataStructure/polynomial.py | 136 +++-- dataStructure/redBlackTree.py | 242 +++++---- dataStructure/splayTree.py | 188 ++++--- dataStructure/unionFindSet.py | 12 + dataStructure/unionFindSet/accountsMerge.py | 99 ---- dataStructure/unionFindSet/friendsCircle.py | 42 -- dataStructure/winnerTree.py | 108 ++-- divideAndConquer/min_distance_of_n_points.py | 141 ++--- dynamicProgramming/last-stone-weight.py | 5 +- dynamicProgramming/lcs.py | 29 +- .../max-len-of-repeated-subarray.py | 14 +- dynamicProgramming/splitStripe.py | 41 +- dynamicProgramming/stoneGame.py | 6 +- graph/cloneGraph.cpp | 21 +- graph/dfs.py | 38 +- graph/isBipartGraph.py | 15 +- math/dft.py | 2 +- math/fastPow.py | 22 +- math/fibonacci/fibonacci.py | 40 +- math/numWeight/addNegaBin.py | 16 +- math/numWeight/convertWeight.py | 45 +- math/numWeight/nega.py | 15 +- math/numberTheory/euler.py | 17 +- math/numberTheory/factor.py | 48 +- math/numberTheory/gcd.py | 33 +- math/numberTheory/hammingDistance.py | 45 +- math/numberTheory/isPrime.py | 105 ++-- math/numberTheory/modulo_equation.py | 116 ++-- math/numberTheory/primesLEn.hs | 2 +- math/numberTheory/sievePrime.py | 56 ++ math/numericalAnalysis/interplotion.py | 69 +-- math/numericalAnalysis/iteration.py | 98 ++-- math/numericalAnalysis/least_square.py | 75 +-- math/numericalAnalysis/linear_equation.py | 108 ++-- .../numerical_differential.py | 13 - .../numerical_integration.py | 47 +- .../solve-linear-by-iteration.py | 133 +++-- math/numericalAnalysis/vector_norm.py | 112 ++-- math/permute/permute_cantor.c | 56 +- search/{8Astar.py => Astar.py} | 125 +++-- search/bloomFilter.py | 21 +- search/schedule.py | 102 ++-- search/work_dispatch.py | 36 +- sort/binaryTree.py | 70 ++- sort/heapSort.py | 62 ++- sort/quickSort.c | 31 +- sort/quickSort.py | 18 +- sort/radixSort.py | 64 +-- sort/select.py | 58 +- sort/shellSort.py | 18 +- string/KMP.py | 59 ++- string/manacher.py | 32 +- string/markov.py | 88 ++-- string/min-window-substring.py | 45 +- string/rabin_karp.py | 54 +- string/rotate.py | 103 ++-- string/sunday.py | 52 +- string/wildcard_matching.py | 13 +- utils/codecogs.py | 32 +- utils/genReadme.py | 13 +- utils/headinfo.py | 43 +- utils/tree.py | 43 +- 75 files changed, 3122 insertions(+), 2426 deletions(-) create mode 100644 dataStructure/unionFindSet.py delete mode 100644 dataStructure/unionFindSet/accountsMerge.py delete mode 100644 dataStructure/unionFindSet/friendsCircle.py create mode 100644 math/numberTheory/sievePrime.py delete mode 100644 math/numericalAnalysis/numerical_differential.py rename search/{8Astar.py => Astar.py} (58%) diff --git a/README.md b/README.md index dd21bdf..8af01f9 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ [![repo-size](https://img.shields.io/github/repo-size/mbinary/algorithm.svg)]() [![License](https://img.shields.io/badge/LICENSE-WTFPL-blue.svg)](LICENSE) [![Language](https://img.shields.io/badge/language-python3-orange.svg)]() -[![codebeat badge](https://codebeat.co/badges/d52dd17d-a437-4dee-a6ec-cb532e8135bd)](https://codebeat.co/projects/github-com-mbinary-algorithm-master) +[![codebeat badge](https://codebeat.co/badges/4ef725b5-405a-4390-a860-a86deefab3f8)](https://codebeat.co/projects/github-com-mbinary-algorithm-master) >Notes and codes for learning algorithm and data structures :smiley: @@ -17,12 +17,10 @@ Some pictures and ideas are from `<>` * [.](.) * [LICENSE](./LICENSE) * [README.md](./README.md) - * [backtracking](./backtracking) * [dataStructure](./dataStructure) * [LRU](./dataStructure/LRU) * [bTree.py](./dataStructure/bTree.py) * [binaryHeap.py](./dataStructure/binaryHeap.py) - * [binaryHeap1.py](./dataStructure/binaryHeap1.py) * [binaryTree.py](./dataStructure/binaryTree.py) * [circularQueue.py](./dataStructure/circularQueue.py) * [graph](./dataStructure/graph) @@ -32,7 +30,6 @@ Some pictures and ideas are from `<>` * [intervalTree.py](./dataStructure/intervalTree.py) * [leftHeap.py](./dataStructure/leftHeap.py) * [linkedList.py](./dataStructure/linkedList.py) - * [loserTree.py](./dataStructure/loserTree.py) * [map.cc](./dataStructure/map.cc) * [polynomial.cpp](./dataStructure/polynomial.cpp) * [polynomial.py](./dataStructure/polynomial.py) @@ -40,7 +37,7 @@ Some pictures and ideas are from `<>` * [redBlackTree0.py](./dataStructure/redBlackTree0.py) * [splayTree.py](./dataStructure/splayTree.py) * [trie](./dataStructure/trie) - * [unionFindSet](./dataStructure/unionFindSet) + * [unionFindSet.py](./dataStructure/unionFindSet.py) * [winnerTree.py](./dataStructure/winnerTree.py) * [divideAndConquer](./divideAndConquer) * [min_distance_of_n_points.py](./divideAndConquer/min_distance_of_n_points.py) @@ -85,8 +82,9 @@ Some pictures and ideas are from `<>` * [PL0-compiler](./parser/PL0-compiler) * [calculator](./parser/calculator) * [declarationParser](./parser/declarationParser) + * [poly.c](./poly.c) * [search](./search) - * [8Astar.py](./search/8Astar.py) + * [Astar.py](./search/Astar.py) * [BFS_knight.hs](./search/BFS_knight.hs) * [binary_search.hs](./search/binary_search.hs) * [bloomFilter.py](./search/bloomFilter.py) diff --git a/dataStructure/bTree.py b/dataStructure/bTree.py index 0ab812b..c8b9d30 100644 --- a/dataStructure/bTree.py +++ b/dataStructure/bTree.py @@ -10,213 +10,257 @@ ######################################################################### ''' + class node: - def __init__(self,keys=None,isLeaf = True,children=None): - if keys is None:keys=[] - if children is None: children =[] + def __init__(self, keys=None, isLeaf=True, children=None): + if keys is None: + keys = [] + if children is None: + children = [] self.keys = keys - self.isLeaf = isLeaf + self.isLeaf = isLeaf self.children = [] - def __getitem__(self,i): + + def __getitem__(self, i): return self.keys[i] - def __delitem__(self,i): + + def __delitem__(self, i): del self.keys[i] - def __setitem__(self,i,k): + + def __setitem__(self, i, k): self.keys[i] = k + def __len__(self): return len(self.keys) + def __repr__(self): return str(self.keys) + def __str__(self): children = ','.join([str(nd.keys) for nd in self.children]) return f'keys: {self.keys}\nchildren: {children}\nisLeaf: {self.isLeaf}' - def getChd(self,i): + + def getChd(self, i): return self.children[i] - def delChd(self,i): + + def delChd(self, i): del self.children[i] - def setChd(self,i,chd): + + def setChd(self, i, chd): self.children[i] = chd - def getChildren(self,begin=0,end=None): - if end is None:return self.children[begin:] + + def getChildren(self, begin=0, end=None): + if end is None: + return self.children[begin:] return self.children[begin:end] - def findKey(self,key): - for i,k in enumerate(self.keys): - if k>=key: + + def findKey(self, key): + for i, k in enumerate(self.keys): + if k >= key: return i return len(self) - def update(self,keys=None,isLeaf=None,children=None): - if keys is not None:self.keys = keys - if children is not None:self.children = children - if isLeaf is not None: self.isLeaf = isLeaf - def insert(self,i,key=None,nd=None): - if key is not None:self.keys.insert(i,key) - if not self.isLeaf and nd is not None: self.children.insert(i,nd) - def isLeafNode(self):return self.isLeaf - def split(self,prt,t): + + def update(self, keys=None, isLeaf=None, children=None): + if keys is not None: + self.keys = keys + if children is not None: + self.children = children + if isLeaf is not None: + self.isLeaf = isLeaf + + def insert(self, i, key=None, nd=None): + if key is not None: + self.keys.insert(i, key) + if not self.isLeaf and nd is not None: + self.children.insert(i, nd) + + def isLeafNode(self): return self.isLeaf + + def split(self, prt, t): # form new two nodes k = self[t-1] nd1 = node() nd2 = node() - nd1.keys,nd2.keys = self[:t-1], self[t:] # note that t is 1 bigger than key index + # note that t is 1 bigger than key index + nd1.keys, nd2.keys = self[:t-1], self[t:] nd1.isLeaf = nd2.isLeaf = self.isLeaf - if not self.isLeaf: + if not self.isLeaf: # note that children index is one bigger than key index, and all children included - nd1.children, nd2.children = self.children[0:t], self.children[t:] + nd1.children, nd2.children = self.children[0:t], self.children[t:] # connect them to parent idx = prt.findKey(k) - if prt.children !=[]: prt.children.remove(self) # remove the original node - prt.insert(idx,k,nd2) - prt.insert(idx,nd = nd1) + if prt.children != []: + prt.children.remove(self) # remove the original node + prt.insert(idx, k, nd2) + prt.insert(idx, nd=nd1) return prt class bTree: - def __init__(self,degree=2): + def __init__(self, degree=2): self.root = node() - self.degree=degree + self.degree = degree self.nodeNum = 1 self.keyNum = 0 - def search(self,key,withpath=False): + + def search(self, key, withpath=False): nd = self.root fathers = [] while True: i = nd.findKey(key) - if i==len(nd): fathers.append((nd,i-1,i)) - else: fathers.append((nd,i,i)) - if i1:self.rebalance(fathers) - def rebalance(self,fathers): - nd,keyIdx,chdIdx = fathers.pop() - while len(nd) 1: + self.rebalance(fathers) + + def rebalance(self, fathers): + nd, keyIdx, chdIdx = fathers.pop() + while len(nd) < self.degree-1: # rebalance tree from down to up + prt, keyIdx, chdIdx = fathers[-1] + lbro = [] if chdIdx == 0 else prt.getChd(chdIdx-1) + rbro = [] if chdIdx == len(prt) else prt.getChd(chdIdx+1) + if len(lbro) < self.degree and len(rbro) < self.degree: # merge two deficient nodes + beforeNode, afterNode = None, None + if lbro == []: keyIdx = chdIdx - beforeNode,afterNode = nd,rbro + beforeNode, afterNode = nd, rbro else: - beforeNode,afterNode = lbro,nd - keyIdx = chdIdx-1 # important, when choosing + beforeNode, afterNode = lbro, nd + keyIdx = chdIdx-1 # important, when choosing keys = beforeNode[:]+[prt[keyIdx]]+afterNode[:] children = beforeNode.getChildren() + afterNode.getChildren() isLeaf = beforeNode.isLeafNode() prt.delChd(keyIdx+1) del prt[keyIdx] - nd.update(keys,isLeaf,children) - prt.children[keyIdx]=nd - self.nodeNum -=1 - elif len(lbro)>=self.degree: # rotate when only one sibling is deficient + nd.update(keys, isLeaf, children) + prt.children[keyIdx] = nd + self.nodeNum -= 1 + elif len(lbro) >= self.degree: # rotate when only one sibling is deficient keyIdx = chdIdx-1 - nd.insert(0,prt[keyIdx]) # rotate keys - prt[keyIdx] = lbro[-1] + nd.insert(0, prt[keyIdx]) # rotate keys + prt[keyIdx] = lbro[-1] del lbro[-1] if not nd.isLeafNode(): # if not leaf, move children - nd.insert(0,nd=lbro.getChd(-1)) + nd.insert(0, nd=lbro.getChd(-1)) lbro.delChd(-1) else: keyIdx = chdIdx - nd.insert(len(nd),prt[keyIdx]) # rotate keys - prt[keyIdx] = rbro[0] + nd.insert(len(nd), prt[keyIdx]) # rotate keys + prt[keyIdx] = rbro[0] del rbro[0] if not nd.isLeafNode(): # if not leaf, move children - #note that insert(-1,ele) will make the ele be the last second one - nd.insert(len(nd),nd=rbro.getChd(0)) + # note that insert(-1,ele) will make the ele be the last second one + nd.insert(len(nd), nd=rbro.getChd(0)) rbro.delChd(0) - if len(fathers)==1: - if len(self.root)==0: + if len(fathers) == 1: + if len(self.root) == 0: self.root = nd - self.nodeNum -=1 + self.nodeNum -= 1 break - nd,i,j = fathers.pop() + nd, i, j = fathers.pop() + def __str__(self): - head= '\n'+'-'*30+'B Tree'+'-'*30 - tail= '-'*30+'the end'+'-'*30+'\n' - lst = [[head],[f'node num: {self.nodeNum}, key num: {self.keyNum}']] + head = '\n'+'-'*30+'B Tree'+'-'*30 + tail = '-'*30+'the end'+'-'*30+'\n' + lst = [[head], [f'node num: {self.nodeNum}, key num: {self.keyNum}']] cur = [] - ndNum =0 - ndTotal= 1 + ndNum = 0 + ndTotal = 1 que = [self.root] - while que!=[]: + while que != []: nd = que.pop(0) cur.append(repr(nd)) - ndNum+=1 - que+=nd.getChildren() - if ndNum==ndTotal: + ndNum += 1 + que += nd.getChildren() + if ndNum == ndTotal: lst.append(cur) cur = [] ndNum = 0 - ndTotal =len(que) + ndTotal = len(que) lst.append([tail]) lst = [','.join(li) for li in lst] return '\n'.join(lst) - def __iter__(self,nd = None): - if nd is None: nd = self.root + + def __iter__(self, nd=None): + if nd is None: + nd = self.root que = [nd] - while que !=[]: + while que != []: nd = que.pop(0) yield nd - if nd.isLeafNode():continue + if nd.isLeafNode(): + continue for i in range(len(nd)+1): que.append(nd.getChd(i)) -if __name__ =='__main__': +if __name__ == '__main__': bt = bTree() - from random import shuffle,sample + from random import shuffle, sample n = 20 lst = [i for i in range(n)] shuffle(lst) - test= sample(lst,len(lst)//4) + test = sample(lst, len(lst)//4) print(f'building b-tree with {lst}') for i in lst: bt.insert(i) - #print(f'inserting {i}) - #print(bt) + # print(f'inserting {i}) + # print(bt) print(bt) print(f'serching {test}') for i in test: - nd,idx = bt.search(i) + nd, idx = bt.search(i) print(f'node: {repr(nd)}[{idx}]== {i}') for i in test: print(f'deleting {i}') diff --git a/dataStructure/binaryHeap.py b/dataStructure/binaryHeap.py index f5452d1..2ef460a 100644 --- a/dataStructure/binaryHeap.py +++ b/dataStructure/binaryHeap.py @@ -11,106 +11,137 @@ ''' -from collections import Iterable +from collections import Iterable + + class node: - def __init__(self,val,freq=1): - self.val=val + def __init__(self, val, freq=1): + self.val = val self.freq = freq - def __eq__(self,a): - return self.val == a.val - def __lt__(self,a): - return self.vala.val - def __ge__(self,a): - return self.val>=a.val - def __ne__(self,a): + + def __eq__(self, a): + return self.val == a.val + + def __lt__(self, a): + return self.val < a.val + + def __le__(self, a): + return self.val <= a.val + + def __gt__(self, a): + return self.val > a.val + + def __ge__(self, a): + return self.val >= a.val + + def __ne__(self, a): return not self == a + + class binaryHeap: - def __init__(self,s=None,sortByFrequency = False,reverse=False): - self.sortByFrequency=sortByFrequency + def __init__(self, s=None, sortByFrequency=False, reverse=False): + self.sortByFrequency = sortByFrequency self.reverse = reverse self.data = [node(0)] # make index begin with 1 - if s==None:return - if not isinstance(s,Iterable):s = [s] + if s == None: + return + if not isinstance(s, Iterable): + s = [s] for i in s: self.insert(i) + def __bool__(self): - return len(self)!=1 - def _cmp(self,a,b): + return len(self) != 1 + + def _cmp(self, a, b): if self.sortByFrequency: - if self.reverse:return a.freq>b.freq - else:return a.freq b.freq + else: + return a.freq < b.freq else: - if self.reverse:return a>b - else:return a b + else: + return a < b + + def insert(self, k): + if not isinstance(k, node): + k = node(k) for j in range(self.data[0].val): i = self.data[j+1] - if i==k: - i.freq+=1 + if i == k: + i.freq += 1 if self.sortByFrequency: idx = self.percolateDown(j+1) self.percolateUp(idx) - return + return self.data.append(k) self.data[0].val += 1 self.percolateUp() - def percolateUp(self,n=None): - if n ==None:n=self.data[0].val + + def percolateUp(self, n=None): + if n == None: + n = self.data[0].val tmp = self.data[n] - while n!=1 and self._cmp(tmp,self.data[n//2]): + while n != 1 and self._cmp(tmp, self.data[n//2]): self.data[n] = self.data[n//2] n = n//2 self.data[n] = tmp + def deleteTop(self): tmp = self.data[1] i = self.percolateDown(1) self.data[i] = self.data[-1] - self.data[0].val-= 1 + self.data[0].val -= 1 del self.data[-1] return tmp - def percolateDown(self,i): + + def percolateDown(self, i): tmp = self.data[i] - while self.data[0].val>=2*i+1: - if self._cmp(self.data[i*2],self.data[2*i+1]): - self.data[i] = self.data[2*i] - i = 2*i - else: - self.data[i] = self.data[2*i+1] - i = 2*i+1 + while self.data[0].val >= 2*i+1: + if self._cmp(self.data[i*2], self.data[2*i+1]): + self.data[i] = self.data[2*i] + i = 2*i + else: + self.data[i] = self.data[2*i+1] + i = 2*i+1 self.data[i] = tmp return i + def __len__(self): return self.data[0].val - def Nth(self,n=1): + + def Nth(self, n=1): tmp = [] for i in range(n): tmp.append(self.deleteTop()) for i in tmp: self.insert(i) return tmp[-1] + def display(self): - val =self.data[0].val+1 + val = self.data[0].val+1 if self.sortByFrequency: - info='heapSort by Frequency:' - else:info = 'heapSort by Value:' + info = 'heapSort by Frequency:' + else: + info = 'heapSort by Value:' if self.reverse: - info +=' From big to small' - else:info +=' From small to big' + info += ' From big to small' + else: + info += ' From small to big' print('*'*15) print(info) - print('total items:%d\nval\tfreq'%(val-1)) + print('total items:%d\nval\tfreq' % (val-1)) fmt = '{}\t{}' - for i in range(1,val): - print(fmt.format(self.data[i].val,self.data[i].freq)) + for i in range(1, val): + print(fmt.format(self.data[i].val, self.data[i].freq)) print('*'*15) + + class Test: def topKFrequent(self, words, k): - hp = binaryHeap(sortByFrequency = True,reverse=True) + hp = binaryHeap(sortByFrequency=True, reverse=True) for i in words: hp.insert(i) hp.display() @@ -124,15 +155,19 @@ class Test: mp[top.freq] = [top.val] for i in mp: mp[i].sort() - key = sorted(mp.keys(),reverse = True) + key = sorted(mp.keys(), reverse=True) rst = [] count = 0 - for i in key: + for i in key: for j in mp[i]: rst.append(j) - count+=1 - if count == k:return rst + count += 1 + if count == k: + return rst + + if __name__ == '__main__': - s=["plpaboutit","jnoqzdute","sfvkdqf","mjc","nkpllqzjzp","foqqenbey","ssnanizsav","nkpllqzjzp","sfvkdqf","isnjmy","pnqsz","hhqpvvt","fvvdtpnzx","jkqonvenhx","cyxwlef","hhqpvvt","fvvdtpnzx","plpaboutit","sfvkdqf","mjc","fvvdtpnzx","bwumsj","foqqenbey","isnjmy","nkpllqzjzp","hhqpvvt","foqqenbey","fvvdtpnzx","bwumsj","hhqpvvt","fvvdtpnzx","jkqonvenhx","jnoqzdute","foqqenbey","jnoqzdute","foqqenbey","hhqpvvt","ssnanizsav","mjc","foqqenbey","bwumsj","ssnanizsav","fvvdtpnzx","nkpllqzjzp","jkqonvenhx","hhqpvvt","mjc","isnjmy","bwumsj","pnqsz","hhqpvvt","nkpllqzjzp","jnoqzdute","pnqsz","nkpllqzjzp","jnoqzdute","foqqenbey","nkpllqzjzp","hhqpvvt","fvvdtpnzx","plpaboutit","jnoqzdute","sfvkdqf","fvvdtpnzx","jkqonvenhx","jnoqzdute","nkpllqzjzp","jnoqzdute","fvvdtpnzx","jkqonvenhx","hhqpvvt","isnjmy","jkqonvenhx","ssnanizsav","jnoqzdute","jkqonvenhx","fvvdtpnzx","hhqpvvt","bwumsj","nkpllqzjzp","bwumsj","jkqonvenhx","jnoqzdute","pnqsz","foqqenbey","sfvkdqf","sfvkdqf"] + s = ["plpaboutit", "jnoqzdute", "sfvkdqf", "mjc", "nkpllqzjzp", "foqqenbey", "ssnanizsav", "nkpllqzjzp", "sfvkdqf", "isnjmy", "pnqsz", "hhqpvvt", "fvvdtpnzx", "jkqonvenhx", "cyxwlef", "hhqpvvt", "fvvdtpnzx", "plpaboutit", "sfvkdqf", "mjc", "fvvdtpnzx", "bwumsj", "foqqenbey", "isnjmy", "nkpllqzjzp", "hhqpvvt", "foqqenbey", "fvvdtpnzx", "bwumsj", "hhqpvvt", "fvvdtpnzx", "jkqonvenhx", "jnoqzdute", "foqqenbey", "jnoqzdute", "foqqenbey", "hhqpvvt", "ssnanizsav", "mjc", "foqqenbey", "bwumsj", "ssnanizsav", "fvvdtpnzx", "nkpllqzjzp", + "jkqonvenhx", "hhqpvvt", "mjc", "isnjmy", "bwumsj", "pnqsz", "hhqpvvt", "nkpllqzjzp", "jnoqzdute", "pnqsz", "nkpllqzjzp", "jnoqzdute", "foqqenbey", "nkpllqzjzp", "hhqpvvt", "fvvdtpnzx", "plpaboutit", "jnoqzdute", "sfvkdqf", "fvvdtpnzx", "jkqonvenhx", "jnoqzdute", "nkpllqzjzp", "jnoqzdute", "fvvdtpnzx", "jkqonvenhx", "hhqpvvt", "isnjmy", "jkqonvenhx", "ssnanizsav", "jnoqzdute", "jkqonvenhx", "fvvdtpnzx", "hhqpvvt", "bwumsj", "nkpllqzjzp", "bwumsj", "jkqonvenhx", "jnoqzdute", "pnqsz", "foqqenbey", "sfvkdqf", "sfvkdqf"] test = Test() - print(test.topKFrequent(s,5)) + print(test.topKFrequent(s, 5)) diff --git a/dataStructure/binaryTree.py b/dataStructure/binaryTree.py index b3cbb80..385cc84 100644 --- a/dataStructure/binaryTree.py +++ b/dataStructure/binaryTree.py @@ -12,61 +12,86 @@ from functools import total_ordering + @total_ordering class node: - def __init__(self,val,left=None,right=None,freq = 1): - self.val=val - self.left=left - self.right=right + def __init__(self, val, left=None, right=None, freq=1): + self.val = val + self.left = left + self.right = right self.freq = freq - def __lt__(self,nd): - return self.valnewNode: - if nd.left is None:nd.left = newNode - else : _add(nd.left,newNode) - else:nd.freq +=1 - _add(self.root,node(val)) - def find(self,val): - prt= self._findPrt(self.root,node(val),None) - if prt.left and prt.left.val==val: + self.root = None + + def add(self, val): + def _add(nd, newNode): + if nd < newNode: + if nd.right is None: + nd.right = newNode + else: + _add(nd.right, newNode) + elif nd > newNode: + if nd.left is None: + nd.left = newNode + else: + _add(nd.left, newNode) + else: + nd.freq += 1 + _add(self.root, node(val)) + + def find(self, val): + prt = self._findPrt(self.root, node(val), None) + if prt.left and prt.left.val == val: return prt.left - elif prt.right and prt.right.val==val:return prt.right - else :return None - def _findPrt(self,nd,tgt,prt): - if nd==tgt or nd is None:return prt - elif nd ''' return self.key == it.key + def __bool__(self): return self.key is not None + def __str__(self): li = [] nd = self @@ -29,27 +34,33 @@ class item: li.append(f'({nd.key}:{nd.val})') nd = nd.next return ' -> '.join(li) + def __repr__(self): return f'item({self.key},{self.val})' + + class hashTable: - def __init__(self,size=100): + def __init__(self, size=100): self.size = size - self.slots=[item(None,None) for i in range(self.size)] - def __setitem__(self,key,val): + self.slots = [item(None, None) for i in range(self.size)] + + def __setitem__(self, key, val): nd = self.slots[self.myhash(key)] while nd.next: - if nd.key ==key: - if nd.val!=val: nd.val=val + if nd.key == key: + if nd.val != val: + nd.val = val return - nd = nd.next - nd.next = item(key,val) + nd = nd.next + nd.next = item(key, val) - def myhash(self,key): - if isinstance(key,str): + def myhash(self, key): + if isinstance(key, str): key = sum(ord(i) for i in key) - if not isinstance(key,int): + if not isinstance(key, int): key = hash(key) return key % self.size + def __iter__(self): '''when using keyword , such as ' if key in dic', the dic's __iter__ method will be called,(if hasn't, calls __getitem__ @@ -57,18 +68,20 @@ class hashTable: ''' for nd in self.slots: nd = nd.next - while nd : + while nd: yield nd.key nd = nd.next - def __getitem__(self,key): - nd =self.slots[ self.myhash(key)].next + + def __getitem__(self, key): + nd = self.slots[self.myhash(key)].next while nd: - if nd.key==key: + if nd.key == key: return nd.val nd = nd.next - raise Exception(f'[KeyError]: {self.__class__.__name__} has no key {key}') + raise Exception( + f'[KeyError]: {self.__class__.__name__} has no key {key}') - def __delitem__(self,key): + def __delitem__(self, key): '''note that None item and item(None,None) differ with each other, which means you should take care of them and correctly cop with None item especially when deleting items @@ -77,31 +90,34 @@ class hashTable: nd = self.slots[n].next if nd.key == key: if nd.next is None: - self.slots[n] = item(None,None) # be careful - else:self.slots[n] = nd.next + self.slots[n] = item(None, None) # be careful + else: + self.slots[n] = nd.next return while nd: - if nd.next is None: break # necessary - if nd.next.key ==key: + if nd.next is None: + break # necessary + if nd.next.key == key: nd.next = nd.next.next nd = nd.next + def __str__(self): li = ['\n\n'+'-'*5+'hashTable'+'-'*5] - for i,nd in enumerate(self.slots): + for i, nd in enumerate(self.slots): li.append(f'{i}: '+str(nd.next)) return '\n'.join(li) - -if __name__ =='__main__': + +if __name__ == '__main__': from random import randint dic = hashTable(16) n = 100 - li = [1,2,5,40,324,123,6,22,18,34,50] + li = [1, 2, 5, 40, 324, 123, 6, 22, 18, 34, 50] print(f'build hashTable using {li}') for i in li: dic[i] = '$'+str(i) print(dic) - for i in [1,34,45,123]: + for i in [1, 34, 45, 123]: if i in dic: print(f'{i} in dic, deleting it') del dic[i] diff --git a/dataStructure/huffman/huffman.cc b/dataStructure/huffman/huffman.cc index 8a8b817..9cdfa48 100644 --- a/dataStructure/huffman/huffman.cc +++ b/dataStructure/huffman/huffman.cc @@ -28,348 +28,437 @@ using namespace std; void cat(string s) { - FILE* f=fopen(s.c_str(),"rb"); - cout<<"file content"< -void mapprint(map &f) +void mapprint(map &f) { - for(class map::iterator i = f.begin();i!=f.end();++i) - cout<first<<") : "<second<::iterator i = f.begin(); i != f.end(); ++i) + cout << i->first << ") : " << i->second << endl; } -template +template class node { - public: +public: ky key; wt val; bool visited; - node * left,*right; - node(const node &a){val = a.val;key= a.key;visited = a.visited;left= a.left;right=a.right;} - node(ky k=0,wt v=0):key(k),val(v),visited(false),left(NULL),right(NULL){}; - bool operator<(const node & a)const{return val>a.val;}; + node * left, *right; + node(const node &a) + { + val = a.val; + key = a.key; + visited = a.visited; + left = a.left; + right = a.right; + } + node(ky k = 0, wt v = 0): key(k), val(v), visited(false), left(NULL), right(NULL) {}; + bool operator<(const node & a)const + { + return val > a.val; + }; }; -template +template class huffman { private: - node root; + node root; string res; public: - long total(){return root.val;} - map encode_map; - map decode_map; - huffman(map& mp); + long total() + { + return root.val; + } + map encode_map; + map decode_map; + huffman(map& mp); void display(); - string encode(string,long &); - string decode(string,long&); - void preOrder(node*,string); + string encode(string, long &); + string decode(string, long&); + void preOrder(node*, string); }; -template -huffman::huffman(map& mp) +template +huffman::huffman(map& mp) { - if(mp.empty()){ - cout<<"Error! No data!"< > hp; - for(typename map::iterator i=mp.begin();i!=mp.end();++i){ - hp.push( node(i->first,i->second)); + + priority_queue > hp; + + for (typename map::iterator i = mp.begin(); i != mp.end(); ++i) { + hp.push(node(i->first, i->second)); } - int n =hp.size(); - if(n==1){ + + int n = hp.size(); + + if (n == 1) { root = hp.top(); return; } - while(--n>=1){ - node *a = new node(hp.top()); + + while (--n >= 1) { + node *a = new node(hp.top()); hp.pop(); - node *b = new node(hp.top()); + node *b = new node(hp.top()); hp.pop(); - node * tmp = new node(0,a->val+b->val); - tmp->left = a,tmp->right = b; + node * tmp = new node(0, a->val + b->val); + tmp->left = a, tmp->right = b; hp.push(*tmp); } + root = hp.top(); - preOrder(&root,string()); + preOrder(&root, string()); } -template -void huffman::preOrder(node* nd,string s) +template +void huffman::preOrder(node* nd, string s) { - if(nd->left == NULL){ - encode_map[nd->key] =s; + if (nd->left == NULL) { + encode_map[nd->key] = s; decode_map[s] = nd->key; delete nd; return ; } - preOrder(nd->left,s+'0'); - preOrder(nd->right,s+'1'); + + preOrder(nd->left, s + '0'); + preOrder(nd->right, s + '1'); delete nd; } -template -string huffman::decode(string zipfile_name,long &charNum) +template +string huffman::decode(string zipfile_name, long &charNum) { string uniFileName(string); - FILE * src = fopen(zipfile_name.c_str(),"rb"); + FILE * src = fopen(zipfile_name.c_str(), "rb"); char file_name[nameLength]; - fgets(file_name,nameLength,src); - int ct=-1; - while(file_name[++ct]!='\n'); + fgets(file_name, nameLength, src); + int ct = -1; + + while (file_name[++ct] != '\n'); + int pos = zipfile_name.find('.'); - if(pos==string::npos)pos=zipfile_name.size(); - string name(zipfile_name.substr(0,pos)) ,suffix(file_name,file_name+ct),file(name+suffix); - file=uniFileName(file); - cout<<"extracting compressed file :"< -string huffman::encode(string file_name,long &charNum) +template +string huffman::encode(string file_name, long &charNum) { - charNum=0; + charNum = 0; string uniFileName(string); - int pos =file_name.rfind('.'); - if(pos==string::npos)pos=file_name.size(); - string zipfile = file_name.substr(0,pos)+string(".zzip"); + int pos = file_name.rfind('.'); + + if (pos == string::npos)pos = file_name.size(); + + string zipfile = file_name.substr(0, pos) + string(".zzip"); zipfile = uniFileName(zipfile); - cout<<"generating zip file :"<::iterator i=decode_map.begin();i!=decode_map.end() ;++i ){ + + for (class map::iterator i = decode_map.begin(); i != decode_map.end() ; ++i) { data.append((i->first)); data.append(" "); - data+=(i->second); + data += (i->second); } + int data_size = data.size(); // calculate the size of the code_data char sz[numDigit]; - snprintf(sz,numDigit,"%d",data_size); - int ct=0; - for(;sz[ct];++ct)fputc(sz[ct],dst); - fputc('\n',dst); - fwrite(data.c_str(),data_size,1,dst); - int sum=0,digit=0,num; + snprintf(sz, numDigit, "%d", data_size); + int ct = 0; + + for (; sz[ct]; ++ct)fputc(sz[ct], dst); + + fputc('\n', dst); + fwrite(data.c_str(), data_size, 1, dst); + int sum = 0, digit = 0, num; string code8; - for(int i=0;i -void huffman::display() +template +void huffman::display() { - cout<<"the encoding map,huffman codes are as bellow:"<::iterator i=encode_map.begin();i!=encode_map.end() ;++i ) - cout<first<<"("<<(int)i->first<<"):"<second<::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 &origin,vector &compressed) +bool handle_one(string file_name, vector &origin, vector &compressed) { int name_length = file_name.size(); - FILE *src=fopen(file_name.c_str(),"rb"); - cout<<"opening "< mp; - while(!feof(src)){ - fread(&cur,sizeof(char),1,src); - if(mp.count(cur)){ - mp[cur]+=1; - } - else mp[cur]=1; + map mp; + + while (!feof(src)) { + fread(&cur, sizeof(char), 1, src); + + if (mp.count(cur)) { + mp[cur] += 1; + } else mp[cur] = 1; } + fclose(src); - huffman hf(mp); + huffman hf(mp); long sz; - string s(hf.encode(file_name,sz)); - origin.push_back(hf.total()),compressed.push_back(sz); - cout<<"\ncontinue to uncompress? [Y/n]"<& v) +void splitToVec(char * s, vector& v) { - int i=0,last=0; - for(;s[i];++i){ - if(isSep(s[i])){ - v.push_back(string(s+last,s+i)); - while(s[++i]&&isSep(s[i])); - last=i; + int i = 0, last = 0; + + for (; s[i]; ++i) { + if (isSep(s[i])) { + v.push_back(string(s + last, s + i)); + + while (s[++i] && isSep(s[i])); + + last = i; } } - if(s[last])v.push_back(string(s+last,s+i)); + + if (s[last])v.push_back(string(s + last, s + i)); } -bool lenStr(string &a,string &b) +bool lenStr(string &a, string &b) { - return a.size() & names) { - vector originSize,compressedSize; + vector originSize, compressedSize; vector deltaTime; double last; vector indicator; bool bl; - for(vector::iterator i=names.begin();i!=names.end();++i){ + + for (vector::iterator i = names.begin(); i != names.end(); ++i) { struct timeval tv; - gettimeofday(&tv,NULL); - last=tv.tv_sec; - bl=handle_one(*i,originSize,compressedSize); + gettimeofday(&tv, NULL); + last = tv.tv_sec; + bl = handle_one(*i, originSize, compressedSize); indicator.push_back(bl); - gettimeofday(&tv,NULL); - deltaTime.push_back(tv.tv_sec-last); + gettimeofday(&tv, NULL); + deltaTime.push_back(tv.tv_sec - last); } - cout<<"\nDealt file number "<::iterator p=max_element(names.begin(),names.end(),lenStr); - int len = p->size()+2; - for(int i =0;i::iterator p = max_element(names.begin(), names.end(), lenStr); + int len = p->size() + 2; + + for (int i = 0; i < names.size(); ++i) { + if (! indicator[i]) { + continue; + } + + cout << names[i] << string(len - names[i].size(), ' '); + cout << deltaTime[i] << "s " << compressedSize[i] / 1024.0 << "KB/" << originSize[i] / 1024.0 << "KB :"; + cout << compressedSize[i] * 100.0 / originSize[i] << "%" << endl; } - cout< names; - string file; - if(argv>1){ - for(int i=1;i 1) { + for (int i = 1; i < argv; ++i) { names.push_back(argc[i]); } + go(names); names.clear(); } + char mk; - while(1){ + + while (1) { char s[201]; - cout<<"Input file names separated by space "< bool: self.vals.append(val) @@ -27,32 +28,35 @@ class RandomizedCollection: else: self.index[val] = {len(self.vals)-1} return True + def removeAll(self, val: int) -> bool: if val not in self.index: return False begin = end = len(self.vals)-len(self.index[val]) - for idx in self.index.pop(val): - if idx int: if self.vals: - return self.vals[random.randint(0,len(self.vals)-1)] + return self.vals[random.randint(0, len(self.vals)-1)] diff --git a/dataStructure/intervalTree.py b/dataStructure/intervalTree.py index adafe28..9b24917 100644 --- a/dataStructure/intervalTree.py +++ b/dataStructure/intervalTree.py @@ -9,60 +9,80 @@ # Description: ######################################################################### ''' +from random import randint, shuffle from redBlackTree import redBlackTree from functools import total_ordering + @total_ordering class node: - def __init__(self,low,high,left=None,right=None,isBlack=False): - self.val = low # self.val is the low + def __init__(self, low, high, left=None, right=None, isBlack=False): + self.val = low # self.val is the low self.high = high self.max = high self.left = left self.right = right - self.parent=None + self.parent = None self.isBlack = isBlack - def __lt__(self,nd): + + def __lt__(self, nd): return self.val < nd.val - def __eq__(self,nd): + + def __eq__(self, nd): return nd is not None and self.val == nd.val - def setChild(self,nd,isLeft = True): - if isLeft: self.left = nd - else: self.right = nd - if nd is not None: nd.parent = self - def getChild(self,isLeft): - if isLeft: return self.left - else: return self.right + + def setChild(self, nd, isLeft=True): + if isLeft: + self.left = nd + else: + self.right = nd + if nd is not None: + nd.parent = self + + def getChild(self, isLeft): + if isLeft: + return self.left + else: + return self.right + def __bool__(self): return self.val is not None + def __str__(self): color = 'B' if self.isBlack else 'R' return f'{color}[{self.val},{self.high}]-{self.max}' + def __repr__(self): return f'intervalNode({self.val},{self.high},{self.max},isBlack={self.isBlack})' - def overlap(self,low,high): - return self.val<=high and self.high>=low + + def overlap(self, low, high): + return self.val <= high and self.high >= low + def setMax(self): l = 0 if self.left is None else self.left.max r = 0 if self.right is None else self.right.max self.max = max(self.high, l, r) return self.max + class intervalTree(redBlackTree): - def search(self,low,high): + def search(self, low, high): nd = self.root - while nd is not None and not nd.overlap(low,high): - if nd.left is not None and nd.left.max>=low: + while nd is not None and not nd.overlap(low, high): + if nd.left is not None and nd.left.max >= low: nd = nd.left - else:nd = nd.right + else: + nd = nd.right return nd - def insert(self,nd): - super(intervalTree,self).insert(nd) + + def insert(self, nd): + super(intervalTree, self).insert(nd) while nd is not None: nd.setMax() nd = nd.parent - def delete(self,val): + + def delete(self, val): nd = self.find(val) if nd is not None: nd.max = 0 @@ -70,56 +90,61 @@ class intervalTree(redBlackTree): while tmp is not None: tmp.setMax() tmp = tmp.parent - super(intervalTree,self).delete(val) - def rotate(self,prt,chd): + super(intervalTree, self).delete(val) + + def rotate(self, prt, chd): '''rotate prt, and return new prt, namyly the original chd''' - super(intervalTree,self).rotate(prt,chd) + super(intervalTree, self).rotate(prt, chd) prt.setMax() chd.setMax() - def copyNode(self,src,des): + + def copyNode(self, src, des): des.val = src.val des.high = src.high des.setMax() - -from random import randint, shuffle -def genNum(n =10,upper=10): - nums ={} +def genNum(n=10, upper=10): + nums = {} for i in range(n): while 1: - d = randint(0,100) + d = randint(0, 100) if d not in nums: - nums[d] = (d,randint(d,d+upper)) + nums[d] = (d, randint(d, d+upper)) break return nums.values() -def buildTree(n=10,nums=None,visitor=None): + +def buildTree(n=10, nums=None, visitor=None): #if nums is None or nums ==[]: nums = genNum(n) tree = intervalTree() print(f'build a red-black tree using {nums}') for i in nums: tree.insert(node(*i)) if visitor: - visitor(tree,i) - return tree,nums + visitor(tree, i) + return tree, nums + + def testInsert(nums=None): - def visitor(t,val): + def visitor(t, val): print('inserting', val) print(t) - tree,nums = buildTree(visitor = visitor,nums=nums) - print('-'*5+ 'in-order visit' + '-'*5) - for i,j in enumerate(tree.sort()): + tree, nums = buildTree(visitor=visitor, nums=nums) + print('-'*5 + 'in-order visit' + '-'*5) + for i, j in enumerate(tree.sort()): print(f'{i+1}: {j}') return tree + def testSuc(nums=None): - tree,nums = buildTree(nums=nums) + tree, nums = buildTree(nums=nums) for i in tree.sort(): print(f'{i}\'s suc is {tree.getSuccessor(i)}') + def testDelete(nums=None): - tree,nums = buildTree(nums = nums) + tree, nums = buildTree(nums=nums) print(tree) for i in nums: print(f'deleting {i}') @@ -127,14 +152,16 @@ def testDelete(nums=None): print(tree) return tree -if __name__=='__main__': - lst = [(0,3),(5,8),(6,10),(26,26),(25,30),(8,9),(19,20),(15,23),(16,21),(17,19)] + +if __name__ == '__main__': + lst = [(0, 3), (5, 8), (6, 10), (26, 26), (25, 30), + (8, 9), (19, 20), (15, 23), (16, 21), (17, 19)] #lst = None - #testSuc(lst) + # testSuc(lst) tree = testInsert(lst) #tree,_= buildTree(lst) while 1: - a =int( input('low:')) - b =int( input('high:')) - res = tree.search(a,b) + a = int(input('low:')) + b = int(input('high:')) + res = tree.search(a, b) print(res) diff --git a/dataStructure/leftHeap.py b/dataStructure/leftHeap.py index a717839..2119049 100644 --- a/dataStructure/leftHeap.py +++ b/dataStructure/leftHeap.py @@ -11,108 +11,137 @@ ''' from functools import total_ordering -@total_ordering + +@total_ordering class node: - def __init__(self,val,freq=1,s=1,left=None,right=None): - self.val=val - self.freq=freq - self.s=s + def __init__(self, val, freq=1, s=1, left=None, right=None): + self.val = val + self.freq = freq + self.s = s if left is None or right is None: self.left = left if left is not None else right - self.right =None + self.right = None else: - if left.s int - if root is None:return t - if t is None:return root - if root int + if root is None: + return t + if t is None: + return root + if root < t: + root, t = t, root + root.right = leftHeap._merge(root.right, t) if root.left is None or root.right is None: - root.s=1 + root.s = 1 if root.left is None: - root.left,root.right = root.right,None + root.left, root.right = root.right, None else: - if root.left.s bool isZero(float a) { - return a<0.00001&&-a<0.00001; + return a < 0.00001 && -a < 0.00001; } -template class map; - //notice that if you declare a class template,declare the class first like this. -template +template class map; +//notice that if you declare a class template,declare the class first like this. +template class pair { - friend class map; - pair *next; - public: + friend class map; + pair *next; +public: t1 first; t2 second; }; -template +template class map { int n; - pair head; + pair head; int cur; - pair *last_visit; - public: + pair *last_visit; +public: map(); ~map(); bool has(t1); void erase(t1); t2& operator[](t1); - pair &locate(int index = -1); + pair &locate(int index = -1); int size(); }; -template -map::map(){ - n=0; - cur=-1; - last_visit= &head; - head.next=NULL; +template +map::map() +{ + n = 0; + cur = -1; + last_visit = &head; + head.next = NULL; head.first = head.second = 0; } -template -map::~map() +template +map::~map() { - pair *p,*q=&head; - while(q!=NULL){ - p=q->next; + pair *p, *q = &head; + + while (q != NULL) { + p = q->next; delete q; - q=p; + q = p; } } -template -bool map::has(t1 key) +template +bool map::has(t1 key) { - pair *p = head.next; - for(int i = 0;ifirst<=key;++i){ - if(isZero(p->first-key)) return 1; - p=p->next; + pair *p = head.next; + + for (int i = 0; i < n && p->first <= key; ++i) { + if (isZero(p->first - key)) return 1; + + p = p->next; } + return 0; } -template -pair& map::locate(int index) +template +pair& map::locate(int index) { - if(index>=n||index<0){ + if (index >= n || index < 0) { printf("the index is out of range\n"); return head; } - if(cur>index){ + + if (cur > index) { last_visit = &head; cur = -1; } - while(curnext; ++cur; } + return *last_visit; } -template -int map::size() +template +int map::size() { return n; } -template -t2& map::operator[](t1 key) +template +t2& map::operator[](t1 key) { - pair * p=&head; - while(p->next!=NULL){ - if(isZero(p->next->first-key)) return p->next->second; - else if(p->next->first>key){break;} - p=p->next; + pair * p = &head; + + while (p->next != NULL) { + if (isZero(p->next->first - key)) return p->next->second; + else if (p->next->first > key) { + break; + } + + p = p->next; } - cur=-1; - last_visit= &head; - pair *tmp = new pair; + + cur = -1; + last_visit = &head; + pair *tmp = new pair; tmp ->next = p->next; tmp->first = key; p->next = tmp; ++n; return tmp->second; } -template -void map::erase(t1 key) +template +void map::erase(t1 key) { - pair *p = &head; - while(p->next!=NULL){ - if(isZero(p->next->first-key)){ - pair *q = p->next; + pair *p = &head; + + while (p->next != NULL) { + if (isZero(p->next->first - key)) { + pair *q = p->next; p->next = p->next->next; delete q; --n; break; } - p=p->next; + + p = p->next; } - cur=-1; - last_visit= &head; + + cur = -1; + last_visit = &head; } int main() { - map b; - for(int i = 0;i<40;++i){ + map b; + + for (int i = 0; i < 40; ++i) { b[i] = i; - if(i%3){ + + if (i % 3) { b[i] = 1; } - if(i%2){ + + if (i % 2) { b.erase(i); } + } + for (int i = 0; i < b.size(); ++i) { + printf("item %d %g:%g\n", i, b.locate(i).first, b.locate(i).second); } - for(int i = 0;i +#include #include #include #include @@ -19,16 +19,17 @@ using namespace std; #if defined(__linux__) - #define LINUX true +#define LINUX true #elif defined(_WIN32) - #define LINUX false +#define LINUX false #endif bool isZero(double a) { - if((a<0.00001)&&-a<0.00001) + if ((a < 0.00001) && -a < 0.00001) return true; + return false; } class node @@ -42,9 +43,9 @@ class polynomial int SIZE; int n; node* p; - public: - polynomial(int sz=50); - polynomial(const polynomial & ); +public: + polynomial(int sz = 50); + polynomial(const polynomial &); ~polynomial(); double cal(double); void getData(); @@ -54,10 +55,10 @@ class polynomial polynomial operator-(const polynomial &); polynomial operator*(const polynomial &); }; -polynomial::polynomial(int sz):n(0),SIZE(sz) +polynomial::polynomial(int sz): n(0), SIZE(sz) { p = (node*) new node[SIZE]; - memset(p,0,sizeof(p)); + memset(p, 0, sizeof(p)); } polynomial::~polynomial() { @@ -65,18 +66,21 @@ polynomial::~polynomial() } double polynomial::cal(double x) { - double rst=0; - for(int i =0;i=0;--i){ + + // char *fmt = ("x"); printf(fmt,...); + for (int i = n - 1; i >= 0; --i) { double t = tmp[i].coefficient; double idx = tmp[i].index; - if(isZero(idx)){ - printf("%+g",t); + + if (isZero(idx)) { + printf("%+g", t); continue; } - if(isZero(t-1)) printf("+"); - else if(isZero(t+1))printf("-"); - else printf("%+g",t); + + if (isZero(t - 1)) printf("+"); + else if (isZero(t + 1))printf("-"); + else printf("%+g", t); + printf("x"); - if(!isZero(idx-1)) printf("^%g",idx); + + if (!isZero(idx - 1)) printf("^%g", idx); } + printf("\n"); } void polynomial::getData() { printf("Please input data . \n"); printf("For every item,Coefficient first .Use space to separate,EOF to end\n"); - map mp; + map mp; double idx; double coef; - while(scanf("%lf%lf",&coef,&idx)!=EOF){ - if(isZero(coef)) continue; - if(mp.count(idx) == 0){ + + while (scanf("%lf%lf", &coef, &idx) != EOF) { + if (isZero(coef)) continue; + + if (mp.count(idx) == 0) { mp[idx] = coef; - } - else{ + } else { mp[idx] += coef; - if(isZero(mp[idx])){ + + if (isZero(mp[idx])) { mp.erase(idx); } } } - if(mp.size()>SIZE){ - SIZE *=2; - p = (node*)realloc(p,sizeof(node)*SIZE) ; + + if (mp.size() > SIZE) { + SIZE *= 2; + p = (node*)realloc(p, sizeof(node) * SIZE) ; } - for(map::iterator it = mp.begin();it!=mp.end();++it){ + + for (map::iterator it = mp.begin(); it != mp.end(); ++it) { p[n].index = it->first; p[n++].coefficient = it->second; } @@ -144,48 +161,52 @@ void polynomial::getData() polynomial polynomial::operator+(const polynomial & a) { polynomial rst ; - int p1 = 0,p2 = 0,p3 = 0; + int p1 = 0, p2 = 0, p3 = 0; double exp1 = p[p1].index; double exp2 = a.p[p2].index; - while(p1exp2){ - rst.p[p3].index = exp2; - rst.p[p3].coefficient = a.p[p2].coefficient; - ++p2,++p3; - exp2 = a.p[p2].index;; + + while (p2 < a.n && exp1 > exp2) { + rst.p[p3].index = exp2; + rst.p[p3].coefficient = a.p[p2].coefficient; + ++p2, ++p3; + exp2 = a.p[p2].index;; } - if(isZero(exp1-exp2)){ - double tmp= p[p1].coefficient + a.p[p2].coefficient; - if(isZero(tmp)){ - ++p1,++p2; - } - else{ + + if (isZero(exp1 - exp2)) { + double tmp = p[p1].coefficient + a.p[p2].coefficient; + + if (isZero(tmp)) { + ++p1, ++p2; + } else { rst.p[p3].index = p[p1].index; rst.p[p3].coefficient = tmp; - ++p1,++p2,++p3; + ++p1, ++p2, ++p3; } } } - if(p1 == n){ - while(p2 mp; - for(int i = 0;i mp; + + for (int i = 0; i < n; ++i) { double idx = p[i].index; double coef = p[i].coefficient; - for(int j = 0;jsz){ - sz *=2; + + int sz = 50; + + while (mp.size() > sz) { + sz *= 2; } + polynomial rst(sz); - for(map::iterator it = mp.begin();it!=mp.end();++it){ + + for (map::iterator it = mp.begin(); it != mp.end(); ++it) { rst.p[rst.n].index = it->first; rst.p[rst.n++].coefficient = it->second; } + return rst; } int num = 0; @@ -250,94 +281,94 @@ void menu() void loop() { int op; - while(scanf("%d",&op)!=EOF){ - if(op == 0){ - pl[num].getData(); - ++num; - printf("You've created polynomial %d:\n",num); - pl[num-1].display(); + + while (scanf("%d", &op) != EOF) { + if (op == 0) { + pl[num].getData(); + ++num; + printf("You've created polynomial %d:\n", num); + pl[num - 1].display(); + } else if (op == 1 || op == 2 || op == 3) { + if (num < 2) { + printf("Oops! you've got less two polynomial\nPlease choose another operation\n"); + continue; } - else if(op==1||op==2||op==3){ - if(num<2){ - printf("Oops! you've got less two polynomial\nPlease choose another operation\n"); - continue; - } - printf("input two nums of the two polynomial to be operated.eg: 1 2\n"); - int t1=100,t2=100; - while(1){ - scanf("%d%d",&t1,&t2); - if(t1>num||t2>num||t1<0||t2<0){ - printf("wrong num ,please input again\n"); - } - else break; - } - printf("the rst is:\n"); - t1 -=1,t2-=1; - if(op == 1){ - (pl[t1]+pl[t2]).display(); - } - else if(op == 2){ - (pl[t1]-pl[t2]).display(); - } - else (pl[t1]*pl[t2]).display(); + + printf("input two nums of the two polynomial to be operated.eg: 1 2\n"); + int t1 = 100, t2 = 100; + + while (1) { + scanf("%d%d", &t1, &t2); + + if (t1 > num || t2 > num || t1 < 0 || t2 < 0) { + printf("wrong num ,please input again\n"); + } else break; } - else if(op == 4){ - printf("input a polynomial's num to display it\n"); - int tmp; - scanf("%d",&tmp); - if(tmp>num){ - printf("wrong num"); - } - else{ - printf("info of polynomial %d\n",tmp); - pl[tmp-1].display(); - } + + printf("the rst is:\n"); + t1 -= 1, t2 -= 1; + + if (op == 1) { + (pl[t1] + pl[t2]).display(); + } else if (op == 2) { + (pl[t1] - pl[t2]).display(); + } else (pl[t1]*pl[t2]).display(); + } else if (op == 4) { + printf("input a polynomial's num to display it\n"); + int tmp; + scanf("%d", &tmp); + + if (tmp > num) { + printf("wrong num"); + } else { + printf("info of polynomial %d\n", tmp); + pl[tmp - 1].display(); } - else if(op == 9){ - for(int i = 0;i num || t < 0) { + printf("wrong num\n"); + } else { + printf("input a value\n"); + scanf("%lf", &x); + pl[t - 1].display(); + printf("%g\n", pl[t - 1].cal(x)); } - else if(op == 6){ - if(LINUX) system("clear"); - else system("cls"); - menu(); + } else if (op == 8) { + if (num == 0) { + printf("you have'nt any polynomial tp copy\n"); + continue; } - else if(op == 10){ - double x; - int t; - printf("choose a polynomial\n"); - scanf("%d",&t); - if(t>num||t<0){ - printf("wrong num\n"); - } - else { - printf("input a value\n"); - scanf("%lf",&x); - pl[t-1].display(); - printf("%g\n",pl[t-1].cal(x)); - } + + int n = num + 1; + + while (n > num) { + printf("input the number of an existing polynomial you want to copy\n"); + scanf("%d", &n); } - else if(op == 8){ - if(num == 0){ - printf("you have'nt any polynomial tp copy\n"); - continue; - } - int n = num+1; - while(n>num){ - printf("input the number of an existing polynomial you want to copy\n"); - scanf("%d",&n); - } - (pl[num] = pl[n-1]); - printf("You've copyed this polynomial:\n"); - pl[num++].display(); - } - else exit(0); - printf("select an operation\n"); + + (pl[num] = pl[n - 1]); + printf("You've copyed this polynomial:\n"); + pl[num++].display(); + } else exit(0); + + printf("select an operation\n"); } } int main(void) diff --git a/dataStructure/polynomial.py b/dataStructure/polynomial.py index 74bbdfb..a8f0384 100644 --- a/dataStructure/polynomial.py +++ b/dataStructure/polynomial.py @@ -11,61 +11,71 @@ ''' #!/bin/python3 -# notice that creating a class's initialization won't conflict with __call__ method +# notice that creating a class's initialization won't conflict with __call__ method # because the former call class ,and the latter call instance # to be implemented + class polynomial: - pls= [] + pls = [] n = 0 + def dictize(pl): - if isinstance(pl,int) or isinstance(pl,float): - pl = {0:pl} - if isinstance(pl,polynomial): + if isinstance(pl, int) or isinstance(pl, float): + pl = {0: pl} + if isinstance(pl, polynomial): pl = pl.polynomial.copy() return pl + def isZero(n): - return abs(n)<0.000001 - def __init__(self,s='0 0'): + return abs(n) < 0.000001 + + def __init__(self, s='0 0'): polynomial.pls.append(self) - polynomial.n +=1 - if isinstance(s,polynomial): - self.polynomial=s.polynomial.copy() - # don't write like this .**self.polynomial = s.polynomial**,it's ref + polynomial.n += 1 + if isinstance(s, polynomial): + self.polynomial = s.polynomial.copy() + # don't write like this .**self.polynomial = s.polynomial**,it's ref return - elif isinstance(s,dict): + elif isinstance(s, dict): self.polynomial = s.copy() return - s= s.replace(',',' ') - s= s.replace('x',' ') - s= s.replace('x^',' ') - s = s.replace(':',' ') - s = s.replace('\n',' ') + s = s.replace(',', ' ') + s = s.replace('x', ' ') + s = s.replace('x^', ' ') + s = s.replace(':', ' ') + s = s.replace('\n', ' ') s = s.split(' ') num = len(s) i = 0 print(s) self.polynomial = dict() li = [float(i) for i in s] - while ival) - def getSuccessor(self,nd): + nd = nd.getChild(nd.val > val) + + def getSuccessor(self, nd): if nd: if nd.right: nd = nd.right @@ -76,18 +96,20 @@ class redBlackTree: while nd.parent is not None and nd.parent.right is nd: nd = nd.parent return None if nd is self.root else nd.parent - def rotate(self,prt,chd): - '''rotate prt with the center of chd''' + + def rotate(self, prt, chd): + '''rotate prt with the center of chd''' if self.root is prt: self.setRoot(chd) else: prt.parent.setChild(chd, prt.parent.left is prt) isLeftChd = prt.left is chd prt.setChild(chd.getChild(not isLeftChd), isLeftChd) - chd.setChild(prt,not isLeftChd) + chd.setChild(prt, not isLeftChd) - def insert(self,nd): - if nd.isBlack: nd.isBlack = False + def insert(self, nd): + if nd.isBlack: + nd.isBlack = False if self.root is None: self.setRoot(nd) @@ -95,16 +117,18 @@ class redBlackTree: else: parent = self.root while parent: - if parent == nd : return None + if parent == nd: + return None isLeft = parent > nd - chd = parent.getChild(isLeft) + chd = parent.getChild(isLeft) if chd is None: - parent.setChild(nd,isLeft) + parent.setChild(nd, isLeft) break else: parent = chd - self.fixUpInsert(parent,nd) - def fixUpInsert(self,parent,nd): + self.fixUpInsert(parent, nd) + + def fixUpInsert(self, parent, nd): ''' adjust color and level, there are two red nodes: the new one and its parent''' while not self.checkBlack(parent): grand = parent.parent @@ -125,8 +149,8 @@ class redBlackTree: # grand grand # parent or parent # nd nd - self.rotate(parent,nd) #parent rotate - nd,parent = parent,nd + self.rotate(parent, nd) # parent rotate + nd, parent = parent, nd # case 3 (case 2.2) the new node is inserted in left-left or right-right form # grand grand # parent or parent @@ -134,25 +158,29 @@ class redBlackTree: self.setBlack(grand, False) self.setBlack(parent, True) - self.rotate(grand,parent) - self.setBlack(self.root,True) + self.rotate(grand, parent) + self.setBlack(self.root, True) - def copyNode(self,src,des): + def copyNode(self, src, des): '''when deleting a node which has two kids, copy its succesor's data to his position data exclude left, right , isBlack ''' des.val = src.val - def delete(self,val): + + def delete(self, val): '''delete node in a binary search tree''' - if isinstance(val,node): val = val.val + if isinstance(val, node): + val = val.val nd = self.find(val) - if nd is None: return + if nd is None: + return self._delete(nd) - def _delete(self,nd): + + def _delete(self, nd): y = None if nd.left and nd.right: - y= self.getSuccessor(nd) + y = self.getSuccessor(nd) else: y = nd py = y.parent @@ -160,58 +188,60 @@ class redBlackTree: if py is None: self.setRoot(x) else: - py.setChild(x,py.left is y) + py.setChild(x, py.left is y) if y != nd: - self.copyNode(y,nd) - if self.checkBlack(y): self.fixUpDel(py,x) - - def fixUpDel(self,prt,chd): + self.copyNode(y, nd) + if self.checkBlack(y): + self.fixUpDel(py, x) + + def fixUpDel(self, prt, chd): ''' adjust colors and rotate ''' while self.root != chd and self.checkBlack(chd): - isLeft =prt.left is chd + isLeft = prt.left is chd brother = prt.getChild(not isLeft) # brother is black lb = self.checkBlack(brother.getChild(isLeft)) rb = self.checkBlack(brother.getChild(not isLeft)) - if not self.checkBlack(brother): + if not self.checkBlack(brother): # case 1: brother is red. converted to case 2,3,4 - self.setBlack(prt,False) - self.setBlack(brother,True) - self.rotate(prt,brother) + self.setBlack(prt, False) + self.setBlack(brother, True) + self.rotate(prt, brother) - elif lb and rb: - # case 2: brother is black and two kids are black. + elif lb and rb: + # case 2: brother is black and two kids are black. # conveted to the begin case - self.setBlack(brother,False) + self.setBlack(brother, False) chd = prt - prt= chd.parent + prt = chd.parent else: - if rb: + if rb: # case 3: brother is black and left kid is red and right child is black # rotate bro to make g w wl wr in one line # uncle's son is nephew, and niece for uncle's daughter nephew = brother.getChild(isLeft) - self.setBlack(nephew,True) - self.setBlack(brother,False) + self.setBlack(nephew, True) + self.setBlack(brother, False) # brother (not isLeft) rotate - self.rotate(brother,nephew) + self.rotate(brother, nephew) brother = nephew # case 4: brother is black and right child is red brother.isBlack = prt.isBlack - self.setBlack(prt,True) - self.setBlack(brother.getChild(not isLeft),True) + self.setBlack(prt, True) + self.setBlack(brother.getChild(not isLeft), True) - self.rotate(prt,brother) + self.rotate(prt, brother) chd = self.root - self.setBlack(chd,True) + self.setBlack(chd, True) - def sort(self,reverse = False): + def sort(self, reverse=False): ''' return a generator of sorted data''' def inOrder(root): - if root is None:return + if root is None: + return if reverse: yield from inOrder(root.right) else: @@ -225,8 +255,10 @@ class redBlackTree: def display(self): def getHeight(nd): - if nd is None:return 0 - return max(getHeight(nd.left),getHeight(nd.right)) +1 + if nd is None: + return 0 + return max(getHeight(nd.left), getHeight(nd.right)) + 1 + def levelVisit(root): from collections import deque lst = deque([root]) @@ -234,24 +266,26 @@ class redBlackTree: h = getHeight(root) ct = lv = 0 while 1: - ct+=1 + ct += 1 nd = lst.popleft() if ct >= 2**lv: - lv+=1 - if lv>h:break + lv += 1 + if lv > h: + break level.append([]) level[-1].append(str(nd)) if nd is not None: - lst += [nd.left,nd.right] + lst += [nd.left, nd.right] else: - lst +=[None,None] + lst += [None, None] return level + def addBlank(lines): width = 1+len(str(self.root)) sep = ' '*width n = len(lines) - for i,oneline in enumerate(lines): - k = 2**(n-i) -1 + for i, oneline in enumerate(lines): + k = 2**(n-i) - 1 new = [sep*((k-1)//2)] for s in oneline: new.append(s.ljust(width)) @@ -262,59 +296,67 @@ class redBlackTree: lines = levelVisit(self.root) lines = addBlank(lines) li = [''.join(line) for line in lines] - length = 10 if li==[] else max(len(i) for i in li)//2 - begin ='\n'+ 'red-black-tree'.rjust(length+14,'-') + '-'*(length) + length = 10 if li == [] else max(len(i) for i in li)//2 + begin = '\n' + 'red-black-tree'.rjust(length+14, '-') + '-'*(length) end = '-'*(length*2+14)+'\n' - return '\n'.join([begin,*li,end]) + return '\n'.join([begin, *li, end]) + def __str__(self): return self.display() -def genNum(n =10): - nums =[] +def genNum(n=10): + nums = [] for i in range(n): while 1: - d = randint(0,100) + d = randint(0, 100) if d not in nums: nums.append(d) break return nums -def buildTree(n=10,nums=None,visitor=None): - if nums is None or nums ==[]: nums = genNum(n) + +def buildTree(n=10, nums=None, visitor=None): + if nums is None or nums == []: + nums = genNum(n) rbtree = redBlackTree() print(f'build a red-black tree using {nums}') for i in nums: rbtree.insert(node(i)) print(rbtree) if visitor: - visitor(rbtree,i) - return rbtree,nums + visitor(rbtree, i) + return rbtree, nums + + def testInsert(nums=None): - def visitor(t,val): + def visitor(t, val): print('inserting', val) print(t) - rbtree,nums = buildTree(visitor = visitor,nums=nums) - print('-'*5+ 'in-order visit' + '-'*5) - for i,j in enumerate(rbtree.sort()): + rbtree, nums = buildTree(visitor=visitor, nums=nums) + print('-'*5 + 'in-order visit' + '-'*5) + for i, j in enumerate(rbtree.sort()): print(f'{i+1}: {j}') + def testSuc(nums=None): - rbtree,nums = buildTree(nums=nums) + rbtree, nums = buildTree(nums=nums) for i in rbtree.sort(): print(f'{i}\'s suc is {rbtree.getSuccessor(i)}') + def testDelete(nums=None): - rbtree,nums = buildTree(nums = nums) + rbtree, nums = buildTree(nums=nums) print(rbtree) for i in sorted(nums): print(f'deleting {i}') rbtree.delete(i) print(rbtree) -if __name__=='__main__': - lst =[45, 30, 64, 36, 95, 38, 76, 34, 50, 1] - lst = [0,3,5,6,26,25,8,19,15,16,17] - #testSuc(lst) - #testInsert(lst) + +if __name__ == '__main__': + lst = [45, 30, 64, 36, 95, 38, 76, 34, 50, 1] + lst = [0, 3, 5, 6, 26, 25, 8, 19, 15, 16, 17] + # testSuc(lst) + # testInsert(lst) testDelete() diff --git a/dataStructure/splayTree.py b/dataStructure/splayTree.py index 42be71b..5c4af4d 100644 --- a/dataStructure/splayTree.py +++ b/dataStructure/splayTree.py @@ -10,148 +10,190 @@ ######################################################################### ''' -from collections import deque,Iterable +from collections import deque, Iterable # use isinstance(obj,Iterable) to judge if an obj is iterable + + class node: - def __init__(self,val = None,left=None,right=None,parent=None): + def __init__(self, val=None, left=None, right=None, parent=None): self.val = val - if val :self.freq = 1 - else :self.freq = 0 + if val: + self.freq = 1 + else: + self.freq = 0 self.left = left self.right = right - self.parent = parent - def getChild(self,s=0): - if isinstance(s,int):s =[s] + self.parent = parent + + def getChild(self, s=0): + if isinstance(s, int): + s = [s] last = self for i in s: - if not last:return None - if i == 0: last = last.left - else:last = last.right + if not last: + return None + if i == 0: + last = last.left + else: + last = last.right return last - def setChild(self,child,s=0): - if isinstance(s,Iterable): + + def setChild(self, child, s=0): + if isinstance(s, Iterable): i = s[0] del s[0] - if i == 0:self.left.setChild(child,s) - else:self.right.setChild(child,s) - elif s:self.right = child - else:self.left = child + if i == 0: + self.left.setChild(child, s) + else: + self.right.setChild(child, s) + elif s: + self.right = child + else: + self.left = child + + class splayTree: - def __init__(self,s=[]): + def __init__(self, s=[]): s = list(s) self.root = None - s = sorted(s,reverse = True) + s = sorted(s, reverse=True) for i in s: - self.insert(self.root,i) - def insert(self,k): - if not self.root :self.root = node(k) - else:self._insert(self.root,k) - def _insert(self,root,k): - if root.val == k : - root.freq +=1 - elif root.val k: - return self._find(root.left,k) - elif root.valself.s else 2*p+self.lowExt-self.n+1 - def arrayToTree(self,i): - return (i+self.offset)//2 if i<=self.lowExt else (i-self.lowExt+ self.n-1)//2 - def win(self,a,b): - return ab - def initTree(self,p): - if p>=self.n: - delta = p%2 #!!! good job notice delta mark the lchild or rchlid + + def treeToArray(self, p): + return 2*p-self.offset if p > self.s else 2*p+self.lowExt-self.n+1 + + def arrayToTree(self, i): + return (i+self.offset)//2 if i <= self.lowExt else (i-self.lowExt + self.n-1)//2 + + def win(self, a, b): + return a < b if self.reverse else a > b + + def initTree(self, p): + if p >= self.n: + delta = p % 2 # !!! good job notice delta mark the lchild or rchlid return self.players[self.treeToArray(p//2)+delta] l = self.initTree(2*p) r = self.initTree(2*p+1) - self.tree[p] = l if self.win(l,r) else r + self.tree[p] = l if self.win(l, r) else r return self.tree[p] + def winner(self): idx = 1 - while 2*idxd2: + if minD > d2: minD = d2 - p,q = pts[1], pts[2] + p, q = pts[1], pts[2] d2 = pts[0].distance(pts[2]) - if minD>d2: return d2, pts[0],pts[2] - else : return minD, p,q + if minD > d2: + return d2, pts[0], pts[2] + else: + return minD, p, q n2 = n//2 - mid = (pts[n2].x +pts[n2-1].x)/2 + mid = (pts[n2].x + pts[n2-1].x)/2 s1 = pts[:n2] s2 = pts[n2:] - minD ,p,q = _min(s1) + minD, p, q = _min(s1) d2, p2, q2 = _min(s2) - #print('\n\n',minD,p,q,s1) - #print(d2,p2,q2,s2) - if minD> d2: - minD,p,q = d2, p2, q2 + # print('\n\n',minD,p,q,s1) + # print(d2,p2,q2,s2) + if minD > d2: + minD, p, q = d2, p2, q2 - linePoints = findif(s1,lambda pt:floatEql(pt.x,mid),reverse=True) - linePoints += findif(s2,lambda pt:floatEql(pt.x,mid)) + linePoints = findif(s1, lambda pt: floatEql(pt.x, mid), reverse=True) + linePoints += findif(s2, lambda pt: floatEql(pt.x, mid)) n = len(linePoints) - if n>1: - for i in range(1,n): - dis = linePoints[i].y -linePoints[i-1].y - if dis 1: + for i in range(1, n): + dis = linePoints[i].y - linePoints[i-1].y + if dis < minD: minD = dis - p,q = linePoints[i-1], linePoints[i] - leftPoints = findif(s1,lambda pt:pt.x>= mid-minD,reverse=True) - rightPoints = findif(s2,lambda pt:pt.x<= mid+minD) + p, q = linePoints[i-1], linePoints[i] + leftPoints = findif(s1, lambda pt: pt.x >= mid-minD, reverse=True) + rightPoints = findif(s2, lambda pt: pt.x <= mid+minD) for lp in leftPoints: - y1,y2 = lp.y-minD, lp.y+minD + y1, y2 = lp.y-minD, lp.y+minD for rp in rightPoints: - if y1< rp.y int: sm = sum(stones) ans = sm//2 dp = [0]*(ans+1) for x in stones: - for j in range(ans,x-1,-1): - dp[j] = max(dp[j],dp[j-x]+x) + for j in range(ans, x-1, -1): + dp[j] = max(dp[j], dp[j-x]+x) return sm-2*dp[ans] diff --git a/dynamicProgramming/lcs.py b/dynamicProgramming/lcs.py index a20f5e3..fe62a2a 100644 --- a/dynamicProgramming/lcs.py +++ b/dynamicProgramming/lcs.py @@ -10,41 +10,44 @@ ######################################################################### ''' -def lcs(a,b): + +def lcs(a, b): '''time: O(mn); space: O(mn)''' - m,n= len(a),len(b) + m, n = len(a), len(b) board = [[[] for i in range(n+1)] for i in range(m+1)] for i in range(m): for j in range(n): - if a[i]==b[j]: - board[i+1][j+1] =board[i][j]+[a[i]] + if a[i] == b[j]: + board[i+1][j+1] = board[i][j]+[a[i]] elif len(board[i][j+1]) < len(board[i+1][j]): board[i+1][j+1] = board[i+1][j] - else : + else: board[i+1][j+1] = board[i][1+j] return board[m][n] -def lcs2(a,b): + +def lcs2(a, b): '''time: O(mn); space: O(m)''' - m,n= len(a),len(b) + m, n = len(a), len(b) board = [[] for i in range(n+1)] for i in range(m): upperLevel = board[0].copy() for j in range(n): tmp = board[j+1].copy() - if a[i]==b[j]: + if a[i] == b[j]: board[j+1] = upperLevel+[a[i]] elif len(board[j+1]) < len(board[j]): - board[j+1] = board[j].copy() # copy is needed + board[j+1] = board[j].copy() # copy is needed upperLevel = tmp return board[n] -if __name__ =='__main__': + +if __name__ == '__main__': a = 'ABCBDAB' b = 'BDCABA' - print('s1:',a) - print('s2:',b) + print('s1:', a) + print('s2:', b) while 1: - print('lcs:',lcs2(a,b)) + print('lcs:', lcs2(a, b)) a = input('s1: ') b = input('s2: ') diff --git a/dynamicProgramming/max-len-of-repeated-subarray.py b/dynamicProgramming/max-len-of-repeated-subarray.py index 7ce0fcc..bac3800 100644 --- a/dynamicProgramming/max-len-of-repeated-subarray.py +++ b/dynamicProgramming/max-len-of-repeated-subarray.py @@ -11,11 +11,13 @@ 给两个整数数组 A 和 B ,返回两个数组中公共的、长度最长的子数组的长度。 ####################################################################### ''' -def findLength(A,B): - n,m = len(A),len(B) + + +def findLength(A, B): + n, m = len(A), len(B) dp = [[0]*(m+1) for i in range(n+1)] - for i in range(1,n+1): - for j in range(1,m+1): - if A[i-1]==B[j-1]: - dp[i][j]=dp[i-1][j-1]+1 + for i in range(1, n+1): + for j in range(1, m+1): + if A[i-1] == B[j-1]: + dp[i][j] = dp[i-1][j-1]+1 return max(max(row) for row in dp) diff --git a/dynamicProgramming/splitStripe.py b/dynamicProgramming/splitStripe.py index 455bb61..d1fe97c 100644 --- a/dynamicProgramming/splitStripe.py +++ b/dynamicProgramming/splitStripe.py @@ -16,33 +16,36 @@ then find the maximum price to split the stripe in different shorter stripes ( including the original length if possible) ''' - -def count(n,prices): - def best(cur): + + +def count(n, prices): + def best(cur): # note that copying the list or create a new list in the following new_stripes codes - if cur in values: return values[cur],stripes[cur] + if cur in values: + return values[cur], stripes[cur] maxPrice = 0 - new_stripes=[] - for i,j in prices.items(): - if i<=cur: + new_stripes = [] + for i, j in prices.items(): + if i <= cur: p, tmp = best(cur-i) - if maxPrice st; - Node *cloneGraph(Node *node){ - Node* ret = new Node(node->val,vector()); - st[node]=ret; - for(auto x:node->neighbors){ + map st; + Node *cloneGraph(Node *node) + { + Node* ret = new Node(node->val, vector()); + st[node] = ret; + + for (auto x : node->neighbors) { auto p = st.find(x); - if(p==st.end()){ + + if (p == st.end()) { ret->neighbors.push_back(cloneGraph(x)); - }else ret->neighbors.push_back(p->second); + } else ret->neighbors.push_back(p->second); } + return ret; } }; diff --git a/graph/dfs.py b/graph/dfs.py index 6f45a84..65ebeb0 100644 --- a/graph/dfs.py +++ b/graph/dfs.py @@ -20,36 +20,37 @@ ####################################################################### ''' + class Solution: def longestStrChain(self, words: List[str]) -> int: - def isAdj(s1,s2): - if len(s1)>len(s2): - s1,s2 = s2,s1 - n1,n2 = len(s1),len(s2) - if n2-n1!=1: + def isAdj(s1, s2): + if len(s1) > len(s2): + s1, s2 = s2, s1 + n1, n2 = len(s1), len(s2) + if n2-n1 != 1: return False - i=j=0 + i = j = 0 flag = False - while i>=1 - a*=a + if n % 2: + rst *= a + n >>= 1 + a *= a return rst -def fastMul(a,b): + +def fastMul(a, b): '''a*b''' rst = 0 while b: - if b&1: - rst +=a - b>>=1 - a*=2 + if b & 1: + rst += a + b >>= 1 + a *= 2 diff --git a/math/fibonacci/fibonacci.py b/math/fibonacci/fibonacci.py index 467d084..9660934 100644 --- a/math/fibonacci/fibonacci.py +++ b/math/fibonacci/fibonacci.py @@ -11,27 +11,31 @@ ####################################################################### ''' + def fib(n): - """Calculates the nth Fibonacci number""" - mat,p = (1,1,1,0),n-2 - if n<=0: # for negative fib item, use f(n) = f(n+2)-f(n-1) to calculate - mat = (0,1,1,-1),2-n - li = matrix_pow((0,1,1,-1),1-n) - return li[0]+li[1] -def matrix_pow(mat,n): - ans = (1,0,0,1) # element matrix - while n>0: - if n%2==1: - ans = matrix_mul(ans,mat) - n>>=1 - mat = matrix_mul(mat,mat) + """Calculates the nth Fibonacci number""" + mat, p = (1, 1, 1, 0), n-2 + if n <= 0: # for negative fib item, use f(n) = f(n+2)-f(n-1) to calculate + mat = (0, 1, 1, -1), 2-n + li = matrix_pow((0, 1, 1, -1), 1-n) + return li[0]+li[1] + + +def matrix_pow(mat, n): + ans = (1, 0, 0, 1) # element matrix + while n > 0: + if n % 2 == 1: + ans = matrix_mul(ans, mat) + n >>= 1 + mat = matrix_mul(mat, mat) return ans -def matrix_mul(a,b): + +def matrix_mul(a, b): '''a,b are four-item tuple, represent matrix [[a[0],a[1]],[a[2],a[3]]]''' - return a[0]*b[0]+a[1]*b[2], a[0]*b[1]+a[1]*b[3], a[2]*b[0]+a[3]*b[2],a[2]*b[1]+a[3]*b[3] + return a[0]*b[0]+a[1]*b[2], a[0]*b[1]+a[1]*b[3], a[2]*b[0]+a[3]*b[2], a[2]*b[1]+a[3]*b[3] -if __name__=='__main__': - for i in range(-5,5): - print(i,fib(i)) +if __name__ == '__main__': + for i in range(-5, 5): + print(i, fib(i)) diff --git a/math/numWeight/addNegaBin.py b/math/numWeight/addNegaBin.py index d92e179..2bf9464 100644 --- a/math/numWeight/addNegaBin.py +++ b/math/numWeight/addNegaBin.py @@ -23,6 +23,7 @@ eg ''' from nega import nega + def addNegaBin(arr1: list, arr2: list) -> list: if len(arr1) < len(arr2): arr1, arr2 = arr2, arr1 @@ -42,19 +43,20 @@ def addNegaBin(arr1: list, arr2: list) -> list: elif arr1[i] == 0 and arr2[i] == 1: arr1[i] = arr2[i] - #print(arr1,arr2,i) + # print(arr1,arr2,i) while len(arr1) > 1 and arr1[0] == 0: arr1.pop(0) return arr1 -if __name__=='__main__': + +if __name__ == '__main__': while 1: print("input q to quit or input x1 x2: ") s = input() - if s=='q': + if s == 'q': break - n1,n2 =[int(i) for i in s.split()] - l1,l2 = nega(n1),nega(n2) - print(n1,l1) - print(n2,l2) + n1, n2 = [int(i) for i in s.split()] + l1, l2 = nega(n1), nega(n2) + print(n1, l1) + print(n2, l2) print(f'{n1}+{n2}={n1+n2}: {addNegaBin(l1,l2)}') diff --git a/math/numWeight/convertWeight.py b/math/numWeight/convertWeight.py index 367c347..e40f709 100644 --- a/math/numWeight/convertWeight.py +++ b/math/numWeight/convertWeight.py @@ -10,34 +10,37 @@ ######################################################################### ''' -def covert(s,basefrom=10,baseto=2): - return d2n(n2d(s,basefrom),baseto) -def n2d(s,base=16): + +def covert(s, basefrom=10, baseto=2): + return d2n(n2d(s, basefrom), baseto) + + +def n2d(s, base=16): ''' num of base_n(n<36) to decimal''' - dic = {chr(i+ord('0')):i for i in range(10)} - s=s.upper() - if base>10: - dic.update({chr(i+ord('A')):i+10 for i in range(26)}) - #if base in [16,8,2] : + dic = {chr(i+ord('0')): i for i in range(10)} + s = s.upper() + if base > 10: + dic.update({chr(i+ord('A')): i+10 for i in range(26)}) + # if base in [16,8,2] : # p=max(map(s.find,'OBX')) # s=s[p+1:] #remove prefix of hex or bin or oct - rst=0 + rst = 0 for i in s: - rst=dic[i]+rst*base + rst = dic[i]+rst*base return rst -def d2n(n,base=16): - ''' num of base_n(n<36) to decimal''' - dic = {i:chr(i+ord('0')) for i in range(10)} - if base>10: - dic.update({i+10:chr(i+ord('A')) for i in range(26)}) - rst=[] - while n!=0: - i=int(n/base) - rst.append(dic[n-i*base]) - n=i - return ''.join(rst[::-1]) +def d2n(n, base=16): + ''' num of base_n(n<36) to decimal''' + dic = {i: chr(i+ord('0')) for i in range(10)} + if base > 10: + dic.update({i+10: chr(i+ord('A')) for i in range(26)}) + rst = [] + while n != 0: + i = int(n/base) + rst.append(dic[n-i*base]) + n = i + return ''.join(rst[::-1]) ''' diff --git a/math/numWeight/nega.py b/math/numWeight/nega.py index 2dbef41..52c94a1 100644 --- a/math/numWeight/nega.py +++ b/math/numWeight/nega.py @@ -9,15 +9,18 @@ # Description: ######################################################################### ''' -def nega(n:int,base=-2:int)->:list: + + +def nega(n: int, base=-2: int)->: list: '''return list of num, the first is the highest digit''' - if base>-2: - raise Exception(f"[Error]: invalid base: {base}, base should be no more than -2") + if base > -2: + raise Exception( + f"[Error]: invalid base: {base}, base should be no more than -2") ans = [] while n: - k = n%base - if k<0: - k-=base + k = n % base + if k < 0: + k -= base ans.append(k) n = (n-k)//base return ans[::-1] diff --git a/math/numberTheory/euler.py b/math/numberTheory/euler.py index f8d4050..7f73ad2 100644 --- a/math/numberTheory/euler.py +++ b/math/numberTheory/euler.py @@ -17,17 +17,20 @@ from factor import factor from collections import Counter from functools import reduce from operator import mul + + def phi(n): - st = set(factor(n)) - return round(reduce(mul,(1-1/p for p in st),n)) + st = set(factor(n)) + return round(reduce(mul, (1-1/p for p in st), n)) + def sigma(n): ct = Counter(factor(n)) - return reduce(mul,(round((p**(ct[p]+1)-1)/(p-1)) for p in ct),1) + return reduce(mul, (round((p**(ct[p]+1)-1)/(p-1)) for p in ct), 1) -if __name__=='__main__': + +if __name__ == '__main__': while 1: n = int(input('n: ')) - print('phi(n):',phi(n)) - print('sigma(n):',sigma(n)) - + print('phi(n):', phi(n)) + print('sigma(n):', sigma(n)) diff --git a/math/numberTheory/factor.py b/math/numberTheory/factor.py index 470f97f..cb204fd 100644 --- a/math/numberTheory/factor.py +++ b/math/numberTheory/factor.py @@ -13,41 +13,49 @@ from random import randint from isPrime import isPrime -from gcd import gcd +from gcd import gcd + def factor(n): '''pollard's rho algorithm''' - if n<1:raise Exception('[Error]: {} is less than 1'.format(n)) - if n==1: return [] - if isPrime(n):return [n] - fact=1 - cycle_size=2 + if n < 1: + raise Exception('[Error]: {} is less than 1'.format(n)) + if n == 1: + return [] + if isPrime(n): + return [n] + fact = 1 + cycle_size = 2 x = x_fixed = 2 - c = randint(1,n) - while fact==1: + c = randint(1, n) + while fact == 1: for i in range(cycle_size): - if fact>1:break - x=(x*x+c)%n - if x==x_fixed: - c = randint(1,n) + if fact > 1: + break + x = (x*x+c) % n + if x == x_fixed: + c = randint(1, n) continue - fact = gcd(x-x_fixed,n) - cycle_size *=2 + fact = gcd(x-x_fixed, n) + cycle_size *= 2 x_fixed = x return factor(fact)+factor(n//fact) + + def fact(n): - f=2 + f = 2 ret = [] - while f*f<=n: - while not n%f: + while f*f <= n: + while not n % f: ret.append(f) n//f - f+=1 - if n>1:ret.append(n) + f += 1 + if n > 1: + ret.append(n) return ret -if __name__=='__main__': +if __name__ == '__main__': while 1: n = int(input('n: ')) print(factor(n)) diff --git a/math/numberTheory/gcd.py b/math/numberTheory/gcd.py index 34d4eb5..2a587ca 100644 --- a/math/numberTheory/gcd.py +++ b/math/numberTheory/gcd.py @@ -11,23 +11,28 @@ ####################################################################### ''' -def gcd(a,b): - while b!=0: - a,b=b,a%b + +def gcd(a, b): + while b != 0: + a, b = b, a % b return a -def lcm(a,b): - return int(a*b/gcd(a,b)) -def xgcd(a,b): - '''return gcd(a,b), x,y where ax+by=gcd(a,b)''' - if b==0:return a,1,0 - g,x,y = xgcd(b,a%b) - return g,y,x-a//b*y -if __name__=='__main__': +def lcm(a, b): + return int(a*b/gcd(a, b)) + + +def xgcd(a, b): + '''return gcd(a,b), x,y where ax+by=gcd(a,b)''' + if b == 0: + return a, 1, 0 + g, x, y = xgcd(b, a % b) + return g, y, x-a//b*y + + +if __name__ == '__main__': while 1: a = int(input('a: ')) b = int(input('b: ')) - print('gcd :',gcd(a,b)) - print('xgcd:',xgcd(a,b)) - + print('gcd :', gcd(a, b)) + print('xgcd:', xgcd(a, b)) diff --git a/math/numberTheory/hammingDistance.py b/math/numberTheory/hammingDistance.py index 76f1946..79c96a6 100644 --- a/math/numberTheory/hammingDistance.py +++ b/math/numberTheory/hammingDistance.py @@ -13,48 +13,51 @@ ####################################################################### ''' -def hammingDistance(a,b): - if isinstance(a,int): - n = a^b + +def hammingDistance(a, b): + if isinstance(a, int): + n = a ^ b ct = 0 while n: - ct+=n%2 - n>>=1 + ct += n % 2 + n >>= 1 return ct else: - n,m = len(a),len(b) + n, m = len(a), len(b) ret = 0 - for i,j in zip(a,b): - ret+= i==j + for i, j in zip(a, b): + ret += i == j return ret+abs(n-m) + def totalHammingDistance(lst): '''return sum of any two items(num or lst( str)) in lst''' - length = len(lst) - if length ==0:return 0 - if isinstance(lst[0],int): + length = len(lst) + if length == 0: + return 0 + if isinstance(lst[0], int): bits = [0] * len(bin(max(lst))) for n in lst: ct = 0 while n: - if n%2==1: - bits[ct]+=1 - ct+=1 - n>>=1 + if n % 2 == 1: + bits[ct] += 1 + ct += 1 + n >>= 1 return sum(i*(length-i) for i in bits) else: - mx = len(max(lst,key=len)) + mx = len(max(lst, key=len)) position = [dict() for i in range(mx)] for li in lst: - for i,x in enumerate(li): + for i, x in enumerate(li): if x in position[i]: - position[i][x] +=1 + position[i][x] += 1 else: - position[i][x] =1 + position[i][x] = 1 ret = 0 for dic in position: left = length for i in dic.values(): - ret+=i*(left-i) # key step - left -=i # key step + ret += i*(left-i) # key step + left -= i # key step return ret diff --git a/math/numberTheory/isPrime.py b/math/numberTheory/isPrime.py index 785903a..8ca130f 100644 --- a/math/numberTheory/isPrime.py +++ b/math/numberTheory/isPrime.py @@ -12,56 +12,61 @@ from random import randint -def quickMulMod(a,b,m): +def quickMulMod(a, b, m): '''a*b%m, quick''' ret = 0 while b: - if b&1: - ret = (a+ret)%m - b//=2 - a = (a+a)%m + if b & 1: + ret = (a+ret) % m + b //= 2 + a = (a+a) % m return ret -def quickPowMod(a,b,m): + +def quickPowMod(a, b, m): '''a^b %m, quick, O(logn)''' - ret =1 + ret = 1 while b: - if b&1: - ret =quickMulMod(ret,a,m) - b//=2 - a = quickMulMod(a,a,m) + if b & 1: + ret = quickMulMod(ret, a, m) + b //= 2 + a = quickMulMod(a, a, m) return ret -def isPrime(n,t=5): +def isPrime(n, t=5): '''miller rabin primality test, a probability result t is the number of iteration(witness) ''' - t = min(n-3,t) - if n<2: + t = min(n-3, t) + if n < 2: print('[Error]: {} can\'t be classed with prime or composite'.format(n)) return - if n==2: return True + if n == 2: + return True d = n-1 r = 0 - while d%2==0: - r+=1 - d//=2 - tested=set() + while d % 2 == 0: + r += 1 + d //= 2 + tested = set() for i in range(t): - a = randint(2,n-2) + a = randint(2, n-2) while a in tested: - a = randint(2,n-2) + a = randint(2, n-2) tested.add(a) - x= quickPowMod(a,d,n) - if x==1 or x==n-1: continue #success, + x = quickPowMod(a, d, n) + if x == 1 or x == n-1: + continue # success, for j in range(r-1): - x= quickMulMod(x,x,n) - if x==n-1:break + x = quickMulMod(x, x, n) + if x == n-1: + break else: return False return True + ''' we shouldn't use Fermat's little theory Namyly: @@ -73,49 +78,23 @@ The inverse theorem of it is not True. a counter-example: 2^340 \equiv 1 (mod 341), but 341 is a composite ''' -class primeSieve: - '''sieve of Eratosthenes, It will be more efficient when judging many times''' - primes = [2,3,5,7,11,13] - def isPrime(self,x): - if x<=primes[-1]: - return twoDivideFind(x,self.primes) - while x>self.primes[-1]: - left = self.primes[-1] - right = (left+1)**2 - lst = [] - for i in range(left,right): - for j in self.primes: - if i%j==0:break - else:lst.append(i) - self.primes+=lst - return twoDivideFind(x,lst) - def nPrime(n): - '''return the n-th prime''' - i=n-len(self.primes) - last = self.primes[-1] - for _ in range(i): - while 1: - last +=2 - for p in self.primes: - if last%p==0: - break - else: - self.primes.append(last) - break - return self.primes[n-1] -def twoDivideFind(x,li): - a,b = 0, len(li) - while a<=b: +def twoDivideFind(x, li): + a, b = 0, len(li) + while a <= b: mid = (a+b)//2 - if li[mid]x: b= mid-1 - else:return mid + if li[mid] < x: + a = mid+1 + elif li[mid] > x: + b = mid-1 + else: + return mid return -1 -if __name__=='__main__': + +if __name__ == '__main__': n = 100 - print('prime numbers below',n) + print('prime numbers below', n) print([i for i in range(n) if isPrime(i)]) while 1: n = int(input('n: ')) diff --git a/math/numberTheory/modulo_equation.py b/math/numberTheory/modulo_equation.py index 1c071bd..456839a 100644 --- a/math/numberTheory/modulo_equation.py +++ b/math/numberTheory/modulo_equation.py @@ -18,110 +18,124 @@ from euler import phi from isPrime import isPrime from factor import factor -def ind(m,g): - ''' mod m ,primary root g -> {n:indg n}''' - return {j:i for i in range(m-1) \ - for j in range(m) if (g**i-j)%m==0} -def gs(m,num=100): - '''return list of m's primary roots below num''' +def ind(m, g): + ''' mod m ,primary root g -> {n:indg n}''' + return {j: i for i in range(m-1) + for j in range(m) if (g**i-j) % m == 0} + + +def gs(m, num=100): + '''return list of m's primary roots below num''' p = phi(m) mp = factor(p) checkLst = [p//i for i in mp] - return [i for i in range(2,num) if all((i**n-1)%m !=0 for n in checkLst)] + return [i for i in range(2, num) if all((i**n-1) % m != 0 for n in checkLst)] + def minG(m): p = phi(m) mp = factor(p) checkLst = [p//i for i in mp] - i=2 - while 1: - if all((i**n-1)%m !=0 for n in checkLst):return i - i+=1 + i = 2 + while 1: + if all((i**n-1) % m != 0 for n in checkLst): + return i + i += 1 + class solve: - def __init__(self,equ=None): - self.linearPat= re.compile(r'\s*(\d+)\s*--\s*(\d+)[\s\(]*mod\s*(\d+)') - self.sol = [] + def __init__(self, equ=None): + self.linearPat = re.compile(r'\s*(\d+)\s*--\s*(\d+)[\s\(]*mod\s*(\d+)') + self.sol = [] #self.m = m #self.ind_mp = ind(m,minG(m)) + def noSol(self): print('equation {equ} has no solution'.format(equ=self.equ)) + def error(self): print("Error! The divisor m must be postive integer") - def solveLinear(self,a,b,m): + + def solveLinear(self, a, b, m): '''ax--b(mod m): solve linear equation with one unknown return ([x1,x2,...],m) ''' - a,b,m = self.check(a,b,m) - g,x,y=xgcd(a,m) - if a*b%g!=0: + a, b, m = self.check(a, b, m) + g, x, y = xgcd(a, m) + if a*b % g != 0: self.noSol() return None - sol=x*b//g + sol = x*b//g m0 = m//g - sols = [(sol+i*m0)%m for i in range(g)] - print('{}x--{}(mod {}), solution: {} mod {}'.format(a,b,m,sols,m)) - return (sols,m) - def check(self,a,b,m): - if m<=0: + sols = [(sol+i*m0) % m for i in range(g)] + print('{}x--{}(mod {}), solution: {} mod {}'.format(a, b, m, sols, m)) + return (sols, m) + + def check(self, a, b, m): + if m <= 0: self.error() return None - if a<0:a,b=-a,-b ## important - if b<0:b+= -b//m * m - return a,b,m + if a < 0: + a, b = -a, -b # important + if b < 0: + b += -b//m * m + return a, b, m - def solveHigh(self,a,n,b,m): + def solveHigh(self, a, n, b, m): ''' ax^n -- b (mod m) ind_mp is a dict of m's {n: indg n}''' - ind_mp = ind(m,minG(m)) + ind_mp = ind(m, minG(m)) tmp = ind_mp[b] - ind_mp[a] - if tmp < 0:tmp+=m - sol = self.solveLinear(n,tmp,phi(m)) - re_mp = {j:i for i ,j in ind_mp.items()} + if tmp < 0: + tmp += m + sol = self.solveLinear(n, tmp, phi(m)) + re_mp = {j: i for i, j in ind_mp.items()} sols = [re_mp[i] for i in sol[0]] - print('{}x^{}--{}(mod {}), solution: {} mod {}'.format(a,n,b,m,sols,m)) - return sols,m + print('{}x^{}--{}(mod {}), solution: {} mod {}'.format(a, n, b, m, sols, m)) + return sols, m - def solveGroup(self,tups): + def solveGroup(self, tups): '''tups is a list of tongyu equation groups, like [(a1,b1,m1),(a2,b2,m2)...] and, m1,m2... are all primes ''' mp = {} print('solving group of equations: ') - for a,b,m in tups: - print('{}x--{}(mod {})'.format(a,b,m)) + for a, b, m in tups: + print('{}x--{}(mod {})'.format(a, b, m)) if m in mp: - if mp[m][0]*b!=mp[m][1]*a: + if mp[m][0]*b != mp[m][1]*a: self.noSol() return - else:mp[m] = (a,b) + else: + mp[m] = (a, b) product = 1 for i in mp.keys(): - product *=i + product *= i sol = [0] for i in mp: - xs,m = self.solveLinear(product//i*mp[i][0],1,i) + xs, m = self.solveLinear(product//i*mp[i][0], 1, i) new = [] for x in xs: cur = x*product//i*mp[i][1] for old in sol: new.append(old+cur) sol = new - sol= [i%product for i in sol] - print('final solution: {} mod {}'.format(sol,product)) - return sol,product + sol = [i % product for i in sol] + print('final solution: {} mod {}'.format(sol, product)) + return sol, product + def __call__(self): - s=input('输入同余方程,用--代表同于号,形如3--5(mod 7)代表3x模7同余于5') - li= self.linearPat.findall(s) - li = [(int(a),int(b),int(m)) for a,b,m in li] + s = input('输入同余方程,用--代表同于号,形如3--5(mod 7)代表3x模7同余于5') + li = self.linearPat.findall(s) + li = [(int(a), int(b), int(m)) for a, b, m in li] print(self.solveLinear(li[0])) if __name__ == '__main__': - solver = solve() - res = solver.solveLinear(3,6,9) + solver = solve() + res = solver.solveLinear(3, 6, 9) print() - res = solver.solveHigh(1,8,3,11) + res = solver.solveHigh(1, 8, 3, 11) print() - res = solver.solveGroup([(5,11,2),(3,8,5),(4,1,7)]) + res = solver.solveGroup([(5, 11, 2), (3, 8, 5), (4, 1, 7)]) diff --git a/math/numberTheory/primesLEn.hs b/math/numberTheory/primesLEn.hs index 7a6ddf8..cc6361f 100644 --- a/math/numberTheory/primesLEn.hs +++ b/math/numberTheory/primesLEn.hs @@ -1,3 +1,3 @@ genPrimes 2= [2] genPrimes n = let li = genPrimes $n-1 - in if all (\x-> mod n x /=0) li then n:li else li +in if all (\x-> mod n x /=0) li then n:li else li diff --git a/math/numberTheory/sievePrime.py b/math/numberTheory/sievePrime.py new file mode 100644 index 0000000..5bab85a --- /dev/null +++ b/math/numberTheory/sievePrime.py @@ -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) diff --git a/math/numericalAnalysis/interplotion.py b/math/numericalAnalysis/interplotion.py index 4bab0a9..4a85236 100644 --- a/math/numericalAnalysis/interplotion.py +++ b/math/numericalAnalysis/interplotion.py @@ -26,58 +26,65 @@ from collections import namedtuple from functools import reduce from operator import mul -X = sympy.Symbol ('x') -point = namedtuple('point',['x','y']) +X = sympy.Symbol('x') +point = namedtuple('point', ['x', 'y']) + class interplotion: - def __init__(self,points): - self.points = [point(x,y) for x,y in points] - self.xs= [i for i,j in points] - self.poly,self.rem = self.newton(self.points,0,len(self.points)-1) + def __init__(self, points): + self.points = [point(x, y) for x, y in points] + self.xs = [i for i, j in points] + self.poly, self.rem = self.newton(self.points, 0, len(self.points)-1) - def newton(self,li,a,b): + def newton(self, li, a, b): '''li:[(x,f(x))...]''' - + qs = [li[0].y] - - def quoDiff(begin,end): - if begin == end:return li[begin].y - q = (quoDiff(begin+1,end)-quoDiff(begin,end-1))/(li[end].x-li[begin].x) - if begin == a:qs.append(q) + + def quoDiff(begin, end): + if begin == end: + return li[begin].y + q = (quoDiff(begin+1, end)-quoDiff(begin, end-1)) / \ + (li[end].x-li[begin].x) + if begin == a: + qs.append(q) return q - quoDiff(a,b) - poly ,base = 0, 1 - for i,q in enumerate(qs): + quoDiff(a, b) + poly, base = 0, 1 + for i, q in enumerate(qs): poly += q*base - base*= X-li[i].x + base *= X-li[i].x return poly, base*qs[-1] - def lagrange(self,points=None): + + def lagrange(self, points=None): xs = None if points is None: xs = self.xs points = self.points - else: xs =[x for x,y in points] - product = reduce(mul,[X-x for x in xs],1) + else: + xs = [x for x, y in points] + product = reduce(mul, [X-x for x in xs], 1) poly = 0 - for x,y in points: - tmp = product/(X-x) - coef = y/(tmp.subs(X,x)) - poly+= coef *tmp + for x, y in points: + tmp = product/(X-x) + coef = y/(tmp.subs(X, x)) + poly += coef * tmp return poly - - def predict(self,val,poly = None): - if poly is None:poly = self.poly - return poly.subs(X,val) # note the func subs + + def predict(self, val, poly=None): + if poly is None: + poly = self.poly + return poly.subs(X, val) # note the func subs if __name__ == '__main__': - f = interplotion([(81,9),(100,10),(121,11)]) + f = interplotion([(81, 9), (100, 10), (121, 11)]) p = f.lagrange() - print(p.subs(X,105)) + print(p.subs(X, 105)) print(p) - intor = interplotion([(0,11),(0.02,9),(0.04,7),(0.06,10)]) + intor = interplotion([(0, 11), (0.02, 9), (0.04, 7), (0.06, 10)]) p = intor.lagrange() print(p) res = intor.predict(0.08) diff --git a/math/numericalAnalysis/iteration.py b/math/numericalAnalysis/iteration.py index f21ed3a..bb25474 100644 --- a/math/numericalAnalysis/iteration.py +++ b/math/numericalAnalysis/iteration.py @@ -15,94 +15,98 @@ import numpy as np from math import sqrt -def newton(y:sympy.core,x0:float,epsilon:float=0.00001,maxtime:int=50) ->(list,list): +def newton(y: sympy.core, x0: float, epsilon: float = 0.00001, maxtime: int = 50) ->(list, list): ''' newton 's iteration method for finding a zeropoint of a func y is the func, x0 is the init x val: int float epsilon is the accurrency ''' - if epsilon <0:epsilon = -epsilon - ct =0 - t = y.free_symbols - varsymbol = 'x' if len(t)==0 else t.pop() - x0= float(x0) + if epsilon < 0: + epsilon = -epsilon + ct = 0 + t = y.free_symbols + varsymbol = 'x' if len(t) == 0 else t.pop() + x0 = float(x0) y_diff = y.diff() li = [x0] vals = [] while 1: - val = y.subs(varsymbol,x0) + val = y.subs(varsymbol, x0) vals.append(val) - x = x0- val/y_diff.subs(varsymbol,x0) + x = x0 - val/y_diff.subs(varsymbol, x0) li.append(x) - ct+=1 - if ct>maxtime: + ct += 1 + if ct > maxtime: print("after iteration for {} times, I still havn't reach the accurrency.\ Maybe this function havsn't zeropoint\n".format(ct)) - return li ,val - if abs(x-x0)(list,list): + +def secant(y: sympy.core, x0: float, x1: float, epsilon: float = 0.00001, maxtime: int = 50) ->(list, list): ''' 弦截法, 使用newton 差商计算,每次只需计算一次f(x) secant method for finding a zeropoint of a func y is the func , x0 is the init x val, epsilon is the accurrency ''' - if epsilon <0:epsilon = -epsilon - ct =0 - x0,x1 = float(x0),float(x1) - li = [x0,x1] - t = y.free_symbols - varsymbol = 'x' if len(t)==0 else t.pop() - last = y.subs(varsymbol,x0) + if epsilon < 0: + epsilon = -epsilon + ct = 0 + x0, x1 = float(x0), float(x1) + li = [x0, x1] + t = y.free_symbols + varsymbol = 'x' if len(t) == 0 else t.pop() + last = y.subs(varsymbol, x0) vals = [last] while 1: - cur = y.subs(varsymbol,x1) + cur = y.subs(varsymbol, x1) vals.append(cur) x = x1-cur*(x1-x0)/(cur-last) - x0 ,x1= x1,x + x0, x1 = x1, x last = cur li.append(x) - ct+=1 - if ct>maxtime: + ct += 1 + if ct > maxtime: print("after iteration for {} times, I still havn't reach the accurrency.\ Maybe this function havsn't zeropoint\n".format(ct)) - return li,vals - if abs(x0-x1)dict: +def solveNonlinearEquations(funcs: [sympy.core], init_dic: dict, epsilon: float = 0.001, maxtime: int = 50)->dict: '''solve nonlinear equations:''' li = list(init_dic.keys()) - delta = {i:0 for i in li} + delta = {i: 0 for i in li} ct = 0 while 1: - ys = np.array([f.subs(init_dic) for f in funcs],dtype = 'float') - mat = np.matrix([[i.diff(x).subs(init_dic) for x in li] for i in funcs ],dtype = 'float') - delt = np.linalg.solve(mat,-ys) - for i,j in enumerate(delt): - init_dic[li[i]] +=j + ys = np.array([f.subs(init_dic) for f in funcs], dtype='float') + mat = np.matrix([[i.diff(x).subs(init_dic) for x in li] + for i in funcs], dtype='float') + delt = np.linalg.solve(mat, -ys) + for i, j in enumerate(delt): + init_dic[li[i]] += j delta[li[i]] = j - if ct>maxtime: + if ct > maxtime: print("after iteration for {} times, I still havn't reach the accurrency.\ Maybe this function havsn't zeropoint\n".format(ct)) return init_dic - if sqrt(sum(i**2 for i in delta.values()))=n\n') - s = s.replace(' ','') - li = re.findall(r'(\[(\d+)(,(\d+))+\])',s) - li = [parseLst(i[0]) for i in li] - if not y:y = input('input a vector y:n*1\n') + if not s: + s = input('input matrix A:m*n //m>=n\n') + s = s.replace(' ', '') + li = re.findall(r'(\[(\d+)(,(\d+))+\])', s) + li = [parseLst(i[0]) for i in li] + if not y: + y = input('input a vector y:n*1\n') y = parseLst(y) print('Equation: Av = y:') - + print('y is as follows: ') print(y) print('A is as follows: ') for i in li: for j in i: - print('{}'.format(j).rjust(5),end='') + print('{}'.format(j).rjust(5), end='') print('') - + print('result v is as follows: ') - res = solveConflitEqualtion(li,y) + res = solveConflitEqualtion(li, y) print(res) + + def parseLst(s): - s = s.strip('[]') + s = s.strip('[]') li = s.split(',') li = [float(j) for j in li] return li @@ -86,19 +91,19 @@ if __name__ == '__main__': s = input('input y to continue, n for exit') if s!='y':break ''' - point = [(-3,14.3),(-2,8.3),(-1,4.7),(2,-8.3),(4,-22.7)] - lst = [0,3] - solveLinear(point,lst) + point = [(-3, 14.3), (-2, 8.3), (-1, 4.7), (2, -8.3), (4, -22.7)] + lst = [0, 3] + solveLinear(point, lst) + + point = [(-3, 14.3), (-2, 8.3), (-1, 4.7), (2, 8.3), (4, 22.7)] + lst = [0, 2] + solveLinear(point, lst) + + A = [[1, 2], [2, 1], [1, 1]] + y = [[5], [6], [4]] + res = solveConflitEqualtion(A, y) - point= [(-3,14.3),(-2,8.3),(-1,4.7),(2,8.3),(4,22.7)] - lst = [0,2] - solveLinear(point,lst) - - A = [[1,2],[2,1],[1,1]] - y = [[5],[6],[4]] - res = solveConflitEqualtion(A,y) - print(res) - A = [[1,-2],[1,5],[2,1],[1,1]] - y = [[1],[13.1],[7.9],[5.1]] - print(solveConflitEqualtion(A,y)) + A = [[1, -2], [1, 5], [2, 1], [1, 1]] + y = [[1], [13.1], [7.9], [5.1]] + print(solveConflitEqualtion(A, y)) diff --git a/math/numericalAnalysis/linear_equation.py b/math/numericalAnalysis/linear_equation.py index c2f302b..3cac098 100644 --- a/math/numericalAnalysis/linear_equation.py +++ b/math/numericalAnalysis/linear_equation.py @@ -19,86 +19,105 @@ > Created Time: 2018-04-20 08:32 ************************************************************************''' + + + import numpy as np def getLU(A): '''doolittle : A = LU, L is in down-triangle form, U is in up-triangle form ''' - m,n = A.shape - if m!=n:raise Exception("this matrix is not inversable") + m, n = A.shape + if m != n: + raise Exception("this matrix is not inversable") - L = np.zeros([m,m]) - U = np.zeros([m,m]) + L = np.zeros([m, m]) + U = np.zeros([m, m]) L = np.matrix(L) U = np. matrix(U) U[0] = A[0] - L[:,0] = A[:,0] / A[0,0] - for i in range(1,m): - for j in range(i,m): - U[i,j]= A[i,j] - sum(L[i,k]*U[k,j] for k in range(i)) - L[j,i] = (A[j,i] - sum(L[j,k]*U[k,i] for k in range(i)))/U[i,i] + L[:, 0] = A[:, 0] / A[0, 0] + for i in range(1, m): + for j in range(i, m): + U[i, j] = A[i, j] - sum(L[i, k]*U[k, j] for k in range(i)) + L[j, i] = (A[j, i] - sum(L[j, k]*U[k, i] + for k in range(i)))/U[i, i] print(L) print(U) - return L,U + return L, U def gauss_prior_elimination(A): '''using guass elimination,get up_trianglge form of A''' - m,n = A.shape - if m!=n:raise Exception("[Error]: matrix is not inversable") - B = np.matrix(A,dtype=float) # necessary,otherwise when the dtype of A is int, then it will be wrong - for i in range(m-1): - col = abs(B[i:,i]) # note using abs value, return a matrix in (m-i)x1 form + m, n = A.shape + if m != n: + raise Exception("[Error]: matrix is not inversable") + # necessary,otherwise when the dtype of A is int, then it will be wrong + B = np.matrix(A, dtype=float) + for i in range(m-1): + # note using abs value, return a matrix in (m-i)x1 form + col = abs(B[i:, i]) mx = col.max() - if mx==0: raise Exception("[Error]: matrix is not inversable") + if mx == 0: + raise Exception("[Error]: matrix is not inversable") pos = i+col.argmax() - if pos != i : B[[pos,i],:] = B[[i,pos],:] # note how to swap cols/rows - B[i,:] = 1/mx*B[i,:] - for j in range(i+1,m): - #print(B) - B[j,:] -= B[j,i] * B[i,:] + if pos != i: + B[[pos, i], :] = B[[i, pos], :] # note how to swap cols/rows + B[i, :] = 1/mx*B[i, :] + for j in range(i+1, m): + # print(B) + B[j, :] -= B[j, i] * B[i, :] print(B) return B -def solveDown(A,b): + +def solveDown(A, b): '''A is a matrix in down-triangle form''' sol = np.zeros(b.shape) for i in range(b.shape[0]): - sol[i,0] = (b[i,0]-sum(A[i,j]*sol[j,0] for j in range(i)))/A[i,i] + sol[i, 0] = (b[i, 0]-sum(A[i, j]*sol[j, 0] for j in range(i)))/A[i, i] return sol -def solveUp(A,b): + +def solveUp(A, b): '''A is a matrix in up-triangle form''' sol = np.zeros(b.shape) n = b.shape[0] - for i in range(n-1,-1,-1): - sol[i,0] = (b[i,0]-sum(A[i,j]*sol[j,0] for j in range(n-1,i,-1)))/A[i,i] + for i in range(n-1, -1, -1): + sol[i, 0] = (b[i, 0]-sum(A[i, j]*sol[j, 0] + for j in range(n-1, i, -1)))/A[i, i] return sol -def doolittle(A,b): - L,U = getLU(A) - y = solveDown(L,b) - x = solveUp(U,y) + + +def doolittle(A, b): + L, U = getLU(A) + y = solveDown(L, b) + x = solveUp(U, y) print(y) print(x) return x -def ldlt(A,b): - L,U = getLU(A) + + +def ldlt(A, b): + L, U = getLU(A) D = np.diag(np.diag(U)) - print(D,"D") - z = np.linalg.solve(L,b) - print(z,"z") - y = np.linalg.solve(D,z) - print(y,"y") - x = np.linalg.solve(L.T,y) - print(x,"x") + print(D, "D") + z = np.linalg.solve(L, b) + print(z, "z") + y = np.linalg.solve(D, z) + print(y, "y") + x = np.linalg.solve(L.T, y) + print(x, "x") return x + + if __name__ == '__main__': - A = np.matrix([[10,5,0,0], - [2,2,1,0], - [0,10,0,5], - [0,0,2,1]]) - b = np.matrix([[5],[3],[27],[6]]) + A = np.matrix([[10, 5, 0, 0], + [2, 2, 1, 0], + [0, 10, 0, 5], + [0, 0, 2, 1]]) + b = np.matrix([[5], [3], [27], [6]]) gauss_prior_elimination(A) '''ldlt @@ -115,4 +134,3 @@ if __name__ == '__main__': b = np.matrix([[4],[6],[5]]) doolittle(A,b) ''' - diff --git a/math/numericalAnalysis/numerical_differential.py b/math/numericalAnalysis/numerical_differential.py deleted file mode 100644 index d76e1ef..0000000 --- a/math/numericalAnalysis/numerical_differential.py +++ /dev/null @@ -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: -######################################################################### -''' - - diff --git a/math/numericalAnalysis/numerical_integration.py b/math/numericalAnalysis/numerical_integration.py index 2a97241..04172f2 100644 --- a/math/numericalAnalysis/numerical_integration.py +++ b/math/numericalAnalysis/numerical_integration.py @@ -18,53 +18,56 @@ # Blog: https://mbinary.xyz # Github: https://github.com/mbinary # Created Time: 2018-05-11 08:58 -# Description: +# Description: # numerical intergration: using Newton-Cotes integration, and Simpson # 数值积分, 使用 牛顿-科特斯积分, 辛普森 ######################################################################### - import numpy as np -def trapezoidal(a,b,h,fs): + + +def trapezoidal(a, b, h, fs): '''梯形积分公式''' - xs = [i for i in np.arange(a,b+h,h)] + xs = [i for i in np.arange(a, b+h, h)] print(xs) ret = h*(sum(fs)-fs[0]/2 - fs[-1]/2) print(ret) return ret -def simpson(a,b,h,fs): +def simpson(a, b, h, fs): '''辛普森积分公式''' - xs = [i for i in np.arange(a,b+h,h)] + xs = [i for i in np.arange(a, b+h, h)] print(xs) - ret = h/3*(4* sum(fs[1::2])+ 2*sum(fs[2:-1:2]) + fs[0]+fs[-1]) + ret = h/3*(4 * sum(fs[1::2]) + 2*sum(fs[2:-1:2]) + fs[0]+fs[-1]) print(ret) return ret -def romberg(a,b,f,epcilon): +def romberg(a, b, f, epcilon): '''romberg(龙贝格) 数值积分''' h = b-a - lst1=[h*(f(a)+f(b))/2] + lst1 = [h*(f(a)+f(b))/2] print(lst1) delta = epcilon - k=1 + k = 1 while delta >= epcilon: - h/=2 - k+=1 - lst2=[] - lst2.append((lst1[0]+h*2*sum(f(a+(2*i-1)*h) for i in range(1,2**(k-2)+1)))/2) - for j in range(0,k-1): + h /= 2 + k += 1 + lst2 = [] + lst2.append((lst1[0]+h*2*sum(f(a+(2*i-1)*h) + for i in range(1, 2**(k-2)+1)))/2) + for j in range(0, k-1): lst2.append(lst2[j]+(lst2[j]-lst1[j])/(4**(j+1)-1)) delta = abs(lst2[-1]-lst1[-1]) - lst1=lst2 + lst1 = lst2 print(lst1) -if __name__=='__main__': - a,b,h = 0.6,1.8,0.2 - fs=[5.7,4.6,3.5,3.7,4.9,5.2,5.5] - trapezoidal(a,b,h,fs) - simpson(a,b,h,fs) - romberg(1,2,lambda x:sin(x**4),1e-4) + +if __name__ == '__main__': + a, b, h = 0.6, 1.8, 0.2 + fs = [5.7, 4.6, 3.5, 3.7, 4.9, 5.2, 5.5] + trapezoidal(a, b, h, fs) + simpson(a, b, h, fs) + romberg(1, 2, lambda x: sin(x**4), 1e-4) diff --git a/math/numericalAnalysis/solve-linear-by-iteration.py b/math/numericalAnalysis/solve-linear-by-iteration.py index f2ba2da..5a6bcce 100644 --- a/math/numericalAnalysis/solve-linear-by-iteration.py +++ b/math/numericalAnalysis/solve-linear-by-iteration.py @@ -21,46 +21,59 @@ # Description: ######################################################################### ''' -import numpy as np -from operator import le,lt -def jacob(A,b,x,accuracy=None,times=6): + + + +import numpy as np +from operator import le, lt +def jacob(A, b, x, accuracy=None, times=6): ''' Ax=b, arg x is the init val, times is the time of iterating''' - A,b,x = np.matrix(A),np.matrix(b),np.matrix(x) - n,m = A.shape - if n!=m:raise Exception("Not square matrix: {A}".format(A=A)) - if b.shape !=( n,1) : raise Exception('Error: {b} must be {n} x1 in dimension'.format(b = b,n=n)) + A, b, x = np.matrix(A), np.matrix(b), np.matrix(x) + n, m = A.shape + if n != m: + raise Exception("Not square matrix: {A}".format(A=A)) + if b.shape != (n, 1): + raise Exception( + 'Error: {b} must be {n} x1 in dimension'.format(b=b, n=n)) D = np.diag(np.diag(A)) - DI = np.zeros([n,n]) - for i in range(n):DI[i,i]= 1/D[i,i] + DI = np.zeros([n, n]) + for i in range(n): + DI[i, i] = 1/D[i, i] R = np.eye(n) - DI * A g = DI * b print('R =\n{}'.format(R)) print('g =\n{}'.format(g)) last = -x if accuracy != None: - ct=0 + ct = 0 while 1: - ct+=1 + ct += 1 tmp = x-last last = x - mx = max ( abs(i) for i in tmp) - if mx=0 for i in range(3)]) + bl = reduce(and_, [self.norm(i) >= 0 for i in range(3)]) if bl: - n = randint(2,100) - bl = reduce(and_,[n*(self.norm(i))==(n*self).norm(i) for i in range(3)]) + n = randint(2, 100) + bl = reduce(and_, [n*(self.norm(i)) == (n*self).norm(i) + for i in range(3)]) if bl: - another = self*randint(2,10)-randint(1,100) - return reduce(and_,[(another+self).norm(i)<=another.norm(i)+self.norm(i) for i in range(3)]) + another = self*randint(2, 10)-randint(1, 100) + return reduce(and_, [(another+self).norm(i) <= another.norm(i)+self.norm(i) for i in range(3)]) return False - + + class vector(obj): - def __init__(self,arr): + def __init__(self, arr): ''' arr: iterable''' - self.data =np.array(arr) - def innerProduct(self,x): + self.data = np.array(arr) + + def innerProduct(self, x): return sum(self.data*x) - def outerProduct(self,x): + + def outerProduct(self, x): pass class matrix(obj): - def __init__(self,s): + def __init__(self, s): '''s is a list of lists''' - self.data=np.mat(s) + self.data = np.mat(s) self.T = None self. I = None ''' @@ -104,31 +119,38 @@ class matrix(obj): def I(self,s): self.I = s ''' - def E(self,n=None): - if n is None: n = self.data.shape[0] + + def E(self, n=None): + if n is None: + n = self.data.shape[0] return np.eye(n) - def norm(self,n=0): - absolute = abs(self.data) + def norm(self, n=0): + absolute = abs(self.data) if n < 1: # max of one row sum return max([sum(i) for i in absolute]) - if n==1:return self.norm1() - elif n==2:return self.norm2() + if n == 1: + return self.norm1() + elif n == 2: + return self.norm2() + def norm1(self): ''' max of sum of cols''' absolute = abs(self.data) - return max(absolute.sum(axis=0)) + return max(absolute.sum(axis=0)) + def norm2(self): ''' max of sum of rows''' absolute = abs(self.data) return max(absolute.sum(axis=1)) + def norm_f(self): return sum((self.data**2).sum(axis=1))**0.5 -if __name__ =='__main__': - v1 = vector([1,-2,3,4]) - v2 = vector([0,2,0,5]) - m1 = matrix([v1,v2,v2,v1]) + +if __name__ == '__main__': + v1 = vector([1, -2, 3, 4]) + v2 = vector([0, 2, 0, 5]) + m1 = matrix([v1, v2, v2, v1]) print([v1.norm(i) for i in range(3)]) - diff --git a/math/permute/permute_cantor.c b/math/permute/permute_cantor.c index f9b0520..4b83232 100644 --- a/math/permute/permute_cantor.c +++ b/math/permute/permute_cantor.c @@ -12,56 +12,64 @@ #include //使用康托展开计算全排列, 下面存储的是0!,1!,2!...(n-1)! -long long int fac[100]={}; +long long int fac[100] = {}; void calFac(int n) { int i; - fac[0]=1; - for(i=1;i<=n;i++){ - fac[i]=i*fac[i-1]; + fac[0] = 1; + + for (i = 1; i <= n; i++) { + fac[i] = i * fac[i - 1]; } } -void permute(int *arr,int n,int sum) +void permute(int *arr, int n, int sum) { /*sum表示全排列由小到大排序后的名次,从0 开始计数, 由名次求出 n位的排列存储到 arr 中*/ - int i,j,ct=0,k, ct2; + int i, j, ct = 0, k, ct2; int flag[n]; - for(i=0;i=0;i--){ - for(j=i;j>=0;j--){ - if(j*fac[i]<=sum){ - ct2=0; - for(k=0;k= 0; i--) { + for (j = i; j >= 0; j--) { + if (j * fac[i] <= sum) { + ct2 = 0; + + for (k = 0; k < n; ++k) { //printf("i%d j%d k%d\n",i,j,k); - if(flag[k]==1)ct2++; - if(ct2>j)break; + if (flag[k] == 1)ct2++; + + if (ct2 > j)break; } + arr[ct++] = k; - flag[k]=0; - sum -=j*fac[i]; + flag[k] = 0; + sum -= j * fac[i]; break; } } } } -void printArr(int *p,int n) +void printArr(int *p, int n) { - for(int i=0;i s[j]: count +=1 + for j in range(i+1, ls): + if s[i] > s[j]: + count += 1 sum += count*fac[lf-i-1] return sum + que = [] -dir = {-3:'u',1:'r',3:'d',-1:'l'} +dir = {-3: 'u', 1: 'r', 3: 'd', -1: 'l'} + + class state: flag = True - def __init__(self,s,x,f,step=0,last=0): + + def __init__(self, s, x, f, step=0, last=0): self.x = x self.s = list(s) self.step = step self.path = [] self.last = last self.f = f + def can(self): - cans = [-1,1,3,-3] - if self.last in cans : + cans = [-1, 1, 3, -3] + if self.last in cans: cans.remove(-self.last) - if self.x<3: + if self.x < 3: cans.remove(-3) - if self.x>5: + if self.x > 5: cans.remove(3) - if self.x%3 is 0: + if self.x % 3 is 0: cans.remove(-1) - if self.x%3 is 2: + if self.x % 3 is 2: cans.remove(1) return cans + def move(self): cans = self.can() for i in cans: @@ -65,36 +74,46 @@ class state: s[self.x] = s[tmp] s[tmp] = '9' ct = cantor(s) - if isVisited[ct] != 2 : + if isVisited[ct] != 2: val = int(s[self.x]) - f = h[8][tmp] +h[val-1][self.x]-h[8][self.x]-h[val-1][tmp]+self.step+1 - new = state(s,tmp,f,self.step +1,i) + f = h[8][tmp] + h[val-1][self.x] - \ + h[8][self.x]-h[val-1][tmp]+self.step+1 + new = state(s, tmp, f, self.step + 1, i) new.path = self.path + [dir[i]] if isVisited[ct] == 1: - for i,node in enumerate(que): + for i, node in enumerate(que): if mew.s == node.s: del que[i] break - else:isVisited[ct] = 1 + else: + isVisited[ct] = 1 if que == []: que.append(new) continue - for i,node in enumerate(que): - if new.f<=node.f: - que.insert(i,new) + for i, node in enumerate(que): + if new.f <= node.f: + que.insert(i, new) + + def solvable(s): reverse = 0 for i in range(8): - if s[i] is '9':continue - for j in range(i+1,9): - if s[i]>s[j]:reverse +=1 - if reverse % 2 is 0:return True - else:return False -def getPath(s,index): + if s[i] is '9': + continue + for j in range(i+1, 9): + if s[i] > s[j]: + reverse += 1 + if reverse % 2 is 0: + return True + else: + return False + + +def getPath(s, index): f = 0 - for i,j in enumerate(s): - f+=h[int(j)-1][i] - que.append(state(s,index,f,0,0)) + for i, j in enumerate(s): + f += h[int(j)-1][i] + que.append(state(s, index, f, 0, 0)) while que != []: cur = que.pop(0) ct = cantor(cur.s) @@ -102,28 +121,34 @@ def getPath(s,index): if ct is 0: return cur.path cur.move() + + def info(): print('input a 3x3 matrix in one line') - print('from left to right,from up to down') + print('from left to right,from up to down') print('such as 56831247x represent matrix as follow') print('5 6 8\n3 1 2\n4 7 x') print('then, if it has, I will print the path of moving x to reach state as follows') print('1 2 3\n4 5 6\n7 8 x') print('print q to quit') -from random import shuffle + case = list('12345678x') + + def genCase(): tmp = case.copy() shuffle(tmp) print(f'Using random data: {tmp}') index = -1 - for i,j in enumerate(tmp): - if j=='x': + for i, j in enumerate(tmp): + if j == 'x': index = i break tmp[index] = '9' - return tmp,index + return tmp, index + + def isValid(li): for i in '123456789': if not i in li: @@ -131,12 +156,13 @@ def isValid(li): return False return True + def run(): while 1: - print('\n\n'+'-'*10+'Game Begins'+ '-'*10) + print('\n\n'+'-'*10+'Game Begins' + '-'*10) info() - s=input('input: ') - if s=='q' or s=='Q' or s=='quit': + s = input('input: ') + if s == 'q' or s == 'Q' or s == 'quit': break index = s.find('x') li = list(s) @@ -145,8 +171,9 @@ def run(): if not isValid(li): li, index = genCase() if solvable(li): - print(''.join(getPath(li,index))) - else:print('unsolvable') + print(''.join(getPath(li, index))) + else: + print('unsolvable') if __name__ == '__main__': diff --git a/search/bloomFilter.py b/search/bloomFilter.py index 90598ec..03dffd5 100644 --- a/search/bloomFilter.py +++ b/search/bloomFilter.py @@ -13,22 +13,27 @@ from bitarray import bitarray import mmh3 + class bloomFilter(set): - def __init__(self,size,hash_count): - super(bloomFilter,self).__init__() + def __init__(self, size, hash_count): + super(bloomFilter, self).__init__() self.bits = bitarray(size) self.bits.setall(0) self.size = size self.hash_count = hash_count + def __len__(self): return self.size + def __iter__(self): return iter(self.bits) - def add(self,item): + + def add(self, item): for i in range(self.hash_count): - idx = mmh3.hash(item,i) % self.size - self.bits[idx]=1 + idx = mmh3.hash(item, i) % self.size + self.bits[idx] = 1 return self - def __contains__(self,item): - idxs = [mmh3.hash(item,i)%self.size for i in range(self.hash_count)] - return all([self.bits[i]==1 for i in idxs]) + + def __contains__(self, item): + idxs = [mmh3.hash(item, i) % self.size for i in range(self.hash_count)] + return all([self.bits[i] == 1 for i in idxs]) diff --git a/search/schedule.py b/search/schedule.py index 9a41221..51ac0dd 100644 --- a/search/schedule.py +++ b/search/schedule.py @@ -15,89 +15,105 @@ 设有n个任务由k个可并行工作的机器来完成,完成任务i需要时间为 。试设计一个算法找出完成这n个任务的最佳调度,使完成全部任务的时间最早。 ''' + + + + from time import time from functools import total_ordering @total_ordering class record: - def __init__(self,nums=None): + def __init__(self, nums=None): if nums is None: - nums=[] - self.nums=nums + nums = [] + self.nums = nums self.sum = sum(nums) - def append(self,x): + + def append(self, x): self.nums.append(x) - self.sum+=x + self.sum += x + def pop(self): x = self.nums.pop() - self.sum-=x + self.sum -= x return x + def __repr__(self): return repr(self.nums) - def __lt__(self,r): - return self.sumcost: - best= cost + + +def schedule(works, k): + def backtrackSearch(i, lsts): + nonlocal best, rst + if i == n: + cost = max(r.sum for r in lsts) + if best > cost: + best = cost rst = [st.tolist() for st in lsts] else: for cur in set(lsts): - if best>cur.sum+works[i]: + if best > cur.sum+works[i]: cur.append(works[i]) - backtrackSearch(i+1,lsts) + backtrackSearch(i+1, lsts) cur.pop() - def findInitial(i,lst): + + def findInitial(i, lst): nonlocal best - if i==n: + if i == n: cost = max(lst) - if best>cost:best = cost + if best > cost: + best = cost else: mn = lst[0] idx = 0 - visited=set() - for j,cur in enumerate(lst): + visited = set() + for j, cur in enumerate(lst): if cur not in visited: visited.add(cur) - if mn>cur: + if mn > cur: mn = cur idx = j - lst[idx]+=works[i] - findInitial(i+1,lst) - lst[idx]-=works[i] - + lst[idx] += works[i] + findInitial(i+1, lst) + lst[idx] -= works[i] n = len(works) print() - print('machine Num:',n) - print('works :',works) - rst = None - works.sort(reverse=True) # key step + print('machine Num:', n) + print('works :', works) + rst = None + works.sort(reverse=True) # key step best = sum(works[:n-k+1]) t = time() - findInitial(0,[0]*k) # key step + findInitial(0, [0]*k) # key step t1 = time()-t - print('init solution: {} cost time {:.6f}s'.format(best,t1)) + print('init solution: {} cost time {:.6f}s'.format(best, t1)) t = time() - backtrackSearch(0,[record() for i in range(k)]) + backtrackSearch(0, [record() for i in range(k)]) t2 = time()-t - print('final solution: {} cost time {:.6f}s'.format(best,t2)) - print('schedule plan:',rst) - return best,rst + print('final solution: {} cost time {:.6f}s'.format(best, t2)) + print('schedule plan:', rst) + return best, rst -if __name__=='__main__': + +if __name__ == '__main__': from random import randint - schedule([47,20,28,44,21,45,30,39,28,33],3) - schedule([98,84,50,23,32,99,22,76,72,61,81,39,76,54,37],5) - schedule([39,39,23,45,100,69,21,81,39,55,20,86,34,53,58,99,36,45,46],8) + schedule([47, 20, 28, 44, 21, 45, 30, 39, 28, 33], 3) + schedule([98, 84, 50, 23, 32, 99, 22, 76, 72, 61, 81, 39, 76, 54, 37], 5) + schedule([39, 39, 23, 45, 100, 69, 21, 81, 39, 55, + 20, 86, 34, 53, 58, 99, 36, 45, 46], 8) ''' machine Num: 19 diff --git a/search/work_dispatch.py b/search/work_dispatch.py index 683ba53..65c8645 100644 --- a/search/work_dispatch.py +++ b/search/work_dispatch.py @@ -12,37 +12,39 @@ ''' 设有n件工作要分配给n个人去完成,将工作i分配给第j个人所需费用为c_ij 。试设计一个算法,为每个人分配1件不同的工作,并使总费用达到最小。 ''' + + + + +import random def dispatch(mat): '''mat: matrix of c_ij''' - def _util(i,arrange,cost): + def _util(i, arrange, cost): ''' for i-th work''' - nonlocal total,used,rst - if i==n: - total=cost - rst = arrange.copy() # copy is needed + nonlocal total, used, rst + if i == n: + total = cost + rst = arrange.copy() # copy is needed else: for j in range(n): - if not used[j] and( total is None or cost+mat[i][j] n2: ret= 1 + self.data = None + + def cmp(self, n1, n2): + ret = 0 + if n1 < n2: + ret = -1 + if n1 > n2: + ret = 1 return ret * -1 if self.reverse else ret - def addNode(self,nd): - def _add(prt,chd): - if self.cmp(prt,chd)==0: + + def addNode(self, nd): + def _add(prt, chd): + if self.cmp(prt, chd) == 0: prt.incFreq() return - if self.cmp(prt,chd)<0: + if self.cmp(prt, chd) < 0: - if not isinstance(nd,node):nd=node(nd) - if not self.root : - self.root=node(val) + if not isinstance(nd, node): + nd = node(nd) + if not self.root: + self.root = node(val) else: if self.root == val: self.root.incfreq() else: cur = self.root - def build(self,lst): + + def build(self, lst): dic = {} for i in lst: if i in dic: dic[i].incFreq() else: dic[i] = node(i) - self.data =list( dic.values()) - - + self.data = list(dic.values()) diff --git a/sort/heapSort.py b/sort/heapSort.py index 13971f7..361217c 100644 --- a/sort/heapSort.py +++ b/sort/heapSort.py @@ -11,62 +11,76 @@ ''' from functools import partial + + class heap: - def __init__(self,lst,reverse = False): - self.data= heapify(lst,reverse) - self.cmp = partial(lambda i,j,r:cmp(self.data[i],self.data[j],r),r= reverse) + def __init__(self, lst, reverse=False): + self.data = heapify(lst, reverse) + self.cmp = partial(lambda i, j, r: cmp( + self.data[i], self.data[j], r), r=reverse) + def getTop(self): return self.data[0] - def __getitem__(self,idx): + + def __getitem__(self, idx): return self.data[idx] + def __bool__(self): return self.data != [] + def popTop(self): ret = self.data[0] n = len(self.data) cur = 1 - while cur * 2<=n: + while cur * 2 <= n: chd = cur-1 r_idx = cur*2 l_idx = r_idx-1 - if r_idx==n: + if r_idx == n: self.data[chd] = self.data[l_idx] break - j = l_idx if self.cmp(l_idx,r_idx)<0 else r_idx + j = l_idx if self.cmp(l_idx, r_idx) < 0 else r_idx self.data[chd] = self.data[j] cur = j+1 self.data[cur-1] = self.data[-1] self.data.pop() return ret - def addNode(self,val): + def addNode(self, val): self.data.append(val) self.data = one_heapify(len(self.data)-1) -def cmp(n1,n2,reverse=False): +def cmp(n1, n2, reverse=False): fac = -1 if reverse else 1 - if n1 < n2: return -fac - elif n1 > n2: return fac + if n1 < n2: + return -fac + elif n1 > n2: + return fac return 0 -def heapify(lst,reverse = False): + +def heapify(lst, reverse=False): for i in range(len(lst)): - lst = one_heapify(lst,i,reverse) + lst = one_heapify(lst, i, reverse) return lst -def one_heapify(lst,cur,reverse = False): - cur +=1 - while cur>1: + + +def one_heapify(lst, cur, reverse=False): + cur += 1 + while cur > 1: chd = cur-1 prt = cur//2-1 - if cmp(lst[prt],lst[chd],reverse)<0: + if cmp(lst[prt], lst[chd], reverse) < 0: break - lst[prt],lst[chd] = lst[chd], lst[prt] + lst[prt], lst[chd] = lst[chd], lst[prt] cur = prt+1 return lst -def heapSort(lst,reverse = False): + + +def heapSort(lst, reverse=False): lst = lst.copy() - hp = heap(lst,reverse) + hp = heap(lst, reverse) ret = [] while hp: ret.append(hp.popTop()) @@ -75,10 +89,10 @@ def heapSort(lst,reverse = False): if __name__ == '__main__': from random import randint - n = randint(10,20) - lst = [randint(0,100) for i in range(n)] + n = randint(10, 20) + lst = [randint(0, 100) for i in range(n)] print('random : ', lst) print('small-heap: ', heapify(lst)) - print('big-heap : ', heapify(lst,True)) + print('big-heap : ', heapify(lst, True)) print('ascend : ', heapSort(lst)) - print('descend : ', heapSort(lst,True)) + print('descend : ', heapSort(lst, True)) diff --git a/sort/quickSort.c b/sort/quickSort.c index 549d895..c324b1d 100644 --- a/sort/quickSort.c +++ b/sort/quickSort.c @@ -9,23 +9,28 @@ # Description: ######################################################################### */ -int partition(int *arr,int i,int j) +int partition(int *arr, int i, int j) { - int pivot = arr[j],p=i,q=j; - while(ppivot)--q; - if(p pivot)--q; + + if (p < q)arr[p++] = arr[q]; } - arr[p]=pivot; + + arr[p] = pivot; return p; } -void quickSort(int *arr,int i,int j) +void quickSort(int *arr, int i, int j) { - if(i= b: return + if a >= b: + return mid = (a + b) // 2 # 三数取中值置于第一个作为 pivot if (lst[a] < lst[mid]) ^ (lst[b] < lst[mid]): @@ -55,12 +59,14 @@ def quickSort2(lst): for i in range(a, b): if lst[i] <= pivot: j += 1 - if i != j: lst[i], lst[j] = lst[j], lst[i] + if i != j: + lst[i], lst[j] = lst[j], lst[i] lst[j + 1], lst[b] = lst[b], lst[j + 1] return j + 1 def _sort(a, b): - if a >= b: return + if a >= b: + return mid = (a + b) // 2 # 三数取中值置于第一个作为 pivot if (lst[a] < lst[mid]) ^ (lst[b] < lst[mid]): @@ -84,7 +90,8 @@ def quickSort3(lst): for i in range(a, b): if lst[i] <= pivot: j += 1 - if i != j: lst[i], lst[j] = lst[j], lst[i] + if i != j: + lst[i], lst[j] = lst[j], lst[i] lst[j + 1], lst[b] = lst[b], lst[j + 1] return j + 1 @@ -104,9 +111,6 @@ def quickSort3(lst): return lst -from time import time - - def timer(func, lst, n=100): t = time() for i in range(n): diff --git a/sort/radixSort.py b/sort/radixSort.py index 900e60a..df7e698 100644 --- a/sort/radixSort.py +++ b/sort/radixSort.py @@ -10,43 +10,47 @@ ######################################################################### ''' -def radixSort(lst,radix=10): - ls = [[] for i in range(radix)] - mx = max(lst) - weight = 1 - while mx >= weight: - for i in lst: - ls[(i // weight)%radix].append(i) - weight *= radix - lst = sum(ls,[]) - ls = [[] for i in range(radix)] - return lst - -def countSort(lst,mn,mx): - mark = [0]*(mx-mn+1) - for i in lst: - mark[i-mn]+=1 - ret =[] - for n,i in enumerate(mark): - ret +=[n+mn]*i - return ret - +from random import randint from quickSort import quickSort from time import time -from random import randint -def timer(funcs,span,num=1000000): - lst = [randint(0,span) for i in range(num)] - print('range({}), {} items'.format(span,num)) + + +def radixSort(lst, radix=10): + ls = [[] for i in range(radix)] + mx = max(lst) + weight = 1 + while mx >= weight: + for i in lst: + ls[(i // weight) % radix].append(i) + weight *= radix + lst = sum(ls, []) + ls = [[] for i in range(radix)] + return lst + + +def countSort(lst, mn, mx): + mark = [0]*(mx-mn+1) + for i in lst: + mark[i-mn] += 1 + ret = [] + for n, i in enumerate(mark): + ret += [n+mn]*i + return ret + + +def timer(funcs, span, num=1000000): + lst = [randint(0, span) for i in range(num)] + print('range({}), {} items'.format(span, num)) for func in funcs: data = lst.copy() t = time() func(data) t = time()-t - print('{}: {}s'.format(func.__name__,t)) + print('{}: {}s'.format(func.__name__, t)) if __name__ == '__main__': - timer([quickSort,radixSort,sorted],1000000000000,1000) - timer([quickSort,radixSort,sorted],10000,100000) - lst = [randint(0,100) for i in range(1000)] - print(countSort(lst,0,100)==sorted(lst)) + timer([quickSort, radixSort, sorted], 1000000000000, 1000) + timer([quickSort, radixSort, sorted], 10000, 100000) + lst = [randint(0, 100) for i in range(1000)] + print(countSort(lst, 0, 100) == sorted(lst)) diff --git a/sort/select.py b/sort/select.py index 50c6248..8049f84 100644 --- a/sort/select.py +++ b/sort/select.py @@ -11,39 +11,47 @@ ''' from random import randint -def select(lst,i): + + +def select(lst, i): lst = lst.copy() - def partition(a,b): + + def partition(a, b): pivot = lst[a] - while apivot: b-=1 - if a pivot: + b -= 1 + if a < b: lst[a] = lst[b] - a+=1 - while a=b: return lst[a] + def _select(a, b): + if a >= b: + return lst[a] # randomized select - n = randint(a,b) - lst[a],lst[n] = lst[n],lst[a] - pos = partition(a,b) - if pos>i: - return _select(a,pos-1) - elif pos i: + return _select(a, pos-1) + elif pos < i: + return _select(pos+1, b) + else: + return lst[pos] + return _select(0, len(lst)-1) -if __name__ =='__main__': - lst = [randint(0,1000) for i in range(100)] +if __name__ == '__main__': + lst = [randint(0, 1000) for i in range(100)] st = sorted(lst) for i in range(10): - n = randint(0,99) - print('select {}th: \nexpect: {}\ngot: {}'.format(n,st[n],select(lst,n))) + n = randint(0, 99) + print('select {}th: \nexpect: {}\ngot: {}'.format( + n, st[n], select(lst, n))) diff --git a/sort/shellSort.py b/sort/shellSort.py index 353be43..d9428cb 100644 --- a/sort/shellSort.py +++ b/sort/shellSort.py @@ -10,26 +10,28 @@ ######################################################################### ''' -def shellSort(s,gaps=None): + +def shellSort(s, gaps=None): if gaps is None: - gaps = [127,63,31,15,7,3,1] + gaps = [127, 63, 31, 15, 7, 3, 1] n = len(s) for gap in gaps: - for j in range(gap,n): + for j in range(gap, n): cur = j num = s[j] - while cur>=gap and num < s[cur-gap]: + while cur >= gap and num < s[cur-gap]: s[cur] = s[cur-gap] - cur-=gap + cur -= gap s[cur] = num return s -if __name__=='__main__': + +if __name__ == '__main__': from random import randint import sys n = 20 - if len(sys.argv)>1: + if len(sys.argv) > 1: n = int(sys.argv[1]) - nums = [randint(1,100) for i in range(n)] + nums = [randint(1, 100) for i in range(n)] print(nums) print(shellSort(nums)) diff --git a/string/KMP.py b/string/KMP.py index 6feaa20..69fd6ed 100644 --- a/string/KMP.py +++ b/string/KMP.py @@ -11,48 +11,55 @@ ######################################################################### ''' + def getPrefixFunc(s): '''return the list of prefix function of s''' length = 0 i = 1 n = len(s) ret = [0] - while i mid+ct[mid]:mid = cur + ct[cur] = 1 + while s2[cur-ct[cur]] == s2[cur+ct[cur]]: + ct[cur] += 1 + if cur+ct[cur] > mid+ct[mid]: + mid = cur mx = max(ct) - idxs = [i for i,j in enumerate(ct) if j == mx] + idxs = [i for i, j in enumerate(ct) if j == mx] p = idxs[0] for i in idxs: - if s2[i]=='#':p = i - rst =s2[p-mx+1:p+mx].replace('#','') - return rst - \ No newline at end of file + if s2[i] == '#': + p = i + rst = s2[p-mx+1:p+mx].replace('#', '') + return rst diff --git a/string/markov.py b/string/markov.py index b902811..70e430e 100644 --- a/string/markov.py +++ b/string/markov.py @@ -15,44 +15,50 @@ import re class markov: - def __init__(self,txt): - self.words= self.clean(txt) - self.dic = self.getDic(self.words) - def clean(self,text): - text = text.replace("\n", " "); - text = text.replace("\"", ""); - - # 保证每个标点符号都和前面的单词在一起 - # 这样不会被剔除,保留在马尔可夫链中 - punctuation = [',', '.', ';',':'] - for symbol in punctuation: - text = text.replace(symbol, symbol+" "); - - return re.split(' +',text) - - def getDic(self,words): - dic = {} - end = len(words) - for i in range(1,end): - if words[i-1] not in dic: - dic[words[i-1]] = {words[i]:1} - elif words[i] not in dic[words[i-1]]: - dic[words[i-1]][words[i]] = 1 - else: dic[words[i-1]][words[i]] +=1 - return dic - def getSum(self,dic): - if '%size' not in dic: - dic['%size'] = sum(list(dic.values())) - return dic['%size'] - def nextWord(self,word): - k = randint(1,self.getSum(self.dic[word])) - for i,j in self.dic[word].items(): - k-=j - if k<=0:return i - def genSentence(self,begin = 'I',length = 30): - li = [begin] - nextWord= begin - for i in range(1,length): - nextWord= self.nextWord(nextWord) - li.append(nextWord) - return ' '.join(li) + def __init__(self, txt): + self.words = self.clean(txt) + self.dic = self.getDic(self.words) + + def clean(self, text): + text = text.replace("\n", " ") + text = text.replace("\"", "") + + # 保证每个标点符号都和前面的单词在一起 + # 这样不会被剔除,保留在马尔可夫链中 + punctuation = [',', '.', ';', ':'] + for symbol in punctuation: + text = text.replace(symbol, symbol+" ") + + return re.split(' +', text) + + def getDic(self, words): + dic = {} + end = len(words) + for i in range(1, end): + if words[i-1] not in dic: + dic[words[i-1]] = {words[i]: 1} + elif words[i] not in dic[words[i-1]]: + dic[words[i-1]][words[i]] = 1 + else: + dic[words[i-1]][words[i]] += 1 + return dic + + def getSum(self, dic): + if '%size' not in dic: + dic['%size'] = sum(list(dic.values())) + return dic['%size'] + + def nextWord(self, word): + k = randint(1, self.getSum(self.dic[word])) + for i, j in self.dic[word].items(): + k -= j + if k <= 0: + return i + + def genSentence(self, begin='I', length=30): + li = [begin] + nextWord = begin + for i in range(1, length): + nextWord = self.nextWord(nextWord) + li.append(nextWord) + return ' '.join(li) diff --git a/string/min-window-substring.py b/string/min-window-substring.py index fb834fe..05ce6f5 100644 --- a/string/min-window-substring.py +++ b/string/min-window-substring.py @@ -27,34 +27,37 @@ When the window is no longer valid, start expanding again using the right pointe ''' from collections import defaultdict + + class Solution: def minWindow(self, s: str, t: str) -> str: - def expand(j,lacked,dic): - while jj-i+1: + while j < n and lacked: + j = expand(j, lacked, dic) + if not lacked: + i, lacked = contract(i, j) + if ans == '' or len(ans) > j-i+1: ans = s[i-1:j] - return ans + return ans diff --git a/string/rabin_karp.py b/string/rabin_karp.py index 9467592..b7ec9d5 100644 --- a/string/rabin_karp.py +++ b/string/rabin_karp.py @@ -11,50 +11,62 @@ ######################################################################### ''' + def isPrime(x): - for i in range(2,int(x**0.5)+1): - if x%i==0:return False + for i in range(2, int(x**0.5)+1): + if x % i == 0: + return False return True + + def getPrime(x): '''return a prime which is bigger than x''' - for i in range(x,2*x): - if isPrime(i):return i -def findAll(s,p): + for i in range(x, 2*x): + if isPrime(i): + return i + + +def findAll(s, p): '''s: string p: pattern''' - dic={} - n,m = len(s),len(p) - d=0 #radix + dic = {} + n, m = len(s), len(p) + d = 0 # radix for c in s: if c not in dic: - dic[c]=d - d+=1 + dic[c] = d + d += 1 sm = 0 for c in p: - if c not in dic:return [] + if c not in dic: + return [] sm = sm*d+dic[c] ret = [] cur = 0 - for i in range(m): cur=cur*d + dic[s[i]] - if cur==sm:ret.append(0) + for i in range(m): + cur = cur*d + dic[s[i]] + if cur == sm: + ret.append(0) tmp = n-m q = getPrime(m) - cur = cur%q - sm = sm%q + cur = cur % q + sm = sm % q exp = d**(m-1) % q - for i in range(m,n): + for i in range(m, n): cur = ((cur-dic[s[i-m]]*exp)*d+dic[s[i]]) % q - if cur == sm and p==s[i-m+1:i+1]: + if cur == sm and p == s[i-m+1:i+1]: ret.append(i-m+1) return ret -def randStr(n=3): - return [randint(ord('a'),ord('z')) for i in range(n)] -if __name__ =='__main__': +def randStr(n=3): + return [randint(ord('a'), ord('z')) for i in range(n)] + + +if __name__ == '__main__': from random import randint s = randStr(50) p = randStr(1) print(s) print(p) - print(findAll(s,p)) + print(findAll(s, p)) diff --git a/string/rotate.py b/string/rotate.py index 9a43bfb..970c6ba 100644 --- a/string/rotate.py +++ b/string/rotate.py @@ -17,77 +17,80 @@ ######################################################################### ''' -def rotate(s,k,right=False): - def reverse(a,b): - while a=ns:return -1 + idx = ps + np-pp + if idx >= ns: + return -1 ch = s[idx] if ch in dic: ps += dic[ch]+1-pp else: ps = idx+1 pp = 0 - if pp==np:return ps-np + if pp == np: + return ps-np else: return -1 -def findAll(s,p): + + +def findAll(s, p): ns = len(s) np = len(p) i = 0 ret = [] while s: - print(s,p) - tmp = find(s,p) - if tmp==-1: break + print(s, p) + tmp = find(s, p) + if tmp == -1: + break ret.append(i+tmp) end = tmp+np - i +=end + i += end s = s[end:] return ret - def randStr(n=3): - return [randint(ord('a'),ord('z')) for i in range(n)] + return [randint(ord('a'), ord('z')) for i in range(n)] + def test(n): s = randStr(n) p = randStr(3) str_s = ''.join((chr(i) for i in s)) str_p = ''.join((chr(i) for i in p)) - n1 = find(s,p) - n2 = str_s.find(str_p) # 利用已有的 str find 算法检验 - if n1!=n2: - print(n1,n2,str_p,str_s) + n1 = find(s, p) + n2 = str_s.find(str_p) # 利用已有的 str find 算法检验 + if n1 != n2: + print(n1, n2, str_p, str_s) return False return True -if __name__ =='__main__': + + +if __name__ == '__main__': from random import randint n = 1000 suc = sum(test(n) for i in range(n)) - print('test {n} times, success {suc} times'.format(n=n,suc=suc)) + print('test {n} times, success {suc} times'.format(n=n, suc=suc)) diff --git a/string/wildcard_matching.py b/string/wildcard_matching.py index a553235..932ae8b 100644 --- a/string/wildcard_matching.py +++ b/string/wildcard_matching.py @@ -33,25 +33,26 @@ else : dp[j][i] = dp[j-1][i-1] and s[i] == p[j] # leetcode: q44 https://leetcode.com/problems/wildcard-matching/description/ + def isMatch(self, s, p): """ :type s: str :type p: str pattern str including wildcard :rtype: bool """ - n,m = len(s),len(p) - last = [False]*(n+1) + n, m = len(s), len(p) + last = [False]*(n+1) last[0] = True for j in range(m): - if p[j]=='*': + if p[j] == '*': for i in range(n): last[i+1] = last[i+1] or last[i] - elif p[j]=='?': + elif p[j] == '?': last.pop() - last.insert(0,False) + last.insert(0, False) else: li = [False] for i in range(n): - li.append( last[i] and p[j]==s[i]) + li.append(last[i] and p[j] == s[i]) last = li return last[-1] diff --git a/utils/codecogs.py b/utils/codecogs.py index 7a50639..6aaef0e 100644 --- a/utils/codecogs.py +++ b/utils/codecogs.py @@ -14,39 +14,47 @@ import re import sys from translate import Translator as TR -FORMULA = re.compile(r'\${1,2}(?P.+?)\${1,2}',re.DOTALL) +FORMULA = re.compile(r'\${1,2}(?P.+?)\${1,2}', re.DOTALL) Chinese = re.compile(u"(?P[\u4e00-\u9fa5]+)") API = 'https://latex.codecogs.com/gif.latex?' + + def codecog(f): if os.path.exists(f) and f.endswith('.md'): with open(f) as fp: txt = fp.read() - with open(f,'w') as fp: - fp.write(re.sub(FORMULA,covert,txt)) + with open(f, 'w') as fp: + fp.write(re.sub(FORMULA, covert, txt)) else: - s = re.sub(FORMULA,covert,f) + s = re.sub(FORMULA, covert, f) print(s) + + def covert(matched): s = matched.group('formula').strip('$ ') - s = re.sub(Chinese,zh2en,s) - s = re.sub(r'\r+|\n+|\\n',' ',s) - s = re.sub(' +','&space;',s) - return '![]({})'.format(API+s) + s = re.sub(Chinese, zh2en, s) + s = re.sub(r'\r+|\n+|\\n', ' ', s) + s = re.sub(' +', '&space;', s) + return '![]({})'.format(API+s) + + def zh2en(txt): s = txt.group('chinese').strip() - tran = TR(to_lang='en',from_lang='zh') + tran = TR(to_lang='en', from_lang='zh') en = tran.translate(s) - return re.sub(' +','-',en) + return re.sub(' +', '-', en) + def handle(path): if os.path.isdir(path): - for p,ds,fs in os.walk(path): + for p, ds, fs in os.walk(path): for f in fs: if f.endswith('.md'): - codecog(os.path.join(p,f)) + codecog(os.path.join(p, f)) else: codecog(path) + if __name__ == '__main__': args = sys.argv[1:] if not args: diff --git a/utils/genReadme.py b/utils/genReadme.py index cf8f233..4b2455a 100644 --- a/utils/genReadme.py +++ b/utils/genReadme.py @@ -16,17 +16,18 @@ from config import README parser = ArgumentParser() -parser.add_argument('-p','--path',default='.',help='path to walk') -parser.add_argument('-f','--fileinclude',action='store_true',default=True,help='if has, list files and dirs, else only dirs') -parser.add_argument('-d','--depth', type = int, default = 2) -#获取参数 +parser.add_argument('-p', '--path', default='.', help='path to walk') +parser.add_argument('-f', '--fileinclude', action='store_true', + default=True, help='if has, list files and dirs, else only dirs') +parser.add_argument('-d', '--depth', type=int, default=2) +# 获取参数 args = parser.parse_args() FILE = args.fileinclude PATH = args.path DEPTH = args.depth -idxs = tree(PATH,DEPTH,FILE) +idxs = tree(PATH, DEPTH, FILE) s = README.format(index='\n'.join(idxs)) -with open('README.md','w') as f: +with open('README.md', 'w') as f: f.write(s) diff --git a/utils/headinfo.py b/utils/headinfo.py index ac7df77..6e7ae24 100644 --- a/utils/headinfo.py +++ b/utils/headinfo.py @@ -15,44 +15,55 @@ import sys import time from config import HEAD count = 0 + + def handleFile(path): global count head = getHead(path) - if head =='': return - with open(path,'r',encoding='utf8',errors='ignore') as f: + if head == '': + return + with open(path, 'r', encoding='utf8', errors='ignore') as f: s = f.read() if 'mbinary' in s: return - count +=1 + count += 1 name = os.path.basename(path) - print('[{count}]: Adding head info to {name}'.format(count=count,name=name)) - with open(path,'w') as f: + print('[{count}]: Adding head info to {name}'.format(count=count, name=name)) + with open(path, 'w') as f: f.write(head+s) + def getHead(path): name = os.path.basename(path) # skip self or hidden file - if name == os.path.basename(__file__) or name[0]=='.': return '' - suf = name[name.rfind('.')+1 :] - begin = end ='' + if name == os.path.basename(__file__) or name[0] == '.': + return '' + suf = name[name.rfind('.')+1:] + begin = end = '' if suf == 'py': begin = end = "'''" - elif suf in ['c','cc','cpp','java']: - begin,end = '/*','*/' + elif suf in ['c', 'cc', 'cpp', 'java']: + begin, end = '/*', '*/' elif suf == 'sh': begin = end = '#' - else:return '' + else: + return '' timeStamp = time.localtime(os.stat(path).st_ctime) - ctime = time.strftime('%Y-%m-%d %H:%M',timeStamp) - return HEAD.format(begin=begin,end=end,ctime=ctime,name = name) + ctime = time.strftime('%Y-%m-%d %H:%M', timeStamp) + return HEAD.format(begin=begin, end=end, ctime=ctime, name=name) + def handleDir(dirPath): gen = os.walk(dirPath) - for path,dirs,files in gen: - for f in files: handleFile(os.path.join(path,f)) + for path, dirs, files in gen: + for f in files: + handleFile(os.path.join(path, f)) + + if __name__ == '__main__': works = sys.argv[1:] - if works==[] : works = ['.'] + if works == []: + works = ['.'] for one in works: if not os.path.exists(one): print('[PathError]: {one} not exists'.format(one=one)) diff --git a/utils/tree.py b/utils/tree.py index a0b6ad0..89eccbd 100644 --- a/utils/tree.py +++ b/utils/tree.py @@ -13,42 +13,51 @@ import os from argparse import ArgumentParser -#命令行输入参数处理 +# 命令行输入参数处理 parser = ArgumentParser() -parser.add_argument('-p','--path',default='.',help='path to walk') -parser.add_argument('-f','--fileinclude',action='store_true',help='if has, list files and dirs, else only dirs') -parser.add_argument('-d','--depth', type = int, default = 2) -#获取参数 +parser.add_argument('-p', '--path', default='.', help='path to walk') +parser.add_argument('-f', '--fileinclude', action='store_true', + help='if has, list files and dirs, else only dirs') +parser.add_argument('-d', '--depth', type=int, default=2) +# 获取参数 args = parser.parse_args() FILE = args.fileinclude PATH = args.path DEPTH = args.depth + def mklink(path): - return '* [{name}]({path})'.format(name=os.path.basename(path),path=path) + return '* [{name}]({path})'.format(name=os.path.basename(path), path=path) + + def clean(paths): ret = [] for path in paths: name = os.path.basename(path) - if not ( name.startswith('.') or name.startswith('__')): + if not (name.startswith('.') or name.startswith('__')): ret.append(path) return ret -def tree(path='.',depth=2,showfile=False): + +def tree(path='.', depth=2, showfile=False): li = [] - if os.path.isdir(path):li = os.listdir(path) - else:li=[path] - items = [os.path.join(path,i) for i in li if not i.startswith('.')] + if os.path.isdir(path): + li = os.listdir(path) + else: + li = [path] + items = [os.path.join(path, i) for i in li if not i.startswith('.')] items = clean(items) items = sorted(items) - if not showfile: items = [i for i in items if os.path.isdir(i)] - if depth==1: + if not showfile: + items = [i for i in items if os.path.isdir(i)] + if depth == 1: return [mklink(path)] + [' '*4 + mklink(i) for i in items] else: - uls = [tree(i,depth-1,showfile) for i in items] + uls = [tree(i, depth-1, showfile) for i in items] ret = [' '*4 + li for ul in uls for li in ul] - return [mklink(path)] + ret + return [mklink(path)] + ret -if __name__ =='__main__': - print('\n'.join(tree(PATH,DEPTH,FILE))) + +if __name__ == '__main__': + print('\n'.join(tree(PATH, DEPTH, FILE)))