Format codes

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

View File

@ -6,7 +6,7 @@
[![repo-size](https://img.shields.io/github/repo-size/mbinary/algorithm.svg)]()
[![License](https://img.shields.io/badge/LICENSE-WTFPL-blue.svg)](LICENSE)
[![Language](https://img.shields.io/badge/language-python3-orange.svg)]()
[![codebeat badge](https://codebeat.co/badges/d52dd17d-a437-4dee-a6ec-cb532e8135bd)](https://codebeat.co/projects/github-com-mbinary-algorithm-master)
[![codebeat badge](https://codebeat.co/badges/4ef725b5-405a-4390-a860-a86deefab3f8)](https://codebeat.co/projects/github-com-mbinary-algorithm-master)
>Notes and codes for learning algorithm and data structures :smiley:
@ -17,12 +17,10 @@ Some pictures and ideas are from `<<Introduction to Algotithm>>`
* [.](.)
* [LICENSE](./LICENSE)
* [README.md](./README.md)
* [backtracking](./backtracking)
* [dataStructure](./dataStructure)
* [LRU](./dataStructure/LRU)
* [bTree.py](./dataStructure/bTree.py)
* [binaryHeap.py](./dataStructure/binaryHeap.py)
* [binaryHeap1.py](./dataStructure/binaryHeap1.py)
* [binaryTree.py](./dataStructure/binaryTree.py)
* [circularQueue.py](./dataStructure/circularQueue.py)
* [graph](./dataStructure/graph)
@ -32,7 +30,6 @@ Some pictures and ideas are from `<<Introduction to Algotithm>>`
* [intervalTree.py](./dataStructure/intervalTree.py)
* [leftHeap.py](./dataStructure/leftHeap.py)
* [linkedList.py](./dataStructure/linkedList.py)
* [loserTree.py](./dataStructure/loserTree.py)
* [map.cc](./dataStructure/map.cc)
* [polynomial.cpp](./dataStructure/polynomial.cpp)
* [polynomial.py](./dataStructure/polynomial.py)
@ -40,7 +37,7 @@ Some pictures and ideas are from `<<Introduction to Algotithm>>`
* [redBlackTree0.py](./dataStructure/redBlackTree0.py)
* [splayTree.py](./dataStructure/splayTree.py)
* [trie](./dataStructure/trie)
* [unionFindSet](./dataStructure/unionFindSet)
* [unionFindSet.py](./dataStructure/unionFindSet.py)
* [winnerTree.py](./dataStructure/winnerTree.py)
* [divideAndConquer](./divideAndConquer)
* [min_distance_of_n_points.py](./divideAndConquer/min_distance_of_n_points.py)
@ -85,8 +82,9 @@ Some pictures and ideas are from `<<Introduction to Algotithm>>`
* [PL0-compiler](./parser/PL0-compiler)
* [calculator](./parser/calculator)
* [declarationParser](./parser/declarationParser)
* [poly.c](./poly.c)
* [search](./search)
* [8Astar.py](./search/8Astar.py)
* [Astar.py](./search/Astar.py)
* [BFS_knight.hs](./search/BFS_knight.hs)
* [binary_search.hs](./search/binary_search.hs)
* [bloomFilter.py](./search/bloomFilter.py)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,99 +0,0 @@
#coding: utf-8
''' mbinary
#######################################################################
# File : accountsMerge.py
# Author: mbinary
# Mail: zhuheqin1@gmail.com
# Blog: https://mbinary.xyz
# Github: https://github.com/mbinary
# Created Time: 2018-12-18 17:07
# Description:
给定一个列表 accounts每个元素 accounts[i] 是一个字符串列表其中第一个元素 accounts[i][0] 名称 (name)其余元素是 emails 表示该帐户的邮箱地址
现在我们想合并这些帐户如果两个帐户都有一些共同的邮件地址则两个帐户必定属于同一个人请注意即使两个帐户具有相同的名称它们也可能属于不同的人因为人们可能具有相同的名称一个人最初可以拥有任意数量的帐户但其所有帐户都具有相同的名称
合并帐户后按以下格式返回帐户每个帐户的第一个元素是名称其余元素是按顺序排列的邮箱地址accounts 本身可以以任意顺序返回
例子 1:
Input:
accounts = [["John", "johnsmith@mail.com", "john00@mail.com"], ["John", "johnnybravo@mail.com"], ["John", "johnsmith@mail.com", "john_newyork@mail.com"], ["Mary", "mary@mail.com"]]
Output: [["John", 'john00@mail.com', 'john_newyork@mail.com', 'johnsmith@mail.com'], ["John", "johnnybravo@mail.com"], ["Mary", "mary@mail.com"]]
Explanation:
第一个和第三个 John 是同一个人因为他们有共同的电子邮件 "johnsmith@mail.com"
第二个 John Mary 是不同的人因为他们的电子邮件地址没有被其他帐户使用
#######################################################################
'''
class Solution(object):
def accountsMerge(self, accounts):
"""
:type accounts: List[List[str]]
:rtype: List[List[str]]
"""
mailDic = {}
for ct,i in enumerate(accounts):
for j in i[1:]:
mailDic[j] = (ct,i[0])
mails = {mail:idx for idx,mail in enumerate(mailDic.keys())}
mailNum = len(mails)
self.findSet = [i for i in range(mailNum)]
for li in accounts:
n = len(li)
for i in range(1,n-1):
for j in range(i+1,n):
self.union(mails[li[i]],mails[li[j]])
dic = {}
mails = {j:i for i,j in mails.items()}
for i in range(mailNum):
mail = mails[i]
n = mailDic[mails[self.find(i)]][0]
if n in dic:
dic[n].append(mail)
else:
dic[n] = [mail]
nameId = {i[0]:i[1] for i in mailDic.values()}
return [[nameId[i]]+sorted(mail) for i,mail in dic.items()]
def find(self,i):
if self.findSet[i]!=i:
n = self.find(self.findSet[i])
self.findSet[i] = n
return self.findSet[i]
def union(self,i,j):
if i!=j:
n = self.find(i)
if n!=self.find(j):
self.findSet[n] = self.findSet[j]
class Solution2:
'''并查映射'''
def accountsMerge(self, accounts):
"""
:type accounts: List[List[str]]
:rtype: List[List[str]]
"""
mailDic = {j:ct for ct,i in enumerate(accounts) for j in i[1:]}
self.findSet = {i:i for i in mailDic}
for li in accounts:
n = len(li)
for i in range(1,n-1):
for j in range(i+1,n):
self.union(li[i],li[j])
dic = {}
for mail in self.findSet:
n = mailDic[self.find(mail)]
if n in dic:
dic[n].append(mail)
else:
dic[n] = [mail]
return [[accounts[i][0]]+sorted(mail) for i,mail in dic.items()]
def find(self,i):
if self.findSet[i]!=i:
n = self.find(self.findSet[i])
self.findSet[i] = n
return self.findSet[i]
def union(self,i,j):
if i!=j:
n = self.find(i)
if n!=self.find(j):
self.findSet[n] = self.findSet[j]

View File

@ -1,42 +0,0 @@
#coding: utf-8
''' mbinary
#######################################################################
# File : unionFind.py
# Author: mbinary
# Mail: zhuheqin1@gmail.com
# Blog: https://mbinary.xyz
# Github: https://github.com/mbinary
# Created Time: 2018-12-18 14:53
# Description:
班上有 N 名学生其中有些人是朋友有些则不是他们的友谊具有是传递性如果已知 A B 的朋友B C 的朋友那么我们可以认为 A 也是 C 的朋友所谓的朋友圈是指所有朋友的集合
给定一个 N * N 的矩阵 M表示班级中学生之间的朋友关系如果 M[i][j] = 1表示已知第 i 个和 j 个学生互为朋友关系否则为不知道你必须输出所有学生中的已知的朋友圈总数
#######################################################################
'''
class Solution(object):
def findCircleNum(self, M):
"""
:type M: List[List[int]]
:rtype: int
"""
n = len(M)
self.data = [i for i in range(n)]
for i in range(n):
for j in range(n):
if M[i][j]==1:
self.union(i,j)
ret = set()
for i in range(n):
ret.add(self.find(i))
return len(ret)
def find(self,i):
if self.data[i]!=i:
self.data[i] = self.find(self.data[i])
return self.data[i]
def union(self,i,j):
if i!=j:
n = self.find(i)
if n!=self.find(j):
self.data[n]= self.data[j]

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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)}')

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -12,56 +12,61 @@
from random import randint
def quickMulMod(a,b,m):
def quickMulMod(a, b, m):
'''a*b%m, quick'''
ret = 0
while b:
if b&1:
ret = (a+ret)%m
b//=2
a = (a+a)%m
if b & 1:
ret = (a+ret) % m
b //= 2
a = (a+a) % m
return ret
def quickPowMod(a,b,m):
def quickPowMod(a, b, m):
'''a^b %m, quick, O(logn)'''
ret =1
ret = 1
while b:
if b&1:
ret =quickMulMod(ret,a,m)
b//=2
a = quickMulMod(a,a,m)
if b & 1:
ret = quickMulMod(ret, a, m)
b //= 2
a = quickMulMod(a, a, m)
return ret
def isPrime(n,t=5):
def isPrime(n, t=5):
'''miller rabin primality test, a probability result
t is the number of iteration(witness)
'''
t = min(n-3,t)
if n<2:
t = min(n-3, t)
if n < 2:
print('[Error]: {} can\'t be classed with prime or composite'.format(n))
return
if n==2: return True
if n == 2:
return True
d = n-1
r = 0
while d%2==0:
r+=1
d//=2
tested=set()
while d % 2 == 0:
r += 1
d //= 2
tested = set()
for i in range(t):
a = randint(2,n-2)
a = randint(2, n-2)
while a in tested:
a = randint(2,n-2)
a = randint(2, n-2)
tested.add(a)
x= quickPowMod(a,d,n)
if x==1 or x==n-1: continue #success,
x = quickPowMod(a, d, n)
if x == 1 or x == n-1:
continue # success,
for j in range(r-1):
x= quickMulMod(x,x,n)
if x==n-1:break
x = quickMulMod(x, x, n)
if x == n-1:
break
else:
return False
return True
'''
we shouldn't use Fermat's little theory
Namyly:
@ -73,49 +78,23 @@ The inverse theorem of it is not True.
a counter-example: 2^340 \equiv 1 (mod 341), but 341 is a composite
'''
class primeSieve:
'''sieve of Eratosthenes, It will be more efficient when judging many times'''
primes = [2,3,5,7,11,13]
def isPrime(self,x):
if x<=primes[-1]:
return twoDivideFind(x,self.primes)
while x>self.primes[-1]:
left = self.primes[-1]
right = (left+1)**2
lst = []
for i in range(left,right):
for j in self.primes:
if i%j==0:break
else:lst.append(i)
self.primes+=lst
return twoDivideFind(x,lst)
def nPrime(n):
'''return the n-th prime'''
i=n-len(self.primes)
last = self.primes[-1]
for _ in range(i):
while 1:
last +=2
for p in self.primes:
if last%p==0:
break
else:
self.primes.append(last)
break
return self.primes[n-1]
def twoDivideFind(x,li):
a,b = 0, len(li)
while a<=b:
def twoDivideFind(x, li):
a, b = 0, len(li)
while a <= b:
mid = (a+b)//2
if li[mid]<x:a=mid+1
elif li[mid]>x: b= mid-1
else:return mid
if li[mid] < x:
a = mid+1
elif li[mid] > x:
b = mid-1
else:
return mid
return -1
if __name__=='__main__':
if __name__ == '__main__':
n = 100
print('prime numbers below',n)
print('prime numbers below', n)
print([i for i in range(n) if isPrime(i)])
while 1:
n = int(input('n: '))

View File

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

View File

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

View File

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

View File

@ -26,58 +26,65 @@ from collections import namedtuple
from functools import reduce
from 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)

View File

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

View File

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

View File

@ -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)
'''

View File

@ -1,13 +0,0 @@
''' mbinary
#########################################################################
# File : numerical_differential.py
# Author: mbinary
# Mail: zhuheqin1@gmail.com
# Blog: https://mbinary.xyz
# Github: https://github.com/mbinary
# Created Time: 2018-10-02 21:14
# Description:
#########################################################################
'''

View File

@ -18,53 +18,56 @@
# Blog: https://mbinary.xyz
# 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)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -11,48 +11,55 @@
#########################################################################
'''
def getPrefixFunc(s):
'''return the list of prefix function of s'''
length = 0
i = 1
n = len(s)
ret = [0]
while i<n:
if s[i]==s[length]:
length +=1
while i < n:
if s[i] == s[length]:
length += 1
ret.append(length)
i+=1
i += 1
else:
if length==0:
if length == 0:
ret.append(0)
i+=1
i += 1
else:
length = ret[length-1]
return ret
def findAll(s,p):
pre = getPrefixFunc(p)
i = j =0
n,m = len(s),len(p)
ret = []
while i<n:
if s[i]==p[j]:
i+=1
j+=1
if j==m:
ret.append(i-j)
j=pre[j-1]
else:
if j==0: i+=1
else: j = pre[j-1]
return ret
def randStr(n=3):
return [randint(ord('a'),ord('z')) for i in range(n)]
if __name__ =='__main__':
def findAll(s, p):
pre = getPrefixFunc(p)
i = j = 0
n, m = len(s), len(p)
ret = []
while i < n:
if s[i] == p[j]:
i += 1
j += 1
if j == m:
ret.append(i-j)
j = pre[j-1]
else:
if j == 0:
i += 1
else:
j = pre[j-1]
return ret
def randStr(n=3):
return [randint(ord('a'), ord('z')) for i in range(n)]
if __name__ == '__main__':
from random import randint
s = randStr(50)
p = randStr(1)
print(s)
print(p)
print(findAll(s,p))
print(findAll(s, p))

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -33,25 +33,26 @@ else : dp[j][i] = dp[j-1][i-1] and s[i] == p[j]
# leetcode: q44 https://leetcode.com/problems/wildcard-matching/description/
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]

View File

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

View File

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

View File

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

View File

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