Format codes

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

View File

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

View File

@ -10,61 +10,87 @@
######################################################################### #########################################################################
''' '''
class node: class node:
def __init__(self, keys=None, isLeaf=True, children=None): def __init__(self, keys=None, isLeaf=True, children=None):
if keys is None:keys=[] if keys is None:
if children is None: children =[] keys = []
if children is None:
children = []
self.keys = keys self.keys = keys
self.isLeaf = isLeaf self.isLeaf = isLeaf
self.children = [] self.children = []
def __getitem__(self, i): def __getitem__(self, i):
return self.keys[i] return self.keys[i]
def __delitem__(self, i): def __delitem__(self, i):
del self.keys[i] del self.keys[i]
def __setitem__(self, i, k): def __setitem__(self, i, k):
self.keys[i] = k self.keys[i] = k
def __len__(self): def __len__(self):
return len(self.keys) return len(self.keys)
def __repr__(self): def __repr__(self):
return str(self.keys) return str(self.keys)
def __str__(self): def __str__(self):
children = ','.join([str(nd.keys) for nd in self.children]) children = ','.join([str(nd.keys) for nd in self.children])
return f'keys: {self.keys}\nchildren: {children}\nisLeaf: {self.isLeaf}' return f'keys: {self.keys}\nchildren: {children}\nisLeaf: {self.isLeaf}'
def getChd(self, i): def getChd(self, i):
return self.children[i] return self.children[i]
def delChd(self, i): def delChd(self, i):
del self.children[i] del self.children[i]
def setChd(self, i, chd): def setChd(self, i, chd):
self.children[i] = chd self.children[i] = chd
def getChildren(self, begin=0, end=None): def getChildren(self, begin=0, end=None):
if end is None:return self.children[begin:] if end is None:
return self.children[begin:]
return self.children[begin:end] return self.children[begin:end]
def findKey(self, key): def findKey(self, key):
for i, k in enumerate(self.keys): for i, k in enumerate(self.keys):
if k >= key: if k >= key:
return i return i
return len(self) return len(self)
def update(self, keys=None, isLeaf=None, children=None): def update(self, keys=None, isLeaf=None, children=None):
if keys is not None:self.keys = keys if keys is not None:
if children is not None:self.children = children self.keys = keys
if isLeaf is not None: self.isLeaf = isLeaf if children is not None:
self.children = children
if isLeaf is not None:
self.isLeaf = isLeaf
def insert(self, i, key=None, nd=None): def insert(self, i, key=None, nd=None):
if key is not None:self.keys.insert(i,key) if key is not None:
if not self.isLeaf and nd is not None: self.children.insert(i,nd) 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 isLeafNode(self): return self.isLeaf
def split(self, prt, t): def split(self, prt, t):
# form new two nodes # form new two nodes
k = self[t-1] k = self[t-1]
nd1 = node() nd1 = node()
nd2 = node() nd2 = node()
nd1.keys,nd2.keys = self[:t-1], self[t:] # note that t is 1 bigger than key index # note that t is 1 bigger than key index
nd1.keys, nd2.keys = self[:t-1], self[t:]
nd1.isLeaf = nd2.isLeaf = self.isLeaf nd1.isLeaf = nd2.isLeaf = self.isLeaf
if not self.isLeaf: if not self.isLeaf:
# note that children index is one bigger than key index, and all children included # note that children index is one bigger than key index, and all children included
nd1.children, nd2.children = self.children[0:t], self.children[t:] nd1.children, nd2.children = self.children[0:t], self.children[t:]
# connect them to parent # connect them to parent
idx = prt.findKey(k) idx = prt.findKey(k)
if prt.children !=[]: prt.children.remove(self) # remove the original node if prt.children != []:
prt.children.remove(self) # remove the original node
prt.insert(idx, k, nd2) prt.insert(idx, k, nd2)
prt.insert(idx, nd=nd1) prt.insert(idx, nd=nd1)
return prt return prt
@ -76,20 +102,28 @@ class bTree:
self.degree = degree self.degree = degree
self.nodeNum = 1 self.nodeNum = 1
self.keyNum = 0 self.keyNum = 0
def search(self, key, withpath=False): def search(self, key, withpath=False):
nd = self.root nd = self.root
fathers = [] fathers = []
while True: while True:
i = nd.findKey(key) i = nd.findKey(key)
if i==len(nd): fathers.append((nd,i-1,i)) if i == len(nd):
else: fathers.append((nd,i,i)) fathers.append((nd, i-1, i))
else:
fathers.append((nd, i, i))
if i < len(nd) and nd[i] == key: if i < len(nd) and nd[i] == key:
if withpath:return nd,i,fathers if withpath:
else:return nd,i return nd, i, fathers
else:
return nd, i
if nd.isLeafNode(): if nd.isLeafNode():
if withpath:return None,None,None if withpath:
else:return None,None return None, None, None
else:
return None, None
nd = nd.getChd(i) nd = nd.getChd(i)
def insert(self, key): def insert(self, key):
if len(self.root) == self.degree*2-1: if len(self.root) == self.degree*2-1:
self.root = self.root.split(node(isLeaf=False), self.degree) self.root = self.root.split(node(isLeaf=False), self.degree)
@ -97,22 +131,26 @@ class bTree:
nd = self.root nd = self.root
while True: while True:
idx = nd.findKey(key) idx = nd.findKey(key)
if idx<len(nd) and nd[idx] == key:return if idx < len(nd) and nd[idx] == key:
return
if nd.isLeafNode(): if nd.isLeafNode():
nd.insert(idx, key) nd.insert(idx, key)
self.keyNum += 1 self.keyNum += 1
return return
else: else:
chd = nd.getChd(idx) chd = nd.getChd(idx)
if len(chd)== self.degree*2-1: #ensure its keys won't excess when its chd split and u # ensure its keys won't excess when its chd split and u
if len(chd) == self.degree*2-1:
nd = chd.split(nd, self.degree) nd = chd.split(nd, self.degree)
self.nodeNum += 1 self.nodeNum += 1
else: else:
nd = chd nd = chd
def delete(self, key): # to do def delete(self, key): # to do
'''search the key, delete it , and form down to up to rebalance it ''' '''search the key, delete it , and form down to up to rebalance it '''
nd, idx, fathers = self.search(key, withpath=True) nd, idx, fathers = self.search(key, withpath=True)
if nd is None : return if nd is None:
return
del nd[idx] del nd[idx]
self.keyNum -= 1 self.keyNum -= 1
if not nd.isLeafNode(): if not nd.isLeafNode():
@ -123,7 +161,9 @@ class bTree:
fathers.append((chd, len(chd)-1, len(chd))) fathers.append((chd, len(chd)-1, len(chd)))
nd.insert(idx, chd[-1]) nd.insert(idx, chd[-1])
del chd[-1] del chd[-1]
if len(fathers)>1:self.rebalance(fathers) if len(fathers) > 1:
self.rebalance(fathers)
def rebalance(self, fathers): def rebalance(self, fathers):
nd, keyIdx, chdIdx = fathers.pop() nd, keyIdx, chdIdx = fathers.pop()
while len(nd) < self.degree-1: # rebalance tree from down to up while len(nd) < self.degree-1: # rebalance tree from down to up
@ -169,6 +209,7 @@ class bTree:
self.nodeNum -= 1 self.nodeNum -= 1
break break
nd, i, j = fathers.pop() nd, i, j = fathers.pop()
def __str__(self): def __str__(self):
head = '\n'+'-'*30+'B Tree'+'-'*30 head = '\n'+'-'*30+'B Tree'+'-'*30
tail = '-'*30+'the end'+'-'*30+'\n' tail = '-'*30+'the end'+'-'*30+'\n'
@ -190,13 +231,16 @@ class bTree:
lst.append([tail]) lst.append([tail])
lst = [','.join(li) for li in lst] lst = [','.join(li) for li in lst]
return '\n'.join(lst) return '\n'.join(lst)
def __iter__(self, nd=None): def __iter__(self, nd=None):
if nd is None: nd = self.root if nd is None:
nd = self.root
que = [nd] que = [nd]
while que != []: while que != []:
nd = que.pop(0) nd = que.pop(0)
yield nd yield nd
if nd.isLeafNode():continue if nd.isLeafNode():
continue
for i in range(len(nd)+1): for i in range(len(nd)+1):
que.append(nd.getChd(i)) que.append(nd.getChd(i))

View File

@ -12,42 +12,62 @@
from collections import Iterable from collections import Iterable
class node: class node:
def __init__(self, val, freq=1): def __init__(self, val, freq=1):
self.val = val self.val = val
self.freq = freq self.freq = freq
def __eq__(self, a): def __eq__(self, a):
return self.val == a.val return self.val == a.val
def __lt__(self, a): def __lt__(self, a):
return self.val < a.val return self.val < a.val
def __le__(self, a): def __le__(self, a):
return self.val <= a.val return self.val <= a.val
def __gt__(self, a): def __gt__(self, a):
return self.val > a.val return self.val > a.val
def __ge__(self, a): def __ge__(self, a):
return self.val >= a.val return self.val >= a.val
def __ne__(self, a): def __ne__(self, a):
return not self == a return not self == a
class binaryHeap: class binaryHeap:
def __init__(self, s=None, sortByFrequency=False, reverse=False): def __init__(self, s=None, sortByFrequency=False, reverse=False):
self.sortByFrequency = sortByFrequency self.sortByFrequency = sortByFrequency
self.reverse = reverse self.reverse = reverse
self.data = [node(0)] # make index begin with 1 self.data = [node(0)] # make index begin with 1
if s==None:return if s == None:
if not isinstance(s,Iterable):s = [s] return
if not isinstance(s, Iterable):
s = [s]
for i in s: for i in s:
self.insert(i) self.insert(i)
def __bool__(self): def __bool__(self):
return len(self) != 1 return len(self) != 1
def _cmp(self, a, b): def _cmp(self, a, b):
if self.sortByFrequency: if self.sortByFrequency:
if self.reverse:return a.freq>b.freq if self.reverse:
else:return a.freq<b.freq return a.freq > b.freq
else: else:
if self.reverse:return a>b return a.freq < b.freq
else:return a<b else:
if self.reverse:
return a > b
else:
return a < b
def insert(self, k): def insert(self, k):
if not isinstance(k,node): k = node(k) if not isinstance(k, node):
k = node(k)
for j in range(self.data[0].val): for j in range(self.data[0].val):
i = self.data[j+1] i = self.data[j+1]
if i == k: if i == k:
@ -59,13 +79,16 @@ class binaryHeap:
self.data.append(k) self.data.append(k)
self.data[0].val += 1 self.data[0].val += 1
self.percolateUp() self.percolateUp()
def percolateUp(self, n=None): def percolateUp(self, n=None):
if n ==None:n=self.data[0].val if n == None:
n = self.data[0].val
tmp = self.data[n] tmp = self.data[n]
while n != 1 and self._cmp(tmp, self.data[n//2]): while n != 1 and self._cmp(tmp, self.data[n//2]):
self.data[n] = self.data[n//2] self.data[n] = self.data[n//2]
n = n//2 n = n//2
self.data[n] = tmp self.data[n] = tmp
def deleteTop(self): def deleteTop(self):
tmp = self.data[1] tmp = self.data[1]
i = self.percolateDown(1) i = self.percolateDown(1)
@ -73,6 +96,7 @@ class binaryHeap:
self.data[0].val -= 1 self.data[0].val -= 1
del self.data[-1] del self.data[-1]
return tmp return tmp
def percolateDown(self, i): def percolateDown(self, i):
tmp = self.data[i] tmp = self.data[i]
while self.data[0].val >= 2*i+1: while self.data[0].val >= 2*i+1:
@ -84,8 +108,10 @@ class binaryHeap:
i = 2*i+1 i = 2*i+1
self.data[i] = tmp self.data[i] = tmp
return i return i
def __len__(self): def __len__(self):
return self.data[0].val return self.data[0].val
def Nth(self, n=1): def Nth(self, n=1):
tmp = [] tmp = []
for i in range(n): for i in range(n):
@ -93,14 +119,17 @@ class binaryHeap:
for i in tmp: for i in tmp:
self.insert(i) self.insert(i)
return tmp[-1] return tmp[-1]
def display(self): def display(self):
val = self.data[0].val+1 val = self.data[0].val+1
if self.sortByFrequency: if self.sortByFrequency:
info = 'heapSort by Frequency:' info = 'heapSort by Frequency:'
else:info = 'heapSort by Value:' else:
info = 'heapSort by Value:'
if self.reverse: if self.reverse:
info += ' From big to small' info += ' From big to small'
else:info +=' From small to big' else:
info += ' From small to big'
print('*'*15) print('*'*15)
print(info) print(info)
print('total items:%d\nval\tfreq' % (val-1)) print('total items:%d\nval\tfreq' % (val-1))
@ -108,6 +137,8 @@ class binaryHeap:
for i in range(1, val): for i in range(1, val):
print(fmt.format(self.data[i].val, self.data[i].freq)) print(fmt.format(self.data[i].val, self.data[i].freq))
print('*'*15) print('*'*15)
class Test: class Test:
def topKFrequent(self, words, k): def topKFrequent(self, words, k):
hp = binaryHeap(sortByFrequency=True, reverse=True) hp = binaryHeap(sortByFrequency=True, reverse=True)
@ -131,8 +162,12 @@ class Test:
for j in mp[i]: for j in mp[i]:
rst.append(j) rst.append(j)
count += 1 count += 1
if count == k:return rst if count == k:
return rst
if __name__ == '__main__': if __name__ == '__main__':
s=["plpaboutit","jnoqzdute","sfvkdqf","mjc","nkpllqzjzp","foqqenbey","ssnanizsav","nkpllqzjzp","sfvkdqf","isnjmy","pnqsz","hhqpvvt","fvvdtpnzx","jkqonvenhx","cyxwlef","hhqpvvt","fvvdtpnzx","plpaboutit","sfvkdqf","mjc","fvvdtpnzx","bwumsj","foqqenbey","isnjmy","nkpllqzjzp","hhqpvvt","foqqenbey","fvvdtpnzx","bwumsj","hhqpvvt","fvvdtpnzx","jkqonvenhx","jnoqzdute","foqqenbey","jnoqzdute","foqqenbey","hhqpvvt","ssnanizsav","mjc","foqqenbey","bwumsj","ssnanizsav","fvvdtpnzx","nkpllqzjzp","jkqonvenhx","hhqpvvt","mjc","isnjmy","bwumsj","pnqsz","hhqpvvt","nkpllqzjzp","jnoqzdute","pnqsz","nkpllqzjzp","jnoqzdute","foqqenbey","nkpllqzjzp","hhqpvvt","fvvdtpnzx","plpaboutit","jnoqzdute","sfvkdqf","fvvdtpnzx","jkqonvenhx","jnoqzdute","nkpllqzjzp","jnoqzdute","fvvdtpnzx","jkqonvenhx","hhqpvvt","isnjmy","jkqonvenhx","ssnanizsav","jnoqzdute","jkqonvenhx","fvvdtpnzx","hhqpvvt","bwumsj","nkpllqzjzp","bwumsj","jkqonvenhx","jnoqzdute","pnqsz","foqqenbey","sfvkdqf","sfvkdqf"] s = ["plpaboutit", "jnoqzdute", "sfvkdqf", "mjc", "nkpllqzjzp", "foqqenbey", "ssnanizsav", "nkpllqzjzp", "sfvkdqf", "isnjmy", "pnqsz", "hhqpvvt", "fvvdtpnzx", "jkqonvenhx", "cyxwlef", "hhqpvvt", "fvvdtpnzx", "plpaboutit", "sfvkdqf", "mjc", "fvvdtpnzx", "bwumsj", "foqqenbey", "isnjmy", "nkpllqzjzp", "hhqpvvt", "foqqenbey", "fvvdtpnzx", "bwumsj", "hhqpvvt", "fvvdtpnzx", "jkqonvenhx", "jnoqzdute", "foqqenbey", "jnoqzdute", "foqqenbey", "hhqpvvt", "ssnanizsav", "mjc", "foqqenbey", "bwumsj", "ssnanizsav", "fvvdtpnzx", "nkpllqzjzp",
"jkqonvenhx", "hhqpvvt", "mjc", "isnjmy", "bwumsj", "pnqsz", "hhqpvvt", "nkpllqzjzp", "jnoqzdute", "pnqsz", "nkpllqzjzp", "jnoqzdute", "foqqenbey", "nkpllqzjzp", "hhqpvvt", "fvvdtpnzx", "plpaboutit", "jnoqzdute", "sfvkdqf", "fvvdtpnzx", "jkqonvenhx", "jnoqzdute", "nkpllqzjzp", "jnoqzdute", "fvvdtpnzx", "jkqonvenhx", "hhqpvvt", "isnjmy", "jkqonvenhx", "ssnanizsav", "jnoqzdute", "jkqonvenhx", "fvvdtpnzx", "hhqpvvt", "bwumsj", "nkpllqzjzp", "bwumsj", "jkqonvenhx", "jnoqzdute", "pnqsz", "foqqenbey", "sfvkdqf", "sfvkdqf"]
test = Test() test = Test()
print(test.topKFrequent(s, 5)) print(test.topKFrequent(s, 5))

View File

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

View File

@ -9,6 +9,8 @@
# Description: # Description:
######################################################################### #########################################################################
''' '''
class MyCircularQueue: class MyCircularQueue:
def __init__(self, k): def __init__(self, k):
@ -31,6 +33,7 @@ class MyCircularQueue:
self.data[self.rear] = value self.data[self.rear] = value
self.rear = (self.rear+1) % self.size self.rear = (self.rear+1) % self.size
return True return True
def deQueue(self): def deQueue(self):
""" """
Delete an element from the circular queue. Return true if the operation is successful. Delete an element from the circular queue. Return true if the operation is successful.
@ -50,7 +53,6 @@ class MyCircularQueue:
return -1 return -1
return self.data[self.head] return self.data[self.head]
def Rear(self): def Rear(self):
""" """
Get the last item from the queue. Get the last item from the queue.
@ -67,7 +69,6 @@ class MyCircularQueue:
""" """
return self.head == self.rear return self.head == self.rear
def isFull(self): def isFull(self):
""" """
Checks whether the circular queue is full or not. Checks whether the circular queue is full or not.
@ -76,7 +77,6 @@ class MyCircularQueue:
return (self.head - self.rear) % self.size == 1 return (self.head - self.rear) % self.size == 1
# Your MyCircularQueue object will be instantiated and called as such: # Your MyCircularQueue object will be instantiated and called as such:
# obj = MyCircularQueue(k) # obj = MyCircularQueue(k)
# param_1 = obj.enQueue(value) # param_1 = obj.enQueue(value)

View File

@ -10,18 +10,23 @@
######################################################################### #########################################################################
''' '''
class item: class item:
def __init__(self, key, val, nextItem=None): def __init__(self, key, val, nextItem=None):
self.key = key self.key = key
self.val = val self.val = val
self.next = nextItem self.next = nextItem
def to(self, it): def to(self, it):
self.next = it self.next = it
def __eq__(self, it): def __eq__(self, it):
'''using keyword <in> ''' '''using keyword <in> '''
return self.key == it.key return self.key == it.key
def __bool__(self): def __bool__(self):
return self.key is not None return self.key is not None
def __str__(self): def __str__(self):
li = [] li = []
nd = self nd = self
@ -29,17 +34,22 @@ class item:
li.append(f'({nd.key}:{nd.val})') li.append(f'({nd.key}:{nd.val})')
nd = nd.next nd = nd.next
return ' -> '.join(li) return ' -> '.join(li)
def __repr__(self): def __repr__(self):
return f'item({self.key},{self.val})' return f'item({self.key},{self.val})'
class hashTable: class hashTable:
def __init__(self, size=100): def __init__(self, size=100):
self.size = size self.size = size
self.slots = [item(None, None) for i in range(self.size)] self.slots = [item(None, None) for i in range(self.size)]
def __setitem__(self, key, val): def __setitem__(self, key, val):
nd = self.slots[self.myhash(key)] nd = self.slots[self.myhash(key)]
while nd.next: while nd.next:
if nd.key == key: if nd.key == key:
if nd.val!=val: nd.val=val if nd.val != val:
nd.val = val
return return
nd = nd.next nd = nd.next
nd.next = item(key, val) nd.next = item(key, val)
@ -50,6 +60,7 @@ class hashTable:
if not isinstance(key, int): if not isinstance(key, int):
key = hash(key) key = hash(key)
return key % self.size return key % self.size
def __iter__(self): def __iter__(self):
'''when using keyword <in>, such as ' if key in dic', '''when using keyword <in>, such as ' if key in dic',
the dic's __iter__ method will be called,(if hasn't, calls __getitem__ the dic's __iter__ method will be called,(if hasn't, calls __getitem__
@ -60,13 +71,15 @@ class hashTable:
while nd: while nd:
yield nd.key yield nd.key
nd = nd.next nd = nd.next
def __getitem__(self, key): def __getitem__(self, key):
nd = self.slots[self.myhash(key)].next nd = self.slots[self.myhash(key)].next
while nd: while nd:
if nd.key == key: if nd.key == key:
return nd.val return nd.val
nd = nd.next nd = nd.next
raise Exception(f'[KeyError]: {self.__class__.__name__} has no key {key}') raise Exception(
f'[KeyError]: {self.__class__.__name__} has no key {key}')
def __delitem__(self, key): def __delitem__(self, key):
'''note that None item and item(None,None) differ with each other, '''note that None item and item(None,None) differ with each other,
@ -78,13 +91,16 @@ class hashTable:
if nd.key == key: if nd.key == key:
if nd.next is None: if nd.next is None:
self.slots[n] = item(None, None) # be careful self.slots[n] = item(None, None) # be careful
else:self.slots[n] = nd.next else:
self.slots[n] = nd.next
return return
while nd: while nd:
if nd.next is None: break # necessary if nd.next is None:
break # necessary
if nd.next.key == key: if nd.next.key == key:
nd.next = nd.next.next nd.next = nd.next.next
nd = nd.next nd = nd.next
def __str__(self): def __str__(self):
li = ['\n\n'+'-'*5+'hashTable'+'-'*5] li = ['\n\n'+'-'*5+'hashTable'+'-'*5]
for i, nd in enumerate(self.slots): for i, nd in enumerate(self.slots):

View File

@ -30,36 +30,47 @@ void cat(string s)
{ {
FILE* f = fopen(s.c_str(), "rb"); FILE* f = fopen(s.c_str(), "rb");
cout << "file content" << endl; cout << "file content" << endl;
while (!feof(f)) { while (!feof(f)) {
cout << fgetc(f); cout << fgetc(f);
} }
cout << endl; cout << endl;
} }
string uniFileName(string file) string uniFileName(string file)
{ {
FILE * check = fopen(file.c_str(), "rb"); FILE * check = fopen(file.c_str(), "rb");
if (check) { if (check) {
char c; char c;
cout << "the file " << file << " already exists! continue? [Y/n]:" << flush; cout << "the file " << file << " already exists! continue? [Y/n]:" << flush;
c = cin.get(); c = cin.get();
if (c == 'n')exit(0); if (c == 'n')exit(0);
int p, q; int p, q;
p = file.find('('); p = file.find('(');
q = file.rfind('.'); q = file.rfind('.');
if (q == string::npos)q = file.size(); if (q == string::npos)q = file.size();
if (p == string::npos)p = q; if (p == string::npos)p = q;
string name = file.substr(0, p), suffix = file.substr(q, file.size()); string name = file.substr(0, p), suffix = file.substr(q, file.size());
int n = 0; int n = 0;
while (true) { while (true) {
char s[3]; char s[3];
n += 1; n += 1;
snprintf(s, 3, "%d", n); snprintf(s, 3, "%d", n);
file = (name + "(" + s + ")" + suffix); file = (name + "(" + s + ")" + suffix);
FILE* f = fopen(file.c_str(), "rb"); FILE* f = fopen(file.c_str(), "rb");
if (!f)break; if (!f)break;
else fclose(f); else fclose(f);
} }
} }
return file; return file;
} }
template<class t1, class t2> template<class t1, class t2>
@ -76,9 +87,19 @@ class node
wt val; wt val;
bool visited; bool visited;
node * left, *right; node * left, *right;
node(const node &a){val = a.val;key= a.key;visited = a.visited;left= a.left;right=a.right;} node(const node &a)
{
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) {}; 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;}; bool operator<(const node<ky, wt> & a)const
{
return val > a.val;
};
}; };
template<typename ky, typename wt> template<typename ky, typename wt>
class huffman class huffman
@ -87,7 +108,10 @@ private:
node<ky, wt> root; node<ky, wt> root;
string res; string res;
public: public:
long total(){return root.val;} long total()
{
return root.val;
}
map<ky, string> encode_map; map<ky, string> encode_map;
map<string, ky> decode_map; map<string, ky> decode_map;
huffman(map<ky, wt>& mp); huffman(map<ky, wt>& mp);
@ -104,15 +128,20 @@ huffman<ky,wt>::huffman(map<ky,wt>& mp)
root = NULL; root = NULL;
return ; return ;
} }
priority_queue<node<ky, wt> > hp; priority_queue<node<ky, wt> > hp;
for (typename map<ky, wt>::iterator i = mp.begin(); i != mp.end(); ++i) { for (typename map<ky, wt>::iterator i = mp.begin(); i != mp.end(); ++i) {
hp.push(node<ky, wt>(i->first, i->second)); hp.push(node<ky, wt>(i->first, i->second));
} }
int n = hp.size(); int n = hp.size();
if (n == 1) { if (n == 1) {
root = hp.top(); root = hp.top();
return; return;
} }
while (--n >= 1) { while (--n >= 1) {
node<ky, wt> *a = new node<ky, wt>(hp.top()); node<ky, wt> *a = new node<ky, wt>(hp.top());
hp.pop(); hp.pop();
@ -122,6 +151,7 @@ huffman<ky,wt>::huffman(map<ky,wt>& mp)
tmp->left = a, tmp->right = b; tmp->left = a, tmp->right = b;
hp.push(*tmp); hp.push(*tmp);
} }
root = hp.top(); root = hp.top();
preOrder(&root, string()); preOrder(&root, string());
} }
@ -134,6 +164,7 @@ void huffman<ky,wt>::preOrder(node<ky, wt>* nd,string s)
delete nd; delete nd;
return ; return ;
} }
preOrder(nd->left, s + '0'); preOrder(nd->left, s + '0');
preOrder(nd->right, s + '1'); preOrder(nd->right, s + '1');
delete nd; delete nd;
@ -146,9 +177,13 @@ string huffman<ky,wt>::decode(string zipfile_name,long &charNum)
char file_name[nameLength]; char file_name[nameLength];
fgets(file_name, nameLength, src); fgets(file_name, nameLength, src);
int ct = -1; int ct = -1;
while (file_name[++ct] != '\n'); while (file_name[++ct] != '\n');
int pos = zipfile_name.find('.'); int pos = zipfile_name.find('.');
if (pos == string::npos)pos = zipfile_name.size(); if (pos == string::npos)pos = zipfile_name.size();
string name(zipfile_name.substr(0, pos)), suffix(file_name, file_name + ct), file(name + suffix); string name(zipfile_name.substr(0, pos)), suffix(file_name, file_name + ct), file(name + suffix);
file = uniFileName(file); file = uniFileName(file);
cout << "extracting compressed file :" << zipfile_name << endl; cout << "extracting compressed file :" << zipfile_name << endl;
@ -159,36 +194,46 @@ string huffman<ky,wt>::decode(string zipfile_name,long &charNum)
char code[sz]; char code[sz];
fread(code, sz, 1, src); fread(code, sz, 1, src);
int idx = 0; int idx = 0;
for (int i = 0; i < sz; ++i) { for (int i = 0; i < sz; ++i) {
if (code[i] == ' ') { if (code[i] == ' ') {
decode_map[string(code + idx, code + i)] = code[++i]; decode_map[string(code + idx, code + i)] = code[++i];
idx = i + 1; idx = i + 1;
} }
} }
for (int i = 0; i < starNum; ++i)cout << "@"; for (int i = 0; i < starNum; ++i)cout << "@";
cout << endl; cout << endl;
char c; char c;
long cur = charNum, gap = charNum / starNum; long cur = charNum, gap = charNum / starNum;
while (cur) { while (cur) {
c = fgetc(src); c = fgetc(src);
if (!((--cur) % gap))cout << "@" << flush; if (!((--cur) % gap))cout << "@" << flush;
for (int i = 0; i < 8; ++i) { for (int i = 0; i < 8; ++i) {
if (c & (1 << i))res.append(1, '1'); if (c & (1 << i))res.append(1, '1');
else res.append(1, '0'); else res.append(1, '0');
if (decode_map.count(res) != 0) { if (decode_map.count(res) != 0) {
fputc(decode_map[res], f); fputc(decode_map[res], f);
res.clear(); res.clear();
} }
} }
} }
cout << endl; cout << endl;
c = fgetc(src); c = fgetc(src);
int dgt = fgetc(src); int dgt = fgetc(src);
cout << feof(f); cout << feof(f);
if ((int)dgt != -1) { if ((int)dgt != -1) {
for (int i = 0; i < dgt; ++i) { for (int i = 0; i < dgt; ++i) {
if (c & (1 << i))res.append(1, '1'); if (c & (1 << i))res.append(1, '1');
else res.append(1, '0'); else res.append(1, '0');
if (decode_map.count(res) != 0) { if (decode_map.count(res) != 0) {
fputc(decode_map[res], f); fputc(decode_map[res], f);
res.clear(); res.clear();
@ -196,6 +241,7 @@ string huffman<ky,wt>::decode(string zipfile_name,long &charNum)
} }
} }
} }
fclose(src); fclose(src);
fclose(f); fclose(f);
cout << "get " << file << " successfully" << endl; cout << "get " << file << " successfully" << endl;
@ -207,7 +253,9 @@ string huffman<ky,wt>::encode(string file_name,long &charNum)
charNum = 0; charNum = 0;
string uniFileName(string); string uniFileName(string);
int pos = file_name.rfind('.'); int pos = file_name.rfind('.');
if (pos == string::npos)pos = file_name.size(); if (pos == string::npos)pos = file_name.size();
string zipfile = file_name.substr(0, pos) + string(".zzip"); string zipfile = file_name.substr(0, pos) + string(".zzip");
zipfile = uniFileName(zipfile); zipfile = uniFileName(zipfile);
cout << "generating zip file :" << zipfile << endl; cout << "generating zip file :" << zipfile << endl;
@ -216,29 +264,40 @@ string huffman<ky,wt>::encode(string file_name,long &charNum)
fputs(file_name.substr(pos).c_str(), dst); fputs(file_name.substr(pos).c_str(), dst);
fputc('\n', dst); fputc('\n', dst);
string data; string data;
for (class map<string, ky>::iterator i = decode_map.begin(); i != decode_map.end() ; ++i) { for (class map<string, ky>::iterator i = decode_map.begin(); i != decode_map.end() ; ++i) {
data.append((i->first)); data.append((i->first));
data.append(" "); data.append(" ");
data += (i->second); data += (i->second);
} }
int data_size = data.size(); // calculate the size of the code_data int data_size = data.size(); // calculate the size of the code_data
char sz[numDigit]; char sz[numDigit];
snprintf(sz, numDigit, "%d", data_size); snprintf(sz, numDigit, "%d", data_size);
int ct = 0; int ct = 0;
for (; sz[ct]; ++ct)fputc(sz[ct], dst); for (; sz[ct]; ++ct)fputc(sz[ct], dst);
fputc('\n', dst); fputc('\n', dst);
fwrite(data.c_str(), data_size, 1, dst); fwrite(data.c_str(), data_size, 1, dst);
int sum = 0, digit = 0, num; int sum = 0, digit = 0, num;
string code8; string code8;
for (int i = 0; i < starNum; ++i)cout << "@"; for (int i = 0; i < starNum; ++i)cout << "@";
cout << endl; cout << endl;
long gap = root.val / starNum, cur = 0; long gap = root.val / starNum, cur = 0;
while (!feof(f)) { while (!feof(f)) {
code8 = encode_map[fgetc(f)]; code8 = encode_map[fgetc(f)];
if (!((++cur) % gap))cout << "@"; if (!((++cur) % gap))cout << "@";
for (int i = 0; i < code8.size(); ++i) { for (int i = 0; i < code8.size(); ++i) {
if (code8[i] == '1')sum += 1 << (digit); //mistake if(tmp[j]) if (code8[i] == '1')sum += 1 << (digit); //mistake if(tmp[j])
++digit; ++digit;
if (digit == 8) { if (digit == 8) {
++charNum; ++charNum;
fputc(sum, dst); fputc(sum, dst);
@ -246,11 +305,14 @@ string huffman<ky,wt>::encode(string file_name,long &charNum)
} }
} }
} }
cout << endl; cout << endl;
if (digit != 0) { //mark if (digit != 0) { //mark
fputc(sum, dst); fputc(sum, dst);
fputc(digit, dst); fputc(digit, dst);
} }
fclose(f); fclose(f);
fclose(dst); fclose(dst);
cout << "compress " << file_name << " successfully" << endl; cout << "compress " << file_name << " successfully" << endl;
@ -260,6 +322,7 @@ template<typename ky,typename wt>
void huffman<ky, wt>::display() void huffman<ky, wt>::display()
{ {
cout << "the encoding map,huffman codes are as bellow:" << endl; cout << "the encoding map,huffman codes are as bellow:" << endl;
for (typename map<ky, string>::iterator i = encode_map.begin(); i != encode_map.end() ; ++i) 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 << i->first << "(" << (int)i->first << "):" << i->second << endl;
} }
@ -268,21 +331,25 @@ bool handle_one(string file_name,vector<long> &origin,vector<long> &compressed)
int name_length = file_name.size(); int name_length = file_name.size();
FILE *src = fopen(file_name.c_str(), "rb"); FILE *src = fopen(file_name.c_str(), "rb");
cout << "opening " << file_name << "..." << endl; cout << "opening " << file_name << "..." << endl;
if (!src) { if (!src) {
cout << "Path Error! Opening " << file_name << " Failed" << endl; cout << "Path Error! Opening " << file_name << " Failed" << endl;
origin.push_back(0); origin.push_back(0);
compressed.push_back(0); compressed.push_back(0);
return false; return false;
} }
char cur; char cur;
map<char, long> mp; map<char, long> mp;
while (!feof(src)) { while (!feof(src)) {
fread(&cur, sizeof(char), 1, src); fread(&cur, sizeof(char), 1, src);
if (mp.count(cur)) { if (mp.count(cur)) {
mp[cur] += 1; mp[cur] += 1;
} else mp[cur] = 1;
} }
else mp[cur]=1;
}
fclose(src); fclose(src);
huffman<char, long> hf(mp); huffman<char, long> hf(mp);
long sz; long sz;
@ -290,7 +357,9 @@ bool handle_one(string file_name,vector<long> &origin,vector<long> &compressed)
origin.push_back(hf.total()), compressed.push_back(sz); origin.push_back(hf.total()), compressed.push_back(sz);
cout << "\ncontinue to uncompress? [Y/n]" << endl; cout << "\ncontinue to uncompress? [Y/n]" << endl;
char c = cin.get(); char c = cin.get();
if (c == 'n')return true; if (c == 'n')return true;
hf.decode(s, sz); hf.decode(s, sz);
return true; return true;
} }
@ -301,13 +370,17 @@ bool isSep(char c)
void splitToVec(char * s, vector<string>& v) void splitToVec(char * s, vector<string>& v)
{ {
int i = 0, last = 0; int i = 0, last = 0;
for (; s[i]; ++i) { for (; s[i]; ++i) {
if (isSep(s[i])) { if (isSep(s[i])) {
v.push_back(string(s + last, s + i)); v.push_back(string(s + last, s + i));
while (s[++i] && isSep(s[i])); while (s[++i] && isSep(s[i]));
last = 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)
@ -321,6 +394,7 @@ void go(vector<string> & names)
double last; double last;
vector<bool> indicator; vector<bool> indicator;
bool bl; bool bl;
for (vector<string>::iterator i = names.begin(); i != names.end(); ++i) { for (vector<string>::iterator i = names.begin(); i != names.end(); ++i) {
struct timeval tv; struct timeval tv;
gettimeofday(&tv, NULL); gettimeofday(&tv, NULL);
@ -330,15 +404,21 @@ void go(vector<string> & names)
gettimeofday(&tv, NULL); gettimeofday(&tv, NULL);
deltaTime.push_back(tv.tv_sec - last); deltaTime.push_back(tv.tv_sec - last);
} }
cout << "\nDealt file number " << originSize.size() << fixed << setprecision(2) << endl; cout << "\nDealt file number " << originSize.size() << fixed << setprecision(2) << endl;
vector<string>::iterator p = max_element(names.begin(), names.end(), lenStr); vector<string>::iterator p = max_element(names.begin(), names.end(), lenStr);
int len = p->size() + 2; int len = p->size() + 2;
for (int i = 0; i < names.size(); ++i) { for (int i = 0; i < names.size(); ++i) {
if(! indicator[i]){continue;} if (! indicator[i]) {
continue;
}
cout << names[i] << string(len - names[i].size(), ' '); cout << names[i] << string(len - names[i].size(), ' ');
cout << deltaTime[i] << "s " << compressedSize[i] / 1024.0 << "KB/" << originSize[i] / 1024.0 << "KB :"; cout << deltaTime[i] << "s " << compressedSize[i] / 1024.0 << "KB/" << originSize[i] / 1024.0 << "KB :";
cout << compressedSize[i] * 100.0 / originSize[i] << "%" << endl; cout << compressedSize[i] * 100.0 / originSize[i] << "%" << endl;
} }
cout << endl; cout << endl;
system("pause"); system("pause");
} }
@ -348,28 +428,37 @@ int main(int argv,char ** argc)
cout << getcwd(cwd, 50) << endl; cout << getcwd(cwd, 50) << endl;
vector<string> names; vector<string> names;
string file; string file;
if (argv > 1) { if (argv > 1) {
for (int i = 1; i < argv; ++i) { for (int i = 1; i < argv; ++i) {
names.push_back(argc[i]); names.push_back(argc[i]);
} }
go(names); go(names);
names.clear(); names.clear();
} }
char mk; char mk;
while (1) { while (1) {
char s[201]; char s[201];
cout << "Input file names separated by space " << endl; cout << "Input file names separated by space " << endl;
if (cin.peek() == '\n')names.push_back(file); if (cin.peek() == '\n')names.push_back(file);
else { else {
cin.getline(s, 200); cin.getline(s, 200);
splitToVec(s, names); splitToVec(s, names);
} }
cout << endl; cout << endl;
go(names); go(names);
cout << "Continue? [Y/n]:" << flush; cout << "Continue? [Y/n]:" << flush;
mk = cin.get(); mk = cin.get();
if (mk == 'n')break; if (mk == 'n')break;
names.clear(); names.clear();
} }
return 0; return 0;
} }

View File

@ -13,6 +13,7 @@
####################################################################### #######################################################################
''' '''
class RandomizedCollection: class RandomizedCollection:
def __init__(self): def __init__(self):
@ -27,6 +28,7 @@ class RandomizedCollection:
else: else:
self.index[val] = {len(self.vals)-1} self.index[val] = {len(self.vals)-1}
return True return True
def removeAll(self, val: int) -> bool: def removeAll(self, val: int) -> bool:
if val not in self.index: if val not in self.index:
return False return False
@ -40,6 +42,7 @@ class RandomizedCollection:
self.index[self.vals[idx]].add(idx) self.index[self.vals[idx]].add(idx)
self.vals = self.vals[:begin] self.vals = self.vals[:begin]
return True return True
def remove(self, val): def remove(self, val):
if val not in self.index: if val not in self.index:
return False return False
@ -53,6 +56,7 @@ class RandomizedCollection:
self.index[self.vals[idx]].add(idx) self.index[self.vals[idx]].add(idx)
self.vals.pop() self.vals.pop()
return True return True
def getRandom(self) -> int: def getRandom(self) -> int:
if self.vals: if self.vals:
return self.vals[random.randint(0, len(self.vals)-1)] return self.vals[random.randint(0, len(self.vals)-1)]

View File

@ -9,10 +9,12 @@
# Description: # Description:
######################################################################### #########################################################################
''' '''
from random import randint, shuffle
from redBlackTree import redBlackTree from redBlackTree import redBlackTree
from functools import total_ordering from functools import total_ordering
@total_ordering @total_ordering
class node: class node:
def __init__(self, low, high, left=None, right=None, isBlack=False): def __init__(self, low, high, left=None, right=None, isBlack=False):
@ -23,45 +25,63 @@ class node:
self.right = right self.right = right
self.parent = None self.parent = None
self.isBlack = isBlack self.isBlack = isBlack
def __lt__(self, nd): def __lt__(self, nd):
return self.val < nd.val return self.val < nd.val
def __eq__(self, nd): def __eq__(self, nd):
return nd is not None and self.val == nd.val return nd is not None and self.val == nd.val
def setChild(self, nd, isLeft=True): def setChild(self, nd, isLeft=True):
if isLeft: self.left = nd if isLeft:
else: self.right = nd self.left = nd
if nd is not None: nd.parent = self else:
self.right = nd
if nd is not None:
nd.parent = self
def getChild(self, isLeft): def getChild(self, isLeft):
if isLeft: return self.left if isLeft:
else: return self.right return self.left
else:
return self.right
def __bool__(self): def __bool__(self):
return self.val is not None return self.val is not None
def __str__(self): def __str__(self):
color = 'B' if self.isBlack else 'R' color = 'B' if self.isBlack else 'R'
return f'{color}[{self.val},{self.high}]-{self.max}' return f'{color}[{self.val},{self.high}]-{self.max}'
def __repr__(self): def __repr__(self):
return f'intervalNode({self.val},{self.high},{self.max},isBlack={self.isBlack})' return f'intervalNode({self.val},{self.high},{self.max},isBlack={self.isBlack})'
def overlap(self, low, high): def overlap(self, low, high):
return self.val <= high and self.high >= low return self.val <= high and self.high >= low
def setMax(self): def setMax(self):
l = 0 if self.left is None else self.left.max l = 0 if self.left is None else self.left.max
r = 0 if self.right is None else self.right.max r = 0 if self.right is None else self.right.max
self.max = max(self.high, l, r) self.max = max(self.high, l, r)
return self.max return self.max
class intervalTree(redBlackTree): class intervalTree(redBlackTree):
def search(self, low, high): def search(self, low, high):
nd = self.root nd = self.root
while nd is not None and not nd.overlap(low, high): while nd is not None and not nd.overlap(low, high):
if nd.left is not None and nd.left.max >= low: if nd.left is not None and nd.left.max >= low:
nd = nd.left nd = nd.left
else:nd = nd.right else:
nd = nd.right
return nd return nd
def insert(self, nd): def insert(self, nd):
super(intervalTree, self).insert(nd) super(intervalTree, self).insert(nd)
while nd is not None: while nd is not None:
nd.setMax() nd.setMax()
nd = nd.parent nd = nd.parent
def delete(self, val): def delete(self, val):
nd = self.find(val) nd = self.find(val)
if nd is not None: if nd is not None:
@ -71,19 +91,19 @@ class intervalTree(redBlackTree):
tmp.setMax() tmp.setMax()
tmp = tmp.parent tmp = tmp.parent
super(intervalTree, self).delete(val) super(intervalTree, self).delete(val)
def rotate(self, prt, chd): def rotate(self, prt, chd):
'''rotate prt, and return new prt, namyly the original chd''' '''rotate prt, and return new prt, namyly the original chd'''
super(intervalTree, self).rotate(prt, chd) super(intervalTree, self).rotate(prt, chd)
prt.setMax() prt.setMax()
chd.setMax() chd.setMax()
def copyNode(self, src, des): def copyNode(self, src, des):
des.val = src.val des.val = src.val
des.high = src.high des.high = src.high
des.setMax() des.setMax()
from random import randint, shuffle
def genNum(n=10, upper=10): def genNum(n=10, upper=10):
nums = {} nums = {}
for i in range(n): for i in range(n):
@ -94,6 +114,7 @@ def genNum(n =10,upper=10):
break break
return nums.values() return nums.values()
def buildTree(n=10, nums=None, visitor=None): def buildTree(n=10, nums=None, visitor=None):
#if nums is None or nums ==[]: nums = genNum(n) #if nums is None or nums ==[]: nums = genNum(n)
tree = intervalTree() tree = intervalTree()
@ -103,6 +124,8 @@ def buildTree(n=10,nums=None,visitor=None):
if visitor: if visitor:
visitor(tree, i) visitor(tree, i)
return tree, nums return tree, nums
def testInsert(nums=None): def testInsert(nums=None):
def visitor(t, val): def visitor(t, val):
print('inserting', val) print('inserting', val)
@ -113,11 +136,13 @@ def testInsert(nums=None):
print(f'{i+1}: {j}') print(f'{i+1}: {j}')
return tree return tree
def testSuc(nums=None): def testSuc(nums=None):
tree, nums = buildTree(nums=nums) tree, nums = buildTree(nums=nums)
for i in tree.sort(): for i in tree.sort():
print(f'{i}\'s suc is {tree.getSuccessor(i)}') print(f'{i}\'s suc is {tree.getSuccessor(i)}')
def testDelete(nums=None): def testDelete(nums=None):
tree, nums = buildTree(nums=nums) tree, nums = buildTree(nums=nums)
print(tree) print(tree)
@ -127,8 +152,10 @@ def testDelete(nums=None):
print(tree) print(tree)
return tree return tree
if __name__ == '__main__': 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 = [(0, 3), (5, 8), (6, 10), (26, 26), (25, 30),
(8, 9), (19, 20), (15, 23), (16, 21), (17, 19)]
#lst = None #lst = None
# testSuc(lst) # testSuc(lst)
tree = testInsert(lst) tree = testInsert(lst)

View File

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

View File

@ -9,10 +9,14 @@
# Description: # Description:
######################################################################### #########################################################################
''' '''
class node: class node:
def __init__(self, val, follow=None): def __init__(self, val, follow=None):
self.val = val self.val = val
self.follow = follow self.follow = follow
class MyLinkedList: class MyLinkedList:
def __init__(self): def __init__(self):
@ -31,7 +35,8 @@ class MyLinkedList:
nd = self.head nd = self.head
for i in range(index+1): for i in range(index+1):
nd = nd.follow nd = nd.follow
if nd is None:return -1 if nd is None:
return -1
return nd.val return nd.val
def addAtHead(self, val): def addAtHead(self, val):
@ -42,7 +47,9 @@ class MyLinkedList:
""" """
nd = node(val, self.head.follow) nd = node(val, self.head.follow)
self.head .follow = nd self.head .follow = nd
if self.tail.val is None:self.tail = nd if self.tail.val is None:
self.tail = nd
def addAtTail(self, val): def addAtTail(self, val):
""" """
Append a node of value val to the last element of the linked list. Append a node of value val to the last element of the linked list.
@ -52,7 +59,6 @@ class MyLinkedList:
self.tail.follow = node(val) self.tail.follow = node(val)
self.tail = self.tail.follow self.tail = self.tail.follow
def addAtIndex(self, index, val): def addAtIndex(self, index, val):
""" """
Add a node of value val before the index-th node in the linked list. If index equals to the length of linked list, the node will be appended to the end of linked list. If index is greater than the length, the node will not be inserted. Add a node of value val before the index-th node in the linked list. If index equals to the length of linked list, the node will be appended to the end of linked list. If index is greater than the length, the node will not be inserted.
@ -70,7 +76,6 @@ class MyLinkedList:
if self.tail == nd: if self.tail == nd:
self.tail = new self.tail = new
def deleteAtIndex(self, index): def deleteAtIndex(self, index):
""" """
Delete the index-th node in the linked list, if the index is valid. Delete the index-th node in the linked list, if the index is valid.
@ -80,10 +85,12 @@ class MyLinkedList:
nd = self.head nd = self.head
for i in range(index): for i in range(index):
nd = nd.follow nd = nd.follow
if nd is None:return if nd is None:
if self.tail == nd.follow:self.tail = nd return
if nd.follow:nd.follow = nd.follow.follow if self.tail == nd.follow:
self.tail = nd
if nd.follow:
nd.follow = nd.follow.follow
# Your MyLinkedList object will be instantiated and called as such: # Your MyLinkedList object will be instantiated and called as such:

View File

@ -44,7 +44,8 @@ class map
int size(); int size();
}; };
template<class t1, class t2> template<class t1, class t2>
map<t1,t2>::map(){ map<t1, t2>::map()
{
n = 0; n = 0;
cur = -1; cur = -1;
last_visit = &head; last_visit = &head;
@ -55,6 +56,7 @@ template<class t1,class t2>
map<t1, t2>::~map() map<t1, t2>::~map()
{ {
pair<t1, t2> *p, *q = &head; pair<t1, t2> *p, *q = &head;
while (q != NULL) { while (q != NULL) {
p = q->next; p = q->next;
delete q; delete q;
@ -65,10 +67,13 @@ template<class t1,class t2>
bool map<t1, t2>::has(t1 key) bool map<t1, t2>::has(t1 key)
{ {
pair<t1, t2> *p = head.next; pair<t1, t2> *p = head.next;
for (int i = 0; i < n && p->first <= key; ++i) { for (int i = 0; i < n && p->first <= key; ++i) {
if (isZero(p->first - key)) return 1; if (isZero(p->first - key)) return 1;
p = p->next; p = p->next;
} }
return 0; return 0;
} }
template<class t1, class t2> template<class t1, class t2>
@ -78,14 +83,17 @@ pair<t1,t2>& map<t1,t2>::locate(int index)
printf("the index is out of range\n"); printf("the index is out of range\n");
return head; return head;
} }
if (cur > index) { if (cur > index) {
last_visit = &head; last_visit = &head;
cur = -1; cur = -1;
} }
while (cur < index) { while (cur < index) {
last_visit = last_visit->next; last_visit = last_visit->next;
++cur; ++cur;
} }
return *last_visit; return *last_visit;
} }
template<class t1, class t2> template<class t1, class t2>
@ -97,11 +105,16 @@ template<class t1,class t2>
t2& map<t1, t2>::operator[](t1 key) t2& map<t1, t2>::operator[](t1 key)
{ {
pair<t1, t2> * p = &head; pair<t1, t2> * p = &head;
while (p->next != NULL) { while (p->next != NULL) {
if (isZero(p->next->first - key)) return p->next->second; if (isZero(p->next->first - key)) return p->next->second;
else if(p->next->first>key){break;} else if (p->next->first > key) {
break;
}
p = p->next; p = p->next;
} }
cur = -1; cur = -1;
last_visit = &head; last_visit = &head;
pair<t1, t2> *tmp = new pair<t1, t2>; pair<t1, t2> *tmp = new pair<t1, t2>;
@ -115,6 +128,7 @@ template<class t1,class t2>
void map<t1, t2>::erase(t1 key) void map<t1, t2>::erase(t1 key)
{ {
pair<t1, t2> *p = &head; pair<t1, t2> *p = &head;
while (p->next != NULL) { while (p->next != NULL) {
if (isZero(p->next->first - key)) { if (isZero(p->next->first - key)) {
pair<t1, t2> *q = p->next; pair<t1, t2> *q = p->next;
@ -123,8 +137,10 @@ void map<t1,t2>::erase(t1 key)
--n; --n;
break; break;
} }
p = p->next; p = p->next;
} }
cur = -1; cur = -1;
last_visit = &head; last_visit = &head;
} }
@ -133,18 +149,22 @@ void map<t1,t2>::erase(t1 key)
int main() int main()
{ {
map<double, float> b; map<double, float> b;
for (int i = 0; i < 40; ++i) { for (int i = 0; i < 40; ++i) {
b[i] = i; b[i] = i;
if (i % 3) { if (i % 3) {
b[i] = 1; b[i] = 1;
} }
if (i % 2) { if (i % 2) {
b.erase(i); b.erase(i);
} }
} }
for (int i = 0; i < b.size(); ++i) { for (int i = 0; i < b.size(); ++i) {
printf("item %d %g:%g\n", i, b.locate(i).first, b.locate(i).second); printf("item %d %g:%g\n", i, b.locate(i).first, b.locate(i).second);
} }
return 0; return 0;
} }

View File

@ -29,6 +29,7 @@ bool isZero(double a)
{ {
if ((a < 0.00001) && -a < 0.00001) if ((a < 0.00001) && -a < 0.00001)
return true; return true;
return false; return false;
} }
class node class node
@ -66,9 +67,11 @@ polynomial::~polynomial()
double polynomial::cal(double x) double polynomial::cal(double x)
{ {
double rst = 0; double rst = 0;
for (int i = 0; i < n; ++i) { for (int i = 0; i < n; ++i) {
rst += pow(x, p[i].index) * p[i].coefficient; rst += pow(x, p[i].index) * p[i].coefficient;
} }
return rst; return rst;
} }
polynomial::polynomial(const polynomial &a) polynomial::polynomial(const polynomial &a)
@ -76,6 +79,7 @@ polynomial::polynomial(const polynomial &a)
p = (node*) new node[50]; p = (node*) new node[50];
memset(p, 0, sizeof(p)); memset(p, 0, sizeof(p));
n = a.n; n = a.n;
for (int i = 0; i < a.n; ++i) { for (int i = 0; i < a.n; ++i) {
p[i].index = a.p[i].index; p[i].index = a.p[i].index;
p[i].coefficient = a.p[i].coefficient; p[i].coefficient = a.p[i].coefficient;
@ -84,33 +88,42 @@ polynomial::polynomial(const polynomial &a)
polynomial polynomial::operator=(const polynomial& a) polynomial polynomial::operator=(const polynomial& a)
{ {
n = a.n; n = a.n;
for (int i = 0; i < a.n; ++i) { for (int i = 0; i < a.n; ++i) {
p[i].index = a.p[i].index; p[i].index = a.p[i].index;
p[i].coefficient = a.p[i].coefficient; p[i].coefficient = a.p[i].coefficient;
} }
return *this; return *this;
} }
void polynomial::display() void polynomial::display()
{ {
node * tmp = p; node * tmp = p;
if (n == 0) { if (n == 0) {
printf("0\n"); printf("0\n");
return; return;
} }
// char *fmt = ("x"); printf(fmt,...); // char *fmt = ("x"); printf(fmt,...);
for (int i = n - 1; i >= 0; --i) { for (int i = n - 1; i >= 0; --i) {
double t = tmp[i].coefficient; double t = tmp[i].coefficient;
double idx = tmp[i].index; double idx = tmp[i].index;
if (isZero(idx)) { if (isZero(idx)) {
printf("%+g", t); printf("%+g", t);
continue; continue;
} }
if (isZero(t - 1)) printf("+"); if (isZero(t - 1)) printf("+");
else if (isZero(t + 1))printf("-"); else if (isZero(t + 1))printf("-");
else printf("%+g", t); else printf("%+g", t);
printf("x"); printf("x");
if (!isZero(idx - 1)) printf("^%g", idx); if (!isZero(idx - 1)) printf("^%g", idx);
} }
printf("\n"); printf("\n");
} }
void polynomial::getData() void polynomial::getData()
@ -120,22 +133,26 @@ void polynomial::getData()
map<double, double> mp; map<double, double> mp;
double idx; double idx;
double coef; double coef;
while (scanf("%lf%lf", &coef, &idx) != EOF) { while (scanf("%lf%lf", &coef, &idx) != EOF) {
if (isZero(coef)) continue; if (isZero(coef)) continue;
if (mp.count(idx) == 0) { if (mp.count(idx) == 0) {
mp[idx] = coef; mp[idx] = coef;
} } else {
else{
mp[idx] += coef; mp[idx] += coef;
if (isZero(mp[idx])) { if (isZero(mp[idx])) {
mp.erase(idx); mp.erase(idx);
} }
} }
} }
if (mp.size() > SIZE) { if (mp.size() > SIZE) {
SIZE *= 2; SIZE *= 2;
p = (node*)realloc(p, sizeof(node) * SIZE) ; p = (node*)realloc(p, sizeof(node) * SIZE) ;
} }
for (map<double, double>::iterator it = mp.begin(); it != mp.end(); ++it) { for (map<double, double>::iterator it = mp.begin(); it != mp.end(); ++it) {
p[n].index = it->first; p[n].index = it->first;
p[n++].coefficient = it->second; p[n++].coefficient = it->second;
@ -147,6 +164,7 @@ polynomial polynomial::operator+(const polynomial & a)
int p1 = 0, p2 = 0, p3 = 0; int p1 = 0, p2 = 0, p3 = 0;
double exp1 = p[p1].index; double exp1 = p[p1].index;
double exp2 = a.p[p2].index; double exp2 = a.p[p2].index;
while (p1 < n && p2 < a.n) { while (p1 < n && p2 < a.n) {
while (p1 < n && exp1 < exp2) { while (p1 < n && exp1 < exp2) {
rst.p[p3].index = exp1; rst.p[p3].index = exp1;
@ -154,38 +172,41 @@ polynomial polynomial::operator+(const polynomial & a)
++p1, ++p3; ++p1, ++p3;
exp1 = p[p1].index;; exp1 = p[p1].index;;
} }
while (p2 < a.n && exp1 > exp2) { while (p2 < a.n && exp1 > exp2) {
rst.p[p3].index = exp2; rst.p[p3].index = exp2;
rst.p[p3].coefficient = a.p[p2].coefficient; rst.p[p3].coefficient = a.p[p2].coefficient;
++p2, ++p3; ++p2, ++p3;
exp2 = a.p[p2].index;; exp2 = a.p[p2].index;;
} }
if (isZero(exp1 - exp2)) { if (isZero(exp1 - exp2)) {
double tmp = p[p1].coefficient + a.p[p2].coefficient; double tmp = p[p1].coefficient + a.p[p2].coefficient;
if (isZero(tmp)) { if (isZero(tmp)) {
++p1, ++p2; ++p1, ++p2;
} } else {
else{
rst.p[p3].index = p[p1].index; rst.p[p3].index = p[p1].index;
rst.p[p3].coefficient = tmp; rst.p[p3].coefficient = tmp;
++p1, ++p2, ++p3; ++p1, ++p2, ++p3;
} }
} }
} }
if (p1 == n) { if (p1 == n) {
while (p2 < a.n) { while (p2 < a.n) {
rst.p[p3].index = a.p[p2].index; rst.p[p3].index = a.p[p2].index;
rst.p[p3].coefficient = a.p[p2].coefficient; rst.p[p3].coefficient = a.p[p2].coefficient;
++p2, ++p3; ++p2, ++p3;
} }
} } else {
else{
while (p1 < n) { while (p1 < n) {
rst.p[p3].index = p[p1].index; rst.p[p3].index = p[p1].index;
rst.p[p3].coefficient = p[p1].coefficient; rst.p[p3].coefficient = p[p1].coefficient;
++p1, ++p3; ++p1, ++p3;
} }
} }
rst.n = p3; rst.n = p3;
return rst; return rst;
} }
@ -193,40 +214,50 @@ polynomial polynomial::operator-(const polynomial & a)
{ {
polynomial rst(a) ; polynomial rst(a) ;
int i = 0; int i = 0;
while (i < rst.n) { while (i < rst.n) {
rst.p[i].coefficient = -rst.p[i].coefficient; rst.p[i].coefficient = -rst.p[i].coefficient;
++i; ++i;
} }
return (*this + rst); return (*this + rst);
} }
polynomial polynomial::operator*(const polynomial & a) polynomial polynomial::operator*(const polynomial & a)
{ {
map<double, double> mp; map<double, double> mp;
for (int i = 0; i < n; ++i) { for (int i = 0; i < n; ++i) {
double idx = p[i].index; double idx = p[i].index;
double coef = p[i].coefficient; double coef = p[i].coefficient;
for (int j = 0; j < a.n; ++j) { for (int j = 0; j < a.n; ++j) {
double index = idx + a.p[j].index; double index = idx + a.p[j].index;
if (mp.count(index) == 0) { if (mp.count(index) == 0) {
mp[index] = coef * a.p[j].coefficient; mp[index] = coef * a.p[j].coefficient;
} } else {
else{
mp[index] += coef * a.p[j].coefficient; mp[index] += coef * a.p[j].coefficient;
if (isZero(mp[index])) { if (isZero(mp[index])) {
mp.erase(index); mp.erase(index);
} }
} }
} }
} }
int sz = 50; int sz = 50;
while (mp.size() > sz) { while (mp.size() > sz) {
sz *= 2; sz *= 2;
} }
polynomial rst(sz); polynomial rst(sz);
for (map<double, double>::iterator it = mp.begin(); it != mp.end(); ++it) { for (map<double, double>::iterator it = mp.begin(); it != mp.end(); ++it) {
rst.p[rst.n].index = it->first; rst.p[rst.n].index = it->first;
rst.p[rst.n++].coefficient = it->second; rst.p[rst.n++].coefficient = it->second;
} }
return rst; return rst;
} }
int num = 0; int num = 0;
@ -250,93 +281,93 @@ void menu()
void loop() void loop()
{ {
int op; int op;
while (scanf("%d", &op) != EOF) { while (scanf("%d", &op) != EOF) {
if (op == 0) { if (op == 0) {
pl[num].getData(); pl[num].getData();
++num; ++num;
printf("You've created polynomial %d:\n", num); printf("You've created polynomial %d:\n", num);
pl[num - 1].display(); pl[num - 1].display();
} } else if (op == 1 || op == 2 || op == 3) {
else if(op==1||op==2||op==3){
if (num < 2) { if (num < 2) {
printf("Oops! you've got less two polynomial\nPlease choose another operation\n"); printf("Oops! you've got less two polynomial\nPlease choose another operation\n");
continue; continue;
} }
printf("input two nums of the two polynomial to be operated.eg: 1 2\n"); printf("input two nums of the two polynomial to be operated.eg: 1 2\n");
int t1 = 100, t2 = 100; int t1 = 100, t2 = 100;
while (1) { while (1) {
scanf("%d%d", &t1, &t2); scanf("%d%d", &t1, &t2);
if (t1 > num || t2 > num || t1 < 0 || t2 < 0) { if (t1 > num || t2 > num || t1 < 0 || t2 < 0) {
printf("wrong num ,please input again\n"); printf("wrong num ,please input again\n");
} else break;
} }
else break;
}
printf("the rst is:\n"); printf("the rst is:\n");
t1 -= 1, t2 -= 1; t1 -= 1, t2 -= 1;
if (op == 1) { if (op == 1) {
(pl[t1] + pl[t2]).display(); (pl[t1] + pl[t2]).display();
} } else if (op == 2) {
else if(op == 2){
(pl[t1] - pl[t2]).display(); (pl[t1] - pl[t2]).display();
} } else (pl[t1]*pl[t2]).display();
else (pl[t1]*pl[t2]).display(); } else if (op == 4) {
}
else if(op == 4){
printf("input a polynomial's num to display it\n"); printf("input a polynomial's num to display it\n");
int tmp; int tmp;
scanf("%d", &tmp); scanf("%d", &tmp);
if (tmp > num) { if (tmp > num) {
printf("wrong num"); printf("wrong num");
} } else {
else{
printf("info of polynomial %d\n", tmp); printf("info of polynomial %d\n", tmp);
pl[tmp - 1].display(); pl[tmp - 1].display();
} }
} } else if (op == 9) {
else if(op == 9){
for (int i = 0; i < num; ++i) { for (int i = 0; i < num; ++i) {
printf("polynomial %d : ", i + 1); printf("polynomial %d : ", i + 1);
pl[i].display(); pl[i].display();
} }
} } else if (op == 5) {
else if(op == 5){
menu(); menu();
} } else if (op == 6) {
else if(op == 6){
if (LINUX) system("clear"); if (LINUX) system("clear");
else system("cls"); else system("cls");
menu(); menu();
} } else if (op == 10) {
else if(op == 10){
double x; double x;
int t; int t;
printf("choose a polynomial\n"); printf("choose a polynomial\n");
scanf("%d", &t); scanf("%d", &t);
if (t > num || t < 0) { if (t > num || t < 0) {
printf("wrong num\n"); printf("wrong num\n");
} } else {
else {
printf("input a value\n"); printf("input a value\n");
scanf("%lf", &x); scanf("%lf", &x);
pl[t - 1].display(); pl[t - 1].display();
printf("%g\n", pl[t - 1].cal(x)); printf("%g\n", pl[t - 1].cal(x));
} }
} } else if (op == 8) {
else if(op == 8){
if (num == 0) { if (num == 0) {
printf("you have'nt any polynomial tp copy\n"); printf("you have'nt any polynomial tp copy\n");
continue; continue;
} }
int n = num + 1; int n = num + 1;
while (n > num) { while (n > num) {
printf("input the number of an existing polynomial you want to copy\n"); printf("input the number of an existing polynomial you want to copy\n");
scanf("%d", &n); scanf("%d", &n);
} }
(pl[num] = pl[n - 1]); (pl[num] = pl[n - 1]);
printf("You've copyed this polynomial:\n"); printf("You've copyed this polynomial:\n");
pl[num++].display(); pl[num++].display();
} } else exit(0);
else exit(0);
printf("select an operation\n"); printf("select an operation\n");
} }
} }

View File

@ -16,17 +16,21 @@
# to be implemented # to be implemented
class polynomial: class polynomial:
pls = [] pls = []
n = 0 n = 0
def dictize(pl): def dictize(pl):
if isinstance(pl, int) or isinstance(pl, float): if isinstance(pl, int) or isinstance(pl, float):
pl = {0: pl} pl = {0: pl}
if isinstance(pl, polynomial): if isinstance(pl, polynomial):
pl = pl.polynomial.copy() pl = pl.polynomial.copy()
return pl return pl
def isZero(n): def isZero(n):
return abs(n) < 0.000001 return abs(n) < 0.000001
def __init__(self, s='0 0'): def __init__(self, s='0 0'):
polynomial.pls.append(self) polynomial.pls.append(self)
polynomial.n += 1 polynomial.n += 1
@ -53,18 +57,24 @@ class polynomial:
index = li[i+1] index = li[i+1]
if index in self.polynomial.keys(): if index in self.polynomial.keys():
self.polynomial[index] += li[i] self.polynomial[index] += li[i]
else:self.polynomial[index] = li[i] else:
self.polynomial[index] = li[i]
i += 2 i += 2
if not self.polynomial: if not self.polynomial:
self.polynomial = {0: 0} self.polynomial = {0: 0}
def __iter__(self): def __iter__(self):
return iter(list(self.polynomial.keys())) return iter(list(self.polynomial.keys()))
def __getitem__(self, key): def __getitem__(self, key):
return self.polynomial[key] return self.polynomial[key]
def __setitem__(self, key, val): def __setitem__(self, key, val):
self.polynomial[key] = val self.polynomial[key] = val
def __delitem__(self, k): def __delitem__(self, k):
del self.polynomial[k] del self.polynomial[k]
def __add__(self, pl): def __add__(self, pl):
pl = polynomial.dictize(pl) pl = polynomial.dictize(pl)
rst = self.polynomial.copy() rst = self.polynomial.copy()
@ -76,6 +86,7 @@ class polynomial:
if polynomial.isZero(rst[i]): if polynomial.isZero(rst[i]):
del rst[i] del rst[i]
return polynomial(rst) return polynomial(rst)
def __iadd__(self, pl): def __iadd__(self, pl):
pl = polynomial.dictize(pl) pl = polynomial.dictize(pl)
for i in pl: for i in pl:
@ -86,10 +97,12 @@ class polynomial:
if polynomial.isZero(self[i]): if polynomial.isZero(self[i]):
del self[i] del self[i]
return self return self
def __sub__(self, pl): def __sub__(self, pl):
pl = polynomial.dictize(pl) pl = polynomial.dictize(pl)
tmp = {i: -j for i, j in pl.items()} tmp = {i: -j for i, j in pl.items()}
return self + tmp return self + tmp
def __mul__(self, pl): def __mul__(self, pl):
pl = polynomial.dictize(pl) pl = polynomial.dictize(pl)
dic = dict() dic = dict()
@ -98,18 +111,23 @@ class polynomial:
index = i+j index = i+j
if index in dic: if index in dic:
dic[index] += pl[i]*self[j] dic[index] += pl[i]*self[j]
else:dic[index] = pl[i]*self[j] else:
dic[index] = pl[i]*self[j]
return polynomial({i: j for i, j in dic.items() if not polynomial.isZero(j)}) return polynomial({i: j for i, j in dic.items() if not polynomial.isZero(j)})
def __imul__(self, pl): def __imul__(self, pl):
self = self*pl self = self*pl
return self return self
def __pow__(self, n): def __pow__(self, n):
rst = polynomial({0: 1}) rst = polynomial({0: 1})
for i in range(n): for i in range(n):
rst *= self.polynomial rst *= self.polynomial
return rst return rst
def __repr__(self): def __repr__(self):
return self.__str__() return self.__str__()
def __str__(self): def __str__(self):
output = '' output = ''
if self.polynomial: if self.polynomial:
@ -122,19 +140,25 @@ class polynomial:
if not polynomial.isZero(self[i]-1): if not polynomial.isZero(self[i]-1):
if not polynomial.isZero(self[i]+1): if not polynomial.isZero(self[i]+1):
output += "%+g" % self[i] output += "%+g" % self[i]
else:output +='-' else:
else:output +='+' output += '-'
if not polynomial.isZero(i): output +='x' else:
if not polynomial.isZero(i-1):output +='^%g'%i output += '+'
if not polynomial.isZero(i):
output += 'x'
if not polynomial.isZero(i-1):
output += '^%g' % i
if output[0] == '+': if output[0] == '+':
return output[1:] return output[1:]
return output return output
def iterPolynomial(self, s): def iterPolynomial(self, s):
rst = polynomial({0: 0}) rst = polynomial({0: 0})
for i in self: for i in self:
rst += s**int(i)*self[i] rst += s**int(i)*self[i]
return rst return rst
def __call__(self, s): def __call__(self, s):
if isinstance(s, polynomial): if isinstance(s, polynomial):
return self.iterPolynomial(s) return self.iterPolynomial(s)
@ -142,16 +166,21 @@ class polynomial:
for i in self: for i in self:
sum += self[i] * s**i sum += self[i] * s**i
return sum return sum
def __xor__(self, n): def __xor__(self, n):
tmp = polynomial(self) tmp = polynomial(self)
for i in range(n): for i in range(n):
self = self.iterPolynomial(tmp) self = self.iterPolynomial(tmp)
return self return self
def save(self): def save(self):
polynomial.pls.append(self) polynomial.pls.append(self)
polynomial.n += 1 polynomial.n += 1
def delPlynomial(self, n): def delPlynomial(self, n):
return polynomial.pls.pop(n-1) return polynomial.pls.pop(n-1)
def menu(): def menu():
print('polynomial operations') print('polynomial operations')
print('1.create') print('1.create')
@ -166,5 +195,6 @@ def menu():
print('10.menu') print('10.menu')
print('11.exit') print('11.exit')
if __name__ == '__main__': if __name__ == '__main__':
pass pass

View File

@ -12,6 +12,7 @@
from functools import total_ordering from functools import total_ordering
from random import randint, shuffle from random import randint, shuffle
@total_ordering @total_ordering
class node: class node:
def __init__(self, val, left=None, right=None, isBlack=False): def __init__(self, val, left=None, right=None, isBlack=False):
@ -20,26 +21,39 @@ class node:
self.right = right self.right = right
self.parent = None self.parent = None
self.isBlack = isBlack self.isBlack = isBlack
def __lt__(self, nd): def __lt__(self, nd):
return self.val < nd.val return self.val < nd.val
def __eq__(self, nd): def __eq__(self, nd):
return nd is not None and self.val == nd.val return nd is not None and self.val == nd.val
def setChild(self, nd, isLeft): def setChild(self, nd, isLeft):
if isLeft: self.left = nd if isLeft:
else: self.right = nd self.left = nd
if nd is not None: nd.parent = self else:
self.right = nd
if nd is not None:
nd.parent = self
def getChild(self, isLeft): def getChild(self, isLeft):
if isLeft: return self.left if isLeft:
else: return self.right return self.left
else:
return self.right
def __bool__(self): def __bool__(self):
return self.val is not None return self.val is not None
def __str__(self): def __str__(self):
color = 'B' if self.isBlack else 'R' color = 'B' if self.isBlack else 'R'
val = '-' if self.parent == None else self.parent.val val = '-' if self.parent == None else self.parent.val
return f'{color}-{self.val}' return f'{color}-{self.val}'
def __repr__(self): def __repr__(self):
return f'node({self.val},isBlack={self.isBlack})' return f'node({self.val},isBlack={self.isBlack})'
class redBlackTree: class redBlackTree:
def __init__(self, unique=False): def __init__(self, unique=False):
'''if unique is True, all node'vals are unique, else there may be equal vals''' '''if unique is True, all node'vals are unique, else there may be equal vals'''
@ -49,15 +63,20 @@ class redBlackTree:
@staticmethod @staticmethod
def checkBlack(nd): def checkBlack(nd):
return nd is None or nd.isBlack return nd is None or nd.isBlack
@staticmethod @staticmethod
def setBlack(nd, isBlack): def setBlack(nd, isBlack):
if nd is not None: if nd is not None:
if isBlack is None or isBlack: if isBlack is None or isBlack:
nd.isBlack = True nd.isBlack = True
else:nd.isBlack = False else:
nd.isBlack = False
def setRoot(self, nd): def setRoot(self, nd):
if nd is not None: nd.parent=None if nd is not None:
nd.parent = None
self.root = nd self.root = nd
def find(self, val): def find(self, val):
nd = self.root nd = self.root
while nd: while nd:
@ -65,6 +84,7 @@ class redBlackTree:
return nd return nd
else: else:
nd = nd.getChild(nd.val > val) nd = nd.getChild(nd.val > val)
def getSuccessor(self, nd): def getSuccessor(self, nd):
if nd: if nd:
if nd.right: if nd.right:
@ -76,6 +96,7 @@ class redBlackTree:
while nd.parent is not None and nd.parent.right is nd: while nd.parent is not None and nd.parent.right is nd:
nd = nd.parent nd = nd.parent
return None if nd is self.root else nd.parent return None if nd is self.root else nd.parent
def rotate(self, prt, chd): def rotate(self, prt, chd):
'''rotate prt with the center of chd''' '''rotate prt with the center of chd'''
if self.root is prt: if self.root is prt:
@ -87,7 +108,8 @@ class redBlackTree:
chd.setChild(prt, not isLeftChd) chd.setChild(prt, not isLeftChd)
def insert(self, nd): def insert(self, nd):
if nd.isBlack: nd.isBlack = False if nd.isBlack:
nd.isBlack = False
if self.root is None: if self.root is None:
self.setRoot(nd) self.setRoot(nd)
@ -95,7 +117,8 @@ class redBlackTree:
else: else:
parent = self.root parent = self.root
while parent: while parent:
if parent == nd : return None if parent == nd:
return None
isLeft = parent > nd isLeft = parent > nd
chd = parent.getChild(isLeft) chd = parent.getChild(isLeft)
if chd is None: if chd is None:
@ -104,6 +127,7 @@ class redBlackTree:
else: else:
parent = chd parent = chd
self.fixUpInsert(parent, nd) self.fixUpInsert(parent, nd)
def fixUpInsert(self, parent, nd): def fixUpInsert(self, parent, nd):
''' adjust color and level, there are two red nodes: the new one and its parent''' ''' adjust color and level, there are two red nodes: the new one and its parent'''
while not self.checkBlack(parent): while not self.checkBlack(parent):
@ -143,12 +167,16 @@ class redBlackTree:
data exclude left, right , isBlack data exclude left, right , isBlack
''' '''
des.val = src.val des.val = src.val
def delete(self, val): def delete(self, val):
'''delete node in a binary search tree''' '''delete node in a binary search tree'''
if isinstance(val,node): val = val.val if isinstance(val, node):
val = val.val
nd = self.find(val) nd = self.find(val)
if nd is None: return if nd is None:
return
self._delete(nd) self._delete(nd)
def _delete(self, nd): def _delete(self, nd):
y = None y = None
if nd.left and nd.right: if nd.left and nd.right:
@ -163,7 +191,8 @@ class redBlackTree:
py.setChild(x, py.left is y) py.setChild(x, py.left is y)
if y != nd: if y != nd:
self.copyNode(y, nd) self.copyNode(y, nd)
if self.checkBlack(y): self.fixUpDel(py,x) if self.checkBlack(y):
self.fixUpDel(py, x)
def fixUpDel(self, prt, chd): def fixUpDel(self, prt, chd):
''' adjust colors and rotate ''' ''' adjust colors and rotate '''
@ -211,7 +240,8 @@ class redBlackTree:
def sort(self, reverse=False): def sort(self, reverse=False):
''' return a generator of sorted data''' ''' return a generator of sorted data'''
def inOrder(root): def inOrder(root):
if root is None:return if root is None:
return
if reverse: if reverse:
yield from inOrder(root.right) yield from inOrder(root.right)
else: else:
@ -225,8 +255,10 @@ class redBlackTree:
def display(self): def display(self):
def getHeight(nd): def getHeight(nd):
if nd is None:return 0 if nd is None:
return 0
return max(getHeight(nd.left), getHeight(nd.right)) + 1 return max(getHeight(nd.left), getHeight(nd.right)) + 1
def levelVisit(root): def levelVisit(root):
from collections import deque from collections import deque
lst = deque([root]) lst = deque([root])
@ -238,7 +270,8 @@ class redBlackTree:
nd = lst.popleft() nd = lst.popleft()
if ct >= 2**lv: if ct >= 2**lv:
lv += 1 lv += 1
if lv>h:break if lv > h:
break
level.append([]) level.append([])
level[-1].append(str(nd)) level[-1].append(str(nd))
if nd is not None: if nd is not None:
@ -246,6 +279,7 @@ class redBlackTree:
else: else:
lst += [None, None] lst += [None, None]
return level return level
def addBlank(lines): def addBlank(lines):
width = 1+len(str(self.root)) width = 1+len(str(self.root))
sep = ' '*width sep = ' '*width
@ -266,6 +300,7 @@ class redBlackTree:
begin = '\n' + 'red-black-tree'.rjust(length+14, '-') + '-'*(length) begin = '\n' + 'red-black-tree'.rjust(length+14, '-') + '-'*(length)
end = '-'*(length*2+14)+'\n' end = '-'*(length*2+14)+'\n'
return '\n'.join([begin, *li, end]) return '\n'.join([begin, *li, end])
def __str__(self): def __str__(self):
return self.display() return self.display()
@ -280,8 +315,10 @@ def genNum(n =10):
break break
return nums return nums
def buildTree(n=10, nums=None, visitor=None): def buildTree(n=10, nums=None, visitor=None):
if nums is None or nums ==[]: nums = genNum(n) if nums is None or nums == []:
nums = genNum(n)
rbtree = redBlackTree() rbtree = redBlackTree()
print(f'build a red-black tree using {nums}') print(f'build a red-black tree using {nums}')
for i in nums: for i in nums:
@ -290,6 +327,8 @@ def buildTree(n=10,nums=None,visitor=None):
if visitor: if visitor:
visitor(rbtree, i) visitor(rbtree, i)
return rbtree, nums return rbtree, nums
def testInsert(nums=None): def testInsert(nums=None):
def visitor(t, val): def visitor(t, val):
print('inserting', val) print('inserting', val)
@ -299,11 +338,13 @@ def testInsert(nums=None):
for i, j in enumerate(rbtree.sort()): for i, j in enumerate(rbtree.sort()):
print(f'{i+1}: {j}') print(f'{i+1}: {j}')
def testSuc(nums=None): def testSuc(nums=None):
rbtree, nums = buildTree(nums=nums) rbtree, nums = buildTree(nums=nums)
for i in rbtree.sort(): for i in rbtree.sort():
print(f'{i}\'s suc is {rbtree.getSuccessor(i)}') print(f'{i}\'s suc is {rbtree.getSuccessor(i)}')
def testDelete(nums=None): def testDelete(nums=None):
rbtree, nums = buildTree(nums=nums) rbtree, nums = buildTree(nums=nums)
print(rbtree) print(rbtree)
@ -312,6 +353,7 @@ def testDelete(nums=None):
rbtree.delete(i) rbtree.delete(i)
print(rbtree) print(rbtree)
if __name__ == '__main__': if __name__ == '__main__':
lst = [45, 30, 64, 36, 95, 38, 76, 34, 50, 1] lst = [45, 30, 64, 36, 95, 38, 76, 34, 50, 1]
lst = [0, 3, 5, 6, 26, 25, 8, 19, 15, 16, 17] lst = [0, 3, 5, 6, 26, 25, 8, 19, 15, 16, 17]

View File

@ -12,30 +12,46 @@
from collections import deque, Iterable from collections import deque, Iterable
# use isinstance(obj,Iterable) to judge if an obj is iterable # use isinstance(obj,Iterable) to judge if an obj is iterable
class node: class node:
def __init__(self, val=None, left=None, right=None, parent=None): def __init__(self, val=None, left=None, right=None, parent=None):
self.val = val self.val = val
if val :self.freq = 1 if val:
else :self.freq = 0 self.freq = 1
else:
self.freq = 0
self.left = left self.left = left
self.right = right self.right = right
self.parent = parent self.parent = parent
def getChild(self, s=0): def getChild(self, s=0):
if isinstance(s,int):s =[s] if isinstance(s, int):
s = [s]
last = self last = self
for i in s: for i in s:
if not last:return None if not last:
if i == 0: last = last.left return None
else:last = last.right if i == 0:
last = last.left
else:
last = last.right
return last return last
def setChild(self, child, s=0): def setChild(self, child, s=0):
if isinstance(s, Iterable): if isinstance(s, Iterable):
i = s[0] i = s[0]
del s[0] del s[0]
if i == 0:self.left.setChild(child,s) if i == 0:
else:self.right.setChild(child,s) self.left.setChild(child, s)
elif s:self.right = child else:
else:self.left = child self.right.setChild(child, s)
elif s:
self.right = child
else:
self.left = child
class splayTree: class splayTree:
def __init__(self, s=[]): def __init__(self, s=[]):
s = list(s) s = list(s)
@ -43,9 +59,13 @@ class splayTree:
s = sorted(s, reverse=True) s = sorted(s, reverse=True)
for i in s: for i in s:
self.insert(self.root, i) self.insert(self.root, i)
def insert(self, k): def insert(self, k):
if not self.root :self.root = node(k) if not self.root:
else:self._insert(self.root,k) self.root = node(k)
else:
self._insert(self.root, k)
def _insert(self, root, k): def _insert(self, root, k):
if root.val == k: if root.val == k:
root.freq += 1 root.freq += 1
@ -53,30 +73,38 @@ class splayTree:
if not root.right: if not root.right:
root.right = node(k) root.right = node(k)
root.right.parent = root root.right.parent = root
else:self._insert(root.right,k) else:
self._insert(root.right, k)
else: else:
if not root.left: if not root.left:
root.left = node(k) root.left = node(k)
root.left.parent = root root.left.parent = root
else:self._insert(root.left,k) else:
self._insert(root.left, k)
def _zigzagRotate(self, i, j, root, parent, grand): def _zigzagRotate(self, i, j, root, parent, grand):
parent.setChild(root.getChild(i), j) parent.setChild(root.getChild(i), j)
root.setChild(parent, i) root.setChild(parent, i)
grand.setChild(root.getChild(j), i) grand.setChild(root.getChild(j), i)
root.setChild(grand, j) root.setChild(grand, j)
if root.parent:root.parent = grand.parent if root.parent:
root.parent = grand.parent
parent.parent = root parent.parent = root
grand.parent = root grand.parent = root
def _lineRotate(self, i, root, parent, grand): def _lineRotate(self, i, root, parent, grand):
grand.setChild(parent.getChild(i ^ 1), i) grand.setChild(parent.getChild(i ^ 1), i)
parent.setChild(grand, i ^ 1) parent.setChild(grand, i ^ 1)
parent.setChild(root.getChild(i ^ 1), i) parent.setChild(root.getChild(i ^ 1), i)
root.setChild(parent, i ^ 1) root.setChild(parent, i ^ 1)
if root.parent:root.parent = grand.parent if root.parent:
root.parent = grand.parent
parent.parent = root parent.parent = root
grand.parent = parent grand.parent = parent
def _rotate(self, root): def _rotate(self, root):
if root == self.root:return if root == self.root:
return
if root.parent == self.root: if root.parent == self.root:
for i in range(2): for i in range(2):
if root.parent.getChild(i) == root: if root.parent.getChild(i) == root:
@ -102,8 +130,10 @@ class splayTree:
elif i == j and grand.getChild([i, i]) == root: elif i == j and grand.getChild([i, i]) == root:
self._lineRotate(i, root, parent, grand) self._lineRotate(i, root, parent, grand)
self._rotate(root) self._rotate(root)
def _find(self, root, k): def _find(self, root, k):
if not root:return 0 if not root:
return 0
if root.val > k: if root.val > k:
return self._find(root.left, k) return self._find(root.left, k)
elif root.val < k: elif root.val < k:
@ -111,18 +141,24 @@ class splayTree:
else: else:
self._rotate(root) self._rotate(root)
return root.freq return root.freq
def _maxmin(self, root, i=0): def _maxmin(self, root, i=0):
if not root:return None if not root:
return None
if root.getChild(i): if root.getChild(i):
return self._maxmin(root.getChild(i)) return self._maxmin(root.getChild(i))
return root return root
def Max(self): def Max(self):
return self._maxmin(self.root, 1) return self._maxmin(self.root, 1)
def Min(self): def Min(self):
return self._maxmin(self.root, 0) return self._maxmin(self.root, 0)
def remove(self, k): def remove(self, k):
tmp = self.find(k) tmp = self.find(k)
if not tmp:raise ValueError if not tmp:
raise ValueError
else: else:
if self.root.left: if self.root.left:
r = self.root.right r = self.root.right
@ -134,8 +170,10 @@ class splayTree:
r.parent = Max r.parent = Max
else: else:
self.root = self.root.right self.root = self.root.right
def find(self, k): def find(self, k):
return self._find(self.root, k) return self._find(self.root, k)
def levelTraverse(self): def levelTraverse(self):
q = deque() q = deque()
q.append((self.root, 0)) q.append((self.root, 0))
@ -143,15 +181,19 @@ class splayTree:
while q: while q:
tmp, n = q.popleft() tmp, n = q.popleft()
rst.append(tmp) rst.append(tmp)
if tmp.left:q.append((tmp.left,n+1)) if tmp.left:
if tmp.right:q.append((tmp.right,n+1)) q.append((tmp.left, n+1))
if tmp.right:
q.append((tmp.right, n+1))
return rst return rst
def display(self): def display(self):
data = self.levelTraverse() data = self.levelTraverse()
for i in data: for i in data:
print(i.val, end=' ') print(i.val, end=' ')
print('') print('')
if __name__ == '__main__': if __name__ == '__main__':
a = splayTree() a = splayTree()
a.insert(5) a.insert(5)

View File

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

View File

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

View File

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

View File

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

View File

@ -13,34 +13,47 @@ from random import randint
from time import time from time import time
from functools import total_ordering from functools import total_ordering
@total_ordering @total_ordering
class point: class point:
def __init__(self, x, y): def __init__(self, x, y):
self.x = x self.x = x
self.y = y self.y = y
def __neg__(self): def __neg__(self):
return pont(-self.x, -self.y) return pont(-self.x, -self.y)
def __len__(self): def __len__(self):
return self.norm(2) return self.norm(2)
def __lt__(self, p): def __lt__(self, p):
return self.x < p.x or (self.x == p.x and self.y < p.y) return self.x < p.x or (self.x == p.x and self.y < p.y)
def __eq__(self, p): def __eq__(self, p):
return self.x == p.x and self.y == p.y return self.x == p.x and self.y == p.y
def __hash__(self): def __hash__(self):
return hash((self.x, self.y)) return hash((self.x, self.y))
def __repr__(self): def __repr__(self):
return 'point({},{})'.format(self.x, self.y) return 'point({},{})'.format(self.x, self.y)
def __str__(self): def __str__(self):
return self.__repr__() return self.__repr__()
def norm(self, n=2): def norm(self, n=2):
if n<=0: return max(abs(self.x),abs(self.y)) if n <= 0:
return max(abs(self.x), abs(self.y))
return (abs(self.x)**n+abs(self.y)**n)**(1/n) return (abs(self.x)**n+abs(self.y)**n)**(1/n)
def distance(self, p): def distance(self, p):
return ((self.x-p.x)**2+(self.y-p.y)**2)**0.5 return ((self.x-p.x)**2+(self.y-p.y)**2)**0.5
def minDistance_n2(points): def minDistance_n2(points):
n = len(points) n = len(points)
if n<=1: return 0 if n <= 1:
return 0
p, q = points[:2] p, q = points[:2]
minD = points[0].distance(points[1]) minD = points[0].distance(points[1])
for i in range(n-1): for i in range(n-1):
@ -52,6 +65,7 @@ def minDistance_n2(points):
q = points[j] q = points[j]
return minD, p, q return minD, p, q
def findif(points, f, reverse=False): def findif(points, f, reverse=False):
n = len(points) n = len(points)
rg = range(n-1, -1, -1) if reverse else range(n) rg = range(n-1, -1, -1) if reverse else range(n)
@ -60,13 +74,16 @@ def findif(points, f,reverse = False):
return points[i+1:] if reverse else points[:i] return points[i+1:] if reverse else points[:i]
return points.copy() # note that don't return exactly points, return a copy one return points.copy() # note that don't return exactly points, return a copy one
def floatEql(f1, f2, epsilon=1e-6): def floatEql(f1, f2, epsilon=1e-6):
return abs(f1-f2) < epsilon return abs(f1-f2) < epsilon
def minDistance_nlogn(n_points): def minDistance_nlogn(n_points):
def _min(pts): def _min(pts):
n = len(pts) n = len(pts)
if n==2: return pts[0].distance(pts[1]) , pts[0],pts[1] if n == 2:
return pts[0].distance(pts[1]), pts[0], pts[1]
if n == 3: if n == 3:
minD = pts[0].distance(pts[1]) minD = pts[0].distance(pts[1])
p, q = pts[0], pts[1] p, q = pts[0], pts[1]
@ -75,8 +92,10 @@ def minDistance_nlogn(n_points):
minD = d2 minD = d2
p, q = pts[1], pts[2] p, q = pts[1], pts[2]
d2 = pts[0].distance(pts[2]) d2 = pts[0].distance(pts[2])
if minD>d2: return d2, pts[0],pts[2] if minD > d2:
else : return minD, p,q return d2, pts[0], pts[2]
else:
return minD, p, q
n2 = n//2 n2 = n//2
mid = (pts[n2].x + pts[n2-1].x)/2 mid = (pts[n2].x + pts[n2-1].x)/2
s1 = pts[:n2] s1 = pts[:n2]
@ -110,6 +129,7 @@ def minDistance_nlogn(n_points):
return minD, p, q return minD, p, q
return _min(sorted(n_points)) return _min(sorted(n_points))
def test(f=minDistance_n2): def test(f=minDistance_n2):
print('\ntest : ', f.__name__) print('\ntest : ', f.__name__)
begin = time() begin = time()
@ -117,6 +137,7 @@ def test(f=minDistance_n2):
print('time : {:.6f} s'.format(time()-begin)) print('time : {:.6f} s'.format(time()-begin))
print('result: {:.2f} {} {}\n'.format(minD, p, q)) print('result: {:.2f} {} {}\n'.format(minD, p, q))
def genData(n, unique=True): def genData(n, unique=True):
upper = 1000000 upper = 1000000
if unique: if unique:
@ -124,7 +145,9 @@ def genData(n,unique=True):
for i in range(n): for i in range(n):
points.add(point(randint(1, upper), randint(1, upper))) points.add(point(randint(1, upper), randint(1, upper)))
return list(points) return list(points)
else:return [point(randint(1,upper),randint(1,upper)) for i in range(n)] else:
return [point(randint(1, upper), randint(1, upper)) for i in range(n)]
if __name__ == '__main__': if __name__ == '__main__':
n = 1000 n = 1000

View File

@ -21,6 +21,7 @@ leetcode 1049: https://leetcode-cn.com/problems/last-stone-weight-ii/
####################################################################### #######################################################################
''' '''
class Solution: class Solution:
def lastStoneWeightII(self, stones: List[int]) -> int: def lastStoneWeightII(self, stones: List[int]) -> int:
sm = sum(stones) sm = sum(stones)

View File

@ -10,6 +10,7 @@
######################################################################### #########################################################################
''' '''
def lcs(a, b): def lcs(a, b):
'''time: O(mn); space: O(mn)''' '''time: O(mn); space: O(mn)'''
m, n = len(a), len(b) m, n = len(a), len(b)
@ -24,6 +25,7 @@ def lcs(a,b):
board[i+1][j+1] = board[i][1+j] board[i+1][j+1] = board[i][1+j]
return board[m][n] return board[m][n]
def lcs2(a, b): def lcs2(a, b):
'''time: O(mn); space: O(m)''' '''time: O(mn); space: O(m)'''
m, n = len(a), len(b) m, n = len(a), len(b)
@ -39,6 +41,7 @@ def lcs2(a,b):
upperLevel = tmp upperLevel = tmp
return board[n] return board[n]
if __name__ == '__main__': if __name__ == '__main__':
a = 'ABCBDAB' a = 'ABCBDAB'
b = 'BDCABA' b = 'BDCABA'

View File

@ -11,6 +11,8 @@
给两个整数数组 A B 返回两个数组中公共的长度最长的子数组的长度 给两个整数数组 A B 返回两个数组中公共的长度最长的子数组的长度
####################################################################### #######################################################################
''' '''
def findLength(A, B): def findLength(A, B):
n, m = len(A), len(B) n, m = len(A), len(B)
dp = [[0]*(m+1) for i in range(n+1)] dp = [[0]*(m+1) for i in range(n+1)]

View File

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

View File

@ -14,6 +14,8 @@
leetcode-cn 877: https://leetcode-cn.com/problems/stone-game/ leetcode-cn 877: https://leetcode-cn.com/problems/stone-game/
####################################################################### #######################################################################
''' '''
def stoneGame(li): def stoneGame(li):
'''li: list, len(li)%2==0, sum(li)%2==1''' '''li: list, len(li)%2==0, sum(li)%2==1'''
def f(p,q): def f(p,q):

View File

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

View File

@ -20,6 +20,7 @@
####################################################################### #######################################################################
''' '''
class Solution: class Solution:
def longestStrChain(self, words: List[str]) -> int: def longestStrChain(self, words: List[str]) -> int:
def isAdj(s1, s2): def isAdj(s1, s2):
@ -67,4 +68,3 @@ class Solution:
for nd in lenDic[lens[i]]: for nd in lenDic[lens[i]]:
ans = max(ans, dfs(nd)) ans = max(ans, dfs(nd))
return ans return ans

View File

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

View File

@ -11,6 +11,7 @@
####################################################################### #######################################################################
''' '''
def fastPow(a, n): def fastPow(a, n):
'''a^n''' '''a^n'''
rst = 1 rst = 1
@ -21,6 +22,7 @@ def fastPow(a,n):
a *= a a *= a
return rst return rst
def fastMul(a, b): def fastMul(a, b):
'''a*b''' '''a*b'''
rst = 0 rst = 0

View File

@ -11,6 +11,7 @@
####################################################################### #######################################################################
''' '''
def fib(n): def fib(n):
"""Calculates the nth Fibonacci number""" """Calculates the nth Fibonacci number"""
mat, p = (1, 1, 1, 0), n-2 mat, p = (1, 1, 1, 0), n-2
@ -18,6 +19,8 @@ def fib(n):
mat = (0, 1, 1, -1), 2-n mat = (0, 1, 1, -1), 2-n
li = matrix_pow((0, 1, 1, -1), 1-n) li = matrix_pow((0, 1, 1, -1), 1-n)
return li[0]+li[1] return li[0]+li[1]
def matrix_pow(mat, n): def matrix_pow(mat, n):
ans = (1, 0, 0, 1) # element matrix ans = (1, 0, 0, 1) # element matrix
while n > 0: while n > 0:
@ -27,6 +30,7 @@ def matrix_pow(mat,n):
mat = matrix_mul(mat, mat) mat = matrix_mul(mat, mat)
return ans return ans
def matrix_mul(a, b): def matrix_mul(a, b):
'''a,b are four-item tuple, represent matrix [[a[0],a[1]],[a[2],a[3]]]''' '''a,b are four-item tuple, represent matrix [[a[0],a[1]],[a[2],a[3]]]'''
return a[0]*b[0]+a[1]*b[2], a[0]*b[1]+a[1]*b[3], a[2]*b[0]+a[3]*b[2], a[2]*b[1]+a[3]*b[3] return a[0]*b[0]+a[1]*b[2], a[0]*b[1]+a[1]*b[3], a[2]*b[0]+a[3]*b[2], a[2]*b[1]+a[3]*b[3]

View File

@ -23,6 +23,7 @@ eg
''' '''
from nega import nega from nega import nega
def addNegaBin(arr1: list, arr2: list) -> list: def addNegaBin(arr1: list, arr2: list) -> list:
if len(arr1) < len(arr2): if len(arr1) < len(arr2):
arr1, arr2 = arr2, arr1 arr1, arr2 = arr2, arr1
@ -47,6 +48,7 @@ def addNegaBin(arr1: list, arr2: list) -> list:
arr1.pop(0) arr1.pop(0)
return arr1 return arr1
if __name__ == '__main__': if __name__ == '__main__':
while 1: while 1:
print("input q to quit or input x1 x2: ") print("input q to quit or input x1 x2: ")

View File

@ -10,8 +10,11 @@
######################################################################### #########################################################################
''' '''
def covert(s, basefrom=10, baseto=2): def covert(s, basefrom=10, baseto=2):
return d2n(n2d(s, basefrom), baseto) return d2n(n2d(s, basefrom), baseto)
def n2d(s, base=16): def n2d(s, base=16):
''' num of base_n(n<36) to decimal''' ''' num of base_n(n<36) to decimal'''
dic = {chr(i+ord('0')): i for i in range(10)} dic = {chr(i+ord('0')): i for i in range(10)}
@ -26,6 +29,7 @@ def n2d(s,base=16):
rst = dic[i]+rst*base rst = dic[i]+rst*base
return rst return rst
def d2n(n, base=16): def d2n(n, base=16):
''' num of base_n(n<36) to decimal''' ''' num of base_n(n<36) to decimal'''
dic = {i: chr(i+ord('0')) for i in range(10)} dic = {i: chr(i+ord('0')) for i in range(10)}
@ -39,7 +43,6 @@ def d2n(n,base=16):
return ''.join(rst[::-1]) return ''.join(rst[::-1])
''' '''
>>> n2d(str(d2n(4001))) >>> n2d(str(d2n(4001)))
4001 4001

View File

@ -9,10 +9,13 @@
# Description: # Description:
######################################################################### #########################################################################
''' '''
def nega(n: int, base=-2: int)->: list: def nega(n: int, base=-2: int)->: list:
'''return list of num, the first is the highest digit''' '''return list of num, the first is the highest digit'''
if base > -2: if base > -2:
raise Exception(f"[Error]: invalid base: {base}, base should be no more than -2") raise Exception(
f"[Error]: invalid base: {base}, base should be no more than -2")
ans = [] ans = []
while n: while n:
k = n % base k = n % base

View File

@ -17,17 +17,20 @@ from factor import factor
from collections import Counter from collections import Counter
from functools import reduce from functools import reduce
from operator import mul from operator import mul
def phi(n): def phi(n):
st = set(factor(n)) st = set(factor(n))
return round(reduce(mul, (1-1/p for p in st), n)) return round(reduce(mul, (1-1/p for p in st), n))
def sigma(n): def sigma(n):
ct = Counter(factor(n)) ct = Counter(factor(n))
return reduce(mul, (round((p**(ct[p]+1)-1)/(p-1)) for p in ct), 1) return reduce(mul, (round((p**(ct[p]+1)-1)/(p-1)) for p in ct), 1)
if __name__ == '__main__': if __name__ == '__main__':
while 1: while 1:
n = int(input('n: ')) n = int(input('n: '))
print('phi(n):', phi(n)) print('phi(n):', phi(n))
print('sigma(n):', sigma(n)) print('sigma(n):', sigma(n))

View File

@ -15,18 +15,23 @@ from random import randint
from isPrime import isPrime from isPrime import isPrime
from gcd import gcd from gcd import gcd
def factor(n): def factor(n):
'''pollard's rho algorithm''' '''pollard's rho algorithm'''
if n<1:raise Exception('[Error]: {} is less than 1'.format(n)) if n < 1:
if n==1: return [] raise Exception('[Error]: {} is less than 1'.format(n))
if isPrime(n):return [n] if n == 1:
return []
if isPrime(n):
return [n]
fact = 1 fact = 1
cycle_size = 2 cycle_size = 2
x = x_fixed = 2 x = x_fixed = 2
c = randint(1, n) c = randint(1, n)
while fact == 1: while fact == 1:
for i in range(cycle_size): for i in range(cycle_size):
if fact>1:break if fact > 1:
break
x = (x*x+c) % n x = (x*x+c) % n
if x == x_fixed: if x == x_fixed:
c = randint(1, n) c = randint(1, n)
@ -35,6 +40,8 @@ def factor(n):
cycle_size *= 2 cycle_size *= 2
x_fixed = x x_fixed = x
return factor(fact)+factor(n//fact) return factor(fact)+factor(n//fact)
def fact(n): def fact(n):
f = 2 f = 2
ret = [] ret = []
@ -43,7 +50,8 @@ def fact(n):
ret.append(f) ret.append(f)
n//f n//f
f += 1 f += 1
if n>1:ret.append(n) if n > 1:
ret.append(n)
return ret return ret

View File

@ -11,23 +11,28 @@
####################################################################### #######################################################################
''' '''
def gcd(a, b): def gcd(a, b):
while b != 0: while b != 0:
a, b = b, a % b a, b = b, a % b
return a return a
def lcm(a, b): def lcm(a, b):
return int(a*b/gcd(a, b)) return int(a*b/gcd(a, b))
def xgcd(a, b): def xgcd(a, b):
'''return gcd(a,b), x,y where ax+by=gcd(a,b)''' '''return gcd(a,b), x,y where ax+by=gcd(a,b)'''
if b==0:return a,1,0 if b == 0:
return a, 1, 0
g, x, y = xgcd(b, a % b) g, x, y = xgcd(b, a % b)
return g, y, x-a//b*y return g, y, x-a//b*y
if __name__ == '__main__': if __name__ == '__main__':
while 1: while 1:
a = int(input('a: ')) a = int(input('a: '))
b = int(input('b: ')) b = int(input('b: '))
print('gcd :', gcd(a, b)) print('gcd :', gcd(a, b))
print('xgcd:', xgcd(a, b)) print('xgcd:', xgcd(a, b))

View File

@ -13,6 +13,7 @@
####################################################################### #######################################################################
''' '''
def hammingDistance(a, b): def hammingDistance(a, b):
if isinstance(a, int): if isinstance(a, int):
n = a ^ b n = a ^ b
@ -28,10 +29,12 @@ def hammingDistance(a,b):
ret += i == j ret += i == j
return ret+abs(n-m) return ret+abs(n-m)
def totalHammingDistance(lst): def totalHammingDistance(lst):
'''return sum of any two items(num or lst( str)) in lst''' '''return sum of any two items(num or lst( str)) in lst'''
length = len(lst) length = len(lst)
if length ==0:return 0 if length == 0:
return 0
if isinstance(lst[0], int): if isinstance(lst[0], int):
bits = [0] * len(bin(max(lst))) bits = [0] * len(bin(max(lst)))
for n in lst: for n in lst:

View File

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

View File

@ -18,11 +18,13 @@ from euler import phi
from isPrime import isPrime from isPrime import isPrime
from factor import factor from factor import factor
def ind(m, g): def ind(m, g):
''' mod m ,primary root g -> {n:indg n}''' ''' mod m ,primary root g -> {n:indg n}'''
return {j:i for i in range(m-1) \ return {j: i for i in range(m-1)
for j in range(m) if (g**i-j) % m == 0} for j in range(m) if (g**i-j) % m == 0}
def gs(m, num=100): def gs(m, num=100):
'''return list of m's primary roots below num''' '''return list of m's primary roots below num'''
p = phi(m) p = phi(m)
@ -30,25 +32,31 @@ def gs(m,num=100):
checkLst = [p//i for i in mp] checkLst = [p//i for i in mp]
return [i for i in range(2, num) if all((i**n-1) % m != 0 for n in checkLst)] return [i for i in range(2, num) if all((i**n-1) % m != 0 for n in checkLst)]
def minG(m): def minG(m):
p = phi(m) p = phi(m)
mp = factor(p) mp = factor(p)
checkLst = [p//i for i in mp] checkLst = [p//i for i in mp]
i = 2 i = 2
while 1: while 1:
if all((i**n-1)%m !=0 for n in checkLst):return i if all((i**n-1) % m != 0 for n in checkLst):
return i
i += 1 i += 1
class solve: class solve:
def __init__(self, equ=None): def __init__(self, equ=None):
self.linearPat = re.compile(r'\s*(\d+)\s*--\s*(\d+)[\s\(]*mod\s*(\d+)') self.linearPat = re.compile(r'\s*(\d+)\s*--\s*(\d+)[\s\(]*mod\s*(\d+)')
self.sol = [] self.sol = []
#self.m = m #self.m = m
#self.ind_mp = ind(m,minG(m)) #self.ind_mp = ind(m,minG(m))
def noSol(self): def noSol(self):
print('equation {equ} has no solution'.format(equ=self.equ)) print('equation {equ} has no solution'.format(equ=self.equ))
def error(self): def error(self):
print("Error! The divisor m must be postive integer") print("Error! The divisor m must be postive integer")
def solveLinear(self, a, b, m): def solveLinear(self, a, b, m):
'''ax--b(mod m): solve linear equation with one unknown '''ax--b(mod m): solve linear equation with one unknown
return ([x1,x2,...],m) return ([x1,x2,...],m)
@ -63,19 +71,23 @@ class solve:
sols = [(sol+i*m0) % m for i in range(g)] sols = [(sol+i*m0) % m for i in range(g)]
print('{}x--{}(mod {}), solution: {} mod {}'.format(a, b, m, sols, m)) print('{}x--{}(mod {}), solution: {} mod {}'.format(a, b, m, sols, m))
return (sols, m) return (sols, m)
def check(self, a, b, m): def check(self, a, b, m):
if m <= 0: if m <= 0:
self.error() self.error()
return None return None
if a<0:a,b=-a,-b ## important if a < 0:
if b<0:b+= -b//m * m a, b = -a, -b # important
if b < 0:
b += -b//m * m
return a, b, m return a, b, m
def solveHigh(self, a, n, b, m): def solveHigh(self, a, n, b, m):
''' ax^n -- b (mod m) ind_mp is a dict of m's {n: indg n}''' ''' ax^n -- b (mod m) ind_mp is a dict of m's {n: indg n}'''
ind_mp = ind(m, minG(m)) ind_mp = ind(m, minG(m))
tmp = ind_mp[b] - ind_mp[a] tmp = ind_mp[b] - ind_mp[a]
if tmp < 0:tmp+=m if tmp < 0:
tmp += m
sol = self.solveLinear(n, tmp, phi(m)) sol = self.solveLinear(n, tmp, phi(m))
re_mp = {j: i for i, j in ind_mp.items()} re_mp = {j: i for i, j in ind_mp.items()}
sols = [re_mp[i] for i in sol[0]] sols = [re_mp[i] for i in sol[0]]
@ -95,7 +107,8 @@ class solve:
if mp[m][0]*b != mp[m][1]*a: if mp[m][0]*b != mp[m][1]*a:
self.noSol() self.noSol()
return return
else:mp[m] = (a,b) else:
mp[m] = (a, b)
product = 1 product = 1
for i in mp.keys(): for i in mp.keys():
product *= i product *= i
@ -111,6 +124,7 @@ class solve:
sol = [i % product for i in sol] sol = [i % product for i in sol]
print('final solution: {} mod {}'.format(sol, product)) print('final solution: {} mod {}'.format(sol, product))
return sol, product return sol, product
def __call__(self): def __call__(self):
s = input('输入同余方程,用--代表同于号形如3--5(mod 7)代表3x模7同余于5') s = input('输入同余方程,用--代表同于号形如3--5(mod 7)代表3x模7同余于5')
li = self.linearPat.findall(s) li = self.linearPat.findall(s)

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

@ -29,6 +29,7 @@ from operator import mul
X = sympy.Symbol('x') X = sympy.Symbol('x')
point = namedtuple('point', ['x', 'y']) point = namedtuple('point', ['x', 'y'])
class interplotion: class interplotion:
def __init__(self, points): def __init__(self, points):
self.points = [point(x, y) for x, y in points] self.points = [point(x, y) for x, y in points]
@ -41,9 +42,12 @@ class interplotion:
qs = [li[0].y] qs = [li[0].y]
def quoDiff(begin, end): def quoDiff(begin, end):
if begin == end:return li[begin].y if begin == end:
q = (quoDiff(begin+1,end)-quoDiff(begin,end-1))/(li[end].x-li[begin].x) return li[begin].y
if begin == a:qs.append(q) q = (quoDiff(begin+1, end)-quoDiff(begin, end-1)) / \
(li[end].x-li[begin].x)
if begin == a:
qs.append(q)
return q return q
quoDiff(a, b) quoDiff(a, b)
@ -52,12 +56,14 @@ class interplotion:
poly += q*base poly += q*base
base *= X-li[i].x base *= X-li[i].x
return poly, base*qs[-1] return poly, base*qs[-1]
def lagrange(self, points=None): def lagrange(self, points=None):
xs = None xs = None
if points is None: if points is None:
xs = self.xs xs = self.xs
points = self.points points = self.points
else: xs =[x for x,y in points] else:
xs = [x for x, y in points]
product = reduce(mul, [X-x for x in xs], 1) product = reduce(mul, [X-x for x in xs], 1)
poly = 0 poly = 0
for x, y in points: for x, y in points:
@ -67,7 +73,8 @@ class interplotion:
return poly return poly
def predict(self, val, poly=None): def predict(self, val, poly=None):
if poly is None:poly = self.poly if poly is None:
poly = self.poly
return poly.subs(X, val) # note the func subs return poly.subs(X, val) # note the func subs

View File

@ -20,7 +20,8 @@ def newton(y:sympy.core,x0:float,epsilon:float=0.00001,maxtime:int=50) ->(list,l
newton 's iteration method for finding a zeropoint of a func newton 's iteration method for finding a zeropoint of a func
y is the func, x0 is the init x val: int float epsilon is the accurrency y is the func, x0 is the init x val: int float epsilon is the accurrency
''' '''
if epsilon <0:epsilon = -epsilon if epsilon < 0:
epsilon = -epsilon
ct = 0 ct = 0
t = y.free_symbols t = y.free_symbols
varsymbol = 'x' if len(t) == 0 else t.pop() varsymbol = 'x' if len(t) == 0 else t.pop()
@ -38,7 +39,8 @@ def newton(y:sympy.core,x0:float,epsilon:float=0.00001,maxtime:int=50) ->(list,l
print("after iteration for {} times, I still havn't reach the accurrency.\ print("after iteration for {} times, I still havn't reach the accurrency.\
Maybe this function havsn't zeropoint\n".format(ct)) Maybe this function havsn't zeropoint\n".format(ct))
return li, val return li, val
if abs(x-x0)<epsilon:return li,vals if abs(x-x0) < epsilon:
return li, vals
x0 = x x0 = x
@ -48,7 +50,8 @@ def secant(y:sympy.core,x0:float,x1:float,epsilon:float =0.00001,maxtime:int=50)
secant method for finding a zeropoint of a func secant method for finding a zeropoint of a func
y is the func , x0 is the init x val, epsilon is the accurrency y is the func , x0 is the init x val, epsilon is the accurrency
''' '''
if epsilon <0:epsilon = -epsilon if epsilon < 0:
epsilon = -epsilon
ct = 0 ct = 0
x0, x1 = float(x0), float(x1) x0, x1 = float(x0), float(x1)
li = [x0, x1] li = [x0, x1]
@ -68,7 +71,8 @@ def secant(y:sympy.core,x0:float,x1:float,epsilon:float =0.00001,maxtime:int=50)
print("after iteration for {} times, I still havn't reach the accurrency.\ print("after iteration for {} times, I still havn't reach the accurrency.\
Maybe this function havsn't zeropoint\n".format(ct)) Maybe this function havsn't zeropoint\n".format(ct))
return li, vals return li, vals
if abs(x0-x1)<epsilon:return li,vals if abs(x0-x1) < epsilon:
return li, vals
x0 = x x0 = x
@ -79,7 +83,8 @@ def solveNonlinearEquations(funcs:[sympy.core],init_dic:dict,epsilon:float=0.001
ct = 0 ct = 0
while 1: while 1:
ys = np.array([f.subs(init_dic) for f in funcs], dtype='float') ys = np.array([f.subs(init_dic) for f in funcs], dtype='float')
mat = np.matrix([[i.diff(x).subs(init_dic) for x in li] for i in funcs ],dtype = 'float') mat = np.matrix([[i.diff(x).subs(init_dic) for x in li]
for i in funcs], dtype='float')
delt = np.linalg.solve(mat, -ys) delt = np.linalg.solve(mat, -ys)
for i, j in enumerate(delt): for i, j in enumerate(delt):
init_dic[li[i]] += j init_dic[li[i]] += j
@ -88,7 +93,8 @@ def solveNonlinearEquations(funcs:[sympy.core],init_dic:dict,epsilon:float=0.001
print("after iteration for {} times, I still havn't reach the accurrency.\ print("after iteration for {} times, I still havn't reach the accurrency.\
Maybe this function havsn't zeropoint\n".format(ct)) Maybe this function havsn't zeropoint\n".format(ct))
return init_dic return init_dic
if sqrt(sum(i**2 for i in delta.values()))<epsilon:return init_dic if sqrt(sum(i**2 for i in delta.values())) < epsilon:
return init_dic
if __name__ == '__main__': if __name__ == '__main__':
@ -97,11 +103,9 @@ if __name__ =='__main__':
res, res2 = newton(x**5-9, 2, 0.01) res, res2 = newton(x**5-9, 2, 0.01)
print(res, res2) print(res, res2)
res, res2 = secant(x**3-3*x-2, 1, 3, 1e-3) res, res2 = secant(x**3-3*x-2, 1, 3, 1e-3)
print(res, res2) print(res, res2)
funcs = [x**2+y**2-1, x**3-y] funcs = [x**2+y**2-1, x**3-y]
init = {x: 0.8, y: 0.6} init = {x: 0.8, y: 0.6}
res_dic = solveNonlinearEquations(funcs, init, 0.001) res_dic = solveNonlinearEquations(funcs, init, 0.001)

View File

@ -20,11 +20,10 @@
************************************************************************''' ************************************************************************'''
import re import re
import numpy as np import numpy as np
def solveConflitEqualtion(A, y): def solveConflitEqualtion(A, y):
'''solve equation like this: Av = y, '''solve equation like this: Av = y,
A:m*n v:n*1 y:m*1 A:m*n v:n*1 y:m*1
@ -37,6 +36,7 @@ def solveConflitEqualtion(A,y):
print(ata) print(ata)
return np.linalg.solve(ata, A.T*y) # note that is numpy.linalg.solve return np.linalg.solve(ata, A.T*y) # note that is numpy.linalg.solve
def solveLinear(point, index): def solveLinear(point, index):
y = [[i[1]] for i in point] y = [[i[1]] for i in point]
x = [[i[0]] for i in point] x = [[i[0]] for i in point]
@ -49,13 +49,16 @@ def solveLinear(point,index):
items = ['{:.4f}x^{}'.format(res[i, 0], j) for i, j in enumerate(index)] items = ['{:.4f}x^{}'.format(res[i, 0], j) for i, j in enumerate(index)]
print('phi(x) = ', ' + '.join(items)) print('phi(x) = ', ' + '.join(items))
def handleInput(s=None, y=None): def handleInput(s=None, y=None):
# numPt = re.compile (r'\d*\.{0,1}\d+') # numPt = re.compile (r'\d*\.{0,1}\d+')
if not s: s = input('input matrix A:m*n //m>=n\n') if not s:
s = input('input matrix A:m*n //m>=n\n')
s = s.replace(' ', '') s = s.replace(' ', '')
li = re.findall(r'(\[(\d+)(,(\d+))+\])', s) li = re.findall(r'(\[(\d+)(,(\d+))+\])', s)
li = [parseLst(i[0]) for i in li] li = [parseLst(i[0]) for i in li]
if not y:y = input('input a vector y:n*1\n') if not y:
y = input('input a vector y:n*1\n')
y = parseLst(y) y = parseLst(y)
print('Equation: Av = y:') print('Equation: Av = y:')
@ -70,6 +73,8 @@ def handleInput(s=None,y=None):
print('result v is as follows: ') print('result v is as follows: ')
res = solveConflitEqualtion(li, y) res = solveConflitEqualtion(li, y)
print(res) print(res)
def parseLst(s): def parseLst(s):
s = s.strip('[]') s = s.strip('[]')
li = s.split(',') li = s.split(',')

View File

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

View File

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

View File

@ -24,8 +24,9 @@
######################################################################### #########################################################################
import numpy as np import numpy as np
def trapezoidal(a, b, h, fs): def trapezoidal(a, b, h, fs):
'''梯形积分公式''' '''梯形积分公式'''
xs = [i for i in np.arange(a, b+h, h)] xs = [i for i in np.arange(a, b+h, h)]
@ -55,13 +56,15 @@ def romberg(a,b,f,epcilon):
h /= 2 h /= 2
k += 1 k += 1
lst2 = [] lst2 = []
lst2.append((lst1[0]+h*2*sum(f(a+(2*i-1)*h) for i in range(1,2**(k-2)+1)))/2) lst2.append((lst1[0]+h*2*sum(f(a+(2*i-1)*h)
for i in range(1, 2**(k-2)+1)))/2)
for j in range(0, k-1): for j in range(0, k-1):
lst2.append(lst2[j]+(lst2[j]-lst1[j])/(4**(j+1)-1)) lst2.append(lst2[j]+(lst2[j]-lst1[j])/(4**(j+1)-1))
delta = abs(lst2[-1]-lst1[-1]) delta = abs(lst2[-1]-lst1[-1])
lst1 = lst2 lst1 = lst2
print(lst1) print(lst1)
if __name__ == '__main__': if __name__ == '__main__':
a, b, h = 0.6, 1.8, 0.2 a, b, h = 0.6, 1.8, 0.2
fs = [5.7, 4.6, 3.5, 3.7, 4.9, 5.2, 5.5] fs = [5.7, 4.6, 3.5, 3.7, 4.9, 5.2, 5.5]

View File

@ -21,18 +21,25 @@
# Description: # Description:
######################################################################### #########################################################################
''' '''
import numpy as np import numpy as np
from operator import le, lt from operator import le, lt
def jacob(A, b, x, accuracy=None, times=6): def jacob(A, b, x, accuracy=None, times=6):
''' Ax=b, arg x is the init val, times is the time of iterating''' ''' Ax=b, arg x is the init val, times is the time of iterating'''
A, b, x = np.matrix(A), np.matrix(b), np.matrix(x) A, b, x = np.matrix(A), np.matrix(b), np.matrix(x)
n, m = A.shape n, m = A.shape
if n!=m:raise Exception("Not square matrix: {A}".format(A=A)) if n != m:
if b.shape !=( n,1) : raise Exception('Error: {b} must be {n} x1 in dimension'.format(b = b,n=n)) raise Exception("Not square matrix: {A}".format(A=A))
if b.shape != (n, 1):
raise Exception(
'Error: {b} must be {n} x1 in dimension'.format(b=b, n=n))
D = np.diag(np.diag(A)) D = np.diag(np.diag(A))
DI = np.zeros([n, n]) DI = np.zeros([n, n])
for i in range(n):DI[i,i]= 1/D[i,i] for i in range(n):
DI[i, i] = 1/D[i, i]
R = np.eye(n) - DI * A R = np.eye(n) - DI * A
g = DI * b g = DI * b
print('R =\n{}'.format(R)) print('R =\n{}'.format(R))
@ -45,7 +52,8 @@ def jacob(A,b,x,accuracy=None,times=6):
tmp = x-last tmp = x-last
last = x last = x
mx = max(abs(i) for i in tmp) mx = max(abs(i) for i in tmp)
if mx<accuracy:return x if mx < accuracy:
return x
x = R*x+g x = R*x+g
print('x{ct} =\n{x}'.format(ct=ct, x=x)) print('x{ct} =\n{x}'.format(ct=ct, x=x))
else: else:
@ -54,12 +62,17 @@ def jacob(A,b,x,accuracy=None,times=6):
print('x{ct} = \n{x}'.format(ct=i+1, x=x)) print('x{ct} = \n{x}'.format(ct=i+1, x=x))
print('isLimitd: {}'.format(isLimited(A))) print('isLimitd: {}'.format(isLimited(A)))
return x return x
def gauss_seidel(A, b, x, accuracy=None, times=6): def gauss_seidel(A, b, x, accuracy=None, times=6):
''' Ax=b, arg x is the init val, times is the time of iterating''' ''' Ax=b, arg x is the init val, times is the time of iterating'''
A, b, x = np.matrix(A), np.matrix(b), np.matrix(x) A, b, x = np.matrix(A), np.matrix(b), np.matrix(x)
n, m = A.shape n, m = A.shape
if n!=m:raise Exception("Not square matrix: {A}".format(A=A)) if n != m:
if b.shape !=( n,1) : raise Exception('Error: {b} must be {n} x1 in dimension'.format(b = b,n=n)) raise Exception("Not square matrix: {A}".format(A=A))
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))) D = np. matrix(np.diag(np.diag(A)))
L = np.tril(A) - D # L = np.triu(D.T) - D L = np.tril(A) - D # L = np.triu(D.T) - D
U = np.triu(A) - D U = np.triu(A) - D
@ -76,7 +89,8 @@ def gauss_seidel(A,b,x,accuracy=None,times=6):
tmp = x-last tmp = x-last
last = x last = x
mx = max(abs(i) for i in tmp) mx = max(abs(i) for i in tmp)
if mx<accuracy:return x if mx < accuracy:
return x
x = S*x+f x = S*x+f
print('x{ct} =\n{x}'.format(ct=ct, x=x)) print('x{ct} =\n{x}'.format(ct=ct, x=x))
else: else:
@ -91,18 +105,25 @@ def isLimited(A,strict=False):
'''通过检查A是否是[严格]对角优来判断迭代是否收敛, 即对角线上的值是否都大于对应行(或者列)的值''' '''通过检查A是否是[严格]对角优来判断迭代是否收敛, 即对角线上的值是否都大于对应行(或者列)的值'''
diag = np.diag(A) diag = np.diag(A)
op = lt if strict else le op = lt if strict else le
if op(A.max(axis=0),diag).all(): return True if op(A.max(axis=0), diag).all():
if op(A.max(axis=1), diag).all(): return True return True
if op(A.max(axis=1), diag).all():
return True
return False return False
testcase = [] testcase = []
def test(): def test():
for func, A, b, x, *args in testcase: for func, A, b, x, *args in testcase:
acc = None acc = None
times = 6 times = 6
if args != []: if args != []:
if isinstance(args[0],int):times = args[0] if isinstance(args[0], int):
else : acc = args[0] times = args[0]
else:
acc = args[0]
return func(A, b, x, acc, times) return func(A, b, x, acc, times)

View File

@ -19,26 +19,34 @@ from functools import reduce
class obj(): class obj():
def __init__(self, data): def __init__(self, data):
self.data = np.array(data) self.data = np.array(data)
def __add__(self, x): def __add__(self, x):
data = x.data if self.__class__ == x.__class__ else x data = x.data if self.__class__ == x.__class__ else x
return self.__class__(self.data + data) return self.__class__(self.data + data)
def __radd__(self, x): def __radd__(self, x):
data = x.data if self.__class__ == x.__class__ else x data = x.data if self.__class__ == x.__class__ else x
return self.__class__(data + self.data) return self.__class__(data + self.data)
def __iadd__(self, x): def __iadd__(self, x):
data = x.data if self.__class__ == x.__class__ else x data = x.data if self.__class__ == x.__class__ else x
self.data += data self.data += data
def __mul__(self, x): def __mul__(self, x):
data = x.data if self.__class__ == x.__class__ else x data = x.data if self.__class__ == x.__class__ else x
return self.__class__(self.data * data) return self.__class__(self.data * data)
def __imul__(self, x): def __imul__(self, x):
data = x.data if self.__class__ == x.__class__ else x data = x.data if self.__class__ == x.__class__ else x
self.data *= data self.data *= data
def __rmul__(self, x): def __rmul__(self, x):
data = x.data if self.__class__ == x.__class__ else x data = x.data if self.__class__ == x.__class__ else x
return self.__class__(data * self.data) return self.__class__(data * self.data)
def __neg__(self): def __neg__(self):
return neg(self) return neg(self)
def __abs__(self): def __abs__(self):
return abs(self.data) return abs(self.data)
''' '''
@ -49,11 +57,14 @@ class obj():
def data(self,s): def data(self,s):
self.data = s self.data = s
''' '''
def norm(self, n=0): def norm(self, n=0):
'''the default is +oo norm''' '''the default is +oo norm'''
absolute = abs(self.data) absolute = abs(self.data)
if n < 1 :return max(absolute) if n < 1:
return max(absolute)
return (sum(absolute**n))**(1/n) return (sum(absolute**n))**(1/n)
def hasNorm(self): def hasNorm(self):
'''check norm's three necessary conditions: '''check norm's three necessary conditions:
1. not neg 1. not neg
@ -65,18 +76,22 @@ class obj():
bl = reduce(and_, [self.norm(i) >= 0 for i in range(3)]) bl = reduce(and_, [self.norm(i) >= 0 for i in range(3)])
if bl: if bl:
n = randint(2, 100) n = randint(2, 100)
bl = reduce(and_,[n*(self.norm(i))==(n*self).norm(i) for i in range(3)]) bl = reduce(and_, [n*(self.norm(i)) == (n*self).norm(i)
for i in range(3)])
if bl: if bl:
another = self*randint(2, 10)-randint(1, 100) another = self*randint(2, 10)-randint(1, 100)
return reduce(and_, [(another+self).norm(i) <= another.norm(i)+self.norm(i) for i in range(3)]) return reduce(and_, [(another+self).norm(i) <= another.norm(i)+self.norm(i) for i in range(3)])
return False return False
class vector(obj): class vector(obj):
def __init__(self, arr): def __init__(self, arr):
''' arr: iterable''' ''' arr: iterable'''
self.data = np.array(arr) self.data = np.array(arr)
def innerProduct(self, x): def innerProduct(self, x):
return sum(self.data*x) return sum(self.data*x)
def outerProduct(self, x): def outerProduct(self, x):
pass pass
@ -104,8 +119,10 @@ class matrix(obj):
def I(self,s): def I(self,s):
self.I = s self.I = s
''' '''
def E(self, n=None): def E(self, n=None):
if n is None: n = self.data.shape[0] if n is None:
n = self.data.shape[0]
return np.eye(n) return np.eye(n)
def norm(self, n=0): def norm(self, n=0):
@ -113,22 +130,27 @@ class matrix(obj):
if n < 1: if n < 1:
# max of one row sum # max of one row sum
return max([sum(i) for i in absolute]) return max([sum(i) for i in absolute])
if n==1:return self.norm1() if n == 1:
elif n==2:return self.norm2() return self.norm1()
elif n == 2:
return self.norm2()
def norm1(self): def norm1(self):
''' max of sum of cols''' ''' max of sum of cols'''
absolute = abs(self.data) absolute = abs(self.data)
return max(absolute.sum(axis=0)) return max(absolute.sum(axis=0))
def norm2(self): def norm2(self):
''' max of sum of rows''' ''' max of sum of rows'''
absolute = abs(self.data) absolute = abs(self.data)
return max(absolute.sum(axis=1)) return max(absolute.sum(axis=1))
def norm_f(self): def norm_f(self):
return sum((self.data**2).sum(axis=1))**0.5 return sum((self.data**2).sum(axis=1))**0.5
if __name__ == '__main__': if __name__ == '__main__':
v1 = vector([1, -2, 3, 4]) v1 = vector([1, -2, 3, 4])
v2 = vector([0, 2, 0, 5]) v2 = vector([0, 2, 0, 5])
m1 = matrix([v1, v2, v2, v1]) m1 = matrix([v1, v2, v2, v1])
print([v1.norm(i) for i in range(3)]) print([v1.norm(i) for i in range(3)])

View File

@ -17,6 +17,7 @@ void calFac(int n)
{ {
int i; int i;
fac[0] = 1; fac[0] = 1;
for (i = 1; i <= n; i++) { for (i = 1; i <= n; i++) {
fac[i] = i * fac[i - 1]; fac[i] = i * fac[i - 1];
} }
@ -27,17 +28,21 @@ void permute(int *arr,int n,int sum)
/*sum表示全排列由小到大排序后的名次,从0 开始计数, 由名次求出 n位的排列存储到 arr 中*/ /*sum表示全排列由小到大排序后的名次,从0 开始计数, 由名次求出 n位的排列存储到 arr 中*/
int i, j, ct = 0, k, ct2; int i, j, ct = 0, k, ct2;
int flag[n]; int flag[n];
for (i = 0; i < n; i++)flag[i] = 1; for (i = 0; i < n; i++)flag[i] = 1;
for (i = n - 1; i >= 0; i--) { for (i = n - 1; i >= 0; i--) {
for (j = i; j >= 0; j--) { for (j = i; j >= 0; j--) {
if (j * fac[i] <= sum) { if (j * fac[i] <= sum) {
ct2 = 0; ct2 = 0;
for (k = 0; k < n; ++k) { for (k = 0; k < n; ++k) {
//printf("i%d j%d k%d\n",i,j,k); //printf("i%d j%d k%d\n",i,j,k);
if (flag[k] == 1)ct2++; if (flag[k] == 1)ct2++;
if (ct2 > j)break; if (ct2 > j)break;
} }
arr[ct++] = k; arr[ct++] = k;
flag[k] = 0; flag[k] = 0;
sum -= j * fac[i]; sum -= j * fac[i];
@ -50,6 +55,7 @@ void permute(int *arr,int n,int sum)
void printArr(int *p, int n) void printArr(int *p, int n)
{ {
for (int i = 0; i < n; ++i)printf("%d, ", p[i]); for (int i = 0; i < n; ++i)printf("%d, ", p[i]);
printf("\n"); printf("\n");
} }
@ -57,11 +63,13 @@ int main()
{ {
int n = 5, arr[n]; int n = 5, arr[n];
calFac(n); calFac(n);
for (int i = 0; i < 5; ++i)arr[i] = i; for (int i = 0; i < 5; ++i)arr[i] = i;
for (int i = 0; i < fac[n]; ++i) { for (int i = 0; i < fac[n]; ++i) {
printArr(arr, n); printArr(arr, n);
permute(arr, n, i); permute(arr, n, i);
} }
return 0; return 0;
} }

View File

@ -1,6 +1,6 @@
''' mbinary ''' mbinary
######################################################################### #########################################################################
# File : 8Astar.py # File : Astar.py
# Author: mbinary # Author: mbinary
# Mail: zhuheqin1@gmail.com # Mail: zhuheqin1@gmail.com
# Blog: https://mbinary.xyz # Blog: https://mbinary.xyz
@ -10,6 +10,7 @@
######################################################################### #########################################################################
''' '''
from random import shuffle
isVisited = [0]*362880 # 0 for not visited,1 for occured,2 for visited isVisited = [0]*362880 # 0 for not visited,1 for occured,2 for visited
fac = [1, 1, 2, 6, 24, 120, 720, 5040, 40320] fac = [1, 1, 2, 6, 24, 120, 720, 5040, 40320]
lf = len(fac) lf = len(fac)
@ -23,20 +24,26 @@ h = [[0,1,2,1,2,3,2,3,4],
[3, 2, 3, 2, 1, 2, 1, 0, 1], [3, 2, 3, 2, 1, 2, 1, 0, 1],
[4, 3, 2, 3, 2, 1, 2, 1, 0]] [4, 3, 2, 3, 2, 1, 2, 1, 0]]
def cantor(s): def cantor(s):
sum = 0 sum = 0
ls = len(s) ls = len(s)
for i in range(ls): for i in range(ls):
count = 0 count = 0
for j in range(i+1, ls): for j in range(i+1, ls):
if s[i] > s[j]: count +=1 if s[i] > s[j]:
count += 1
sum += count*fac[lf-i-1] sum += count*fac[lf-i-1]
return sum return sum
que = [] que = []
dir = {-3: 'u', 1: 'r', 3: 'd', -1: 'l'} dir = {-3: 'u', 1: 'r', 3: 'd', -1: 'l'}
class state: class state:
flag = True flag = True
def __init__(self, s, x, f, step=0, last=0): def __init__(self, s, x, f, step=0, last=0):
self.x = x self.x = x
self.s = list(s) self.s = list(s)
@ -44,6 +51,7 @@ class state:
self.path = [] self.path = []
self.last = last self.last = last
self.f = f self.f = f
def can(self): def can(self):
cans = [-1, 1, 3, -3] cans = [-1, 1, 3, -3]
if self.last in cans: if self.last in cans:
@ -57,6 +65,7 @@ class state:
if self.x % 3 is 2: if self.x % 3 is 2:
cans.remove(1) cans.remove(1)
return cans return cans
def move(self): def move(self):
cans = self.can() cans = self.can()
for i in cans: for i in cans:
@ -67,7 +76,8 @@ class state:
ct = cantor(s) ct = cantor(s)
if isVisited[ct] != 2: if isVisited[ct] != 2:
val = int(s[self.x]) val = int(s[self.x])
f = h[8][tmp] +h[val-1][self.x]-h[8][self.x]-h[val-1][tmp]+self.step+1 f = h[8][tmp] + h[val-1][self.x] - \
h[8][self.x]-h[val-1][tmp]+self.step+1
new = state(s, tmp, f, self.step + 1, i) new = state(s, tmp, f, self.step + 1, i)
new.path = self.path + [dir[i]] new.path = self.path + [dir[i]]
if isVisited[ct] == 1: if isVisited[ct] == 1:
@ -75,21 +85,30 @@ class state:
if mew.s == node.s: if mew.s == node.s:
del que[i] del que[i]
break break
else:isVisited[ct] = 1 else:
isVisited[ct] = 1
if que == []: if que == []:
que.append(new) que.append(new)
continue continue
for i, node in enumerate(que): for i, node in enumerate(que):
if new.f <= node.f: if new.f <= node.f:
que.insert(i, new) que.insert(i, new)
def solvable(s): def solvable(s):
reverse = 0 reverse = 0
for i in range(8): for i in range(8):
if s[i] is '9':continue if s[i] is '9':
continue
for j in range(i+1, 9): for j in range(i+1, 9):
if s[i]>s[j]:reverse +=1 if s[i] > s[j]:
if reverse % 2 is 0:return True reverse += 1
else:return False if reverse % 2 is 0:
return True
else:
return False
def getPath(s, index): def getPath(s, index):
f = 0 f = 0
for i, j in enumerate(s): for i, j in enumerate(s):
@ -102,6 +121,8 @@ def getPath(s,index):
if ct is 0: if ct is 0:
return cur.path return cur.path
cur.move() cur.move()
def info(): def info():
print('input a 3x3 matrix in one line') print('input a 3x3 matrix in one line')
print('from left to right,from up to down') print('from left to right,from up to down')
@ -111,8 +132,10 @@ def info():
print('1 2 3\n4 5 6\n7 8 x') print('1 2 3\n4 5 6\n7 8 x')
print('print q to quit') print('print q to quit')
from random import shuffle
case = list('12345678x') case = list('12345678x')
def genCase(): def genCase():
tmp = case.copy() tmp = case.copy()
shuffle(tmp) shuffle(tmp)
@ -124,6 +147,8 @@ def genCase():
break break
tmp[index] = '9' tmp[index] = '9'
return tmp, index return tmp, index
def isValid(li): def isValid(li):
for i in '123456789': for i in '123456789':
if not i in li: if not i in li:
@ -131,6 +156,7 @@ def isValid(li):
return False return False
return True return True
def run(): def run():
while 1: while 1:
print('\n\n'+'-'*10+'Game Begins' + '-'*10) print('\n\n'+'-'*10+'Game Begins' + '-'*10)
@ -146,7 +172,8 @@ def run():
li, index = genCase() li, index = genCase()
if solvable(li): if solvable(li):
print(''.join(getPath(li, index))) print(''.join(getPath(li, index)))
else:print('unsolvable') else:
print('unsolvable')
if __name__ == '__main__': if __name__ == '__main__':

View File

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

View File

@ -15,6 +15,10 @@
设有n个任务由k个可并行工作的机器来完成完成任务i需要时间为 试设计一个算法找出完成这n个任务的最佳调度使完成全部任务的时间最早 设有n个任务由k个可并行工作的机器来完成完成任务i需要时间为 试设计一个算法找出完成这n个任务的最佳调度使完成全部任务的时间最早
''' '''
from time import time from time import time
from functools import total_ordering from functools import total_ordering
@total_ordering @total_ordering
@ -24,23 +28,32 @@ class record:
nums = [] nums = []
self.nums = nums self.nums = nums
self.sum = sum(nums) self.sum = sum(nums)
def append(self, x): def append(self, x):
self.nums.append(x) self.nums.append(x)
self.sum += x self.sum += x
def pop(self): def pop(self):
x = self.nums.pop() x = self.nums.pop()
self.sum -= x self.sum -= x
return x return x
def __repr__(self): def __repr__(self):
return repr(self.nums) return repr(self.nums)
def __lt__(self, r): def __lt__(self, r):
return self.sum < r.sum return self.sum < r.sum
def __eq__(self, r): def __eq__(self, r):
return self.sum == r.sum return self.sum == r.sum
def tolist(self): def tolist(self):
return self.nums.copy() return self.nums.copy()
def __hash__(self): def __hash__(self):
return self.sum return self.sum
def schedule(works, k): def schedule(works, k):
def backtrackSearch(i, lsts): def backtrackSearch(i, lsts):
nonlocal best, rst nonlocal best, rst
@ -55,11 +68,13 @@ def schedule(works,k):
cur.append(works[i]) cur.append(works[i])
backtrackSearch(i+1, lsts) backtrackSearch(i+1, lsts)
cur.pop() cur.pop()
def findInitial(i, lst): def findInitial(i, lst):
nonlocal best nonlocal best
if i == n: if i == n:
cost = max(lst) cost = max(lst)
if best>cost:best = cost if best > cost:
best = cost
else: else:
mn = lst[0] mn = lst[0]
idx = 0 idx = 0
@ -74,7 +89,6 @@ def schedule(works,k):
findInitial(i+1, lst) findInitial(i+1, lst)
lst[idx] -= works[i] lst[idx] -= works[i]
n = len(works) n = len(works)
print() print()
print('machine Num:', n) print('machine Num:', n)
@ -93,11 +107,13 @@ def schedule(works,k):
print('schedule plan:', rst) print('schedule plan:', rst)
return best, rst return best, rst
if __name__ == '__main__': if __name__ == '__main__':
from random import randint from random import randint
schedule([47, 20, 28, 44, 21, 45, 30, 39, 28, 33], 3) schedule([47, 20, 28, 44, 21, 45, 30, 39, 28, 33], 3)
schedule([98, 84, 50, 23, 32, 99, 22, 76, 72, 61, 81, 39, 76, 54, 37], 5) schedule([98, 84, 50, 23, 32, 99, 22, 76, 72, 61, 81, 39, 76, 54, 37], 5)
schedule([39,39,23,45,100,69,21,81,39,55,20,86,34,53,58,99,36,45,46],8) schedule([39, 39, 23, 45, 100, 69, 21, 81, 39, 55,
20, 86, 34, 53, 58, 99, 36, 45, 46], 8)
''' '''
machine Num: 19 machine Num: 19

View File

@ -12,6 +12,11 @@
''' '''
设有n件工作要分配给n个人去完成将工作i分配给第j个人所需费用为c_ij 试设计一个算法为每个人分配1件不同的工作并使总费用达到最小 设有n件工作要分配给n个人去完成将工作i分配给第j个人所需费用为c_ij 试设计一个算法为每个人分配1件不同的工作并使总费用达到最小
''' '''
import random
def dispatch(mat): def dispatch(mat):
'''mat: matrix of c_ij''' '''mat: matrix of c_ij'''
def _util(i, arrange, cost): def _util(i, arrange, cost):
@ -35,7 +40,6 @@ def dispatch(mat):
return total, rst return total, rst
import random
if __name__ == '__main__': if __name__ == '__main__':
n = 10 n = 10
mat = [[random.randint(1, 100) for i in range(n)] for i in range(n)] mat = [[random.randint(1, 100) for i in range(n)] for i in range(n)]
@ -44,5 +48,3 @@ if __name__=='__main__':
print(mat[i]) print(mat[i])
print('result: ', end='') print('result: ', end='')
print(dispatch(mat)) print(dispatch(mat))

View File

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

View File

@ -11,16 +11,23 @@
''' '''
from functools import partial from functools import partial
class heap: class heap:
def __init__(self, lst, reverse=False): def __init__(self, lst, reverse=False):
self.data = heapify(lst, reverse) self.data = heapify(lst, reverse)
self.cmp = partial(lambda i,j,r:cmp(self.data[i],self.data[j],r),r= reverse) self.cmp = partial(lambda i, j, r: cmp(
self.data[i], self.data[j], r), r=reverse)
def getTop(self): def getTop(self):
return self.data[0] return self.data[0]
def __getitem__(self, idx): def __getitem__(self, idx):
return self.data[idx] return self.data[idx]
def __bool__(self): def __bool__(self):
return self.data != [] return self.data != []
def popTop(self): def popTop(self):
ret = self.data[0] ret = self.data[0]
n = len(self.data) n = len(self.data)
@ -46,14 +53,19 @@ class heap:
def cmp(n1, n2, reverse=False): def cmp(n1, n2, reverse=False):
fac = -1 if reverse else 1 fac = -1 if reverse else 1
if n1 < n2: return -fac if n1 < n2:
elif n1 > n2: return fac return -fac
elif n1 > n2:
return fac
return 0 return 0
def heapify(lst, reverse=False): def heapify(lst, reverse=False):
for i in range(len(lst)): for i in range(len(lst)):
lst = one_heapify(lst, i, reverse) lst = one_heapify(lst, i, reverse)
return lst return lst
def one_heapify(lst, cur, reverse=False): def one_heapify(lst, cur, reverse=False):
cur += 1 cur += 1
while cur > 1: while cur > 1:
@ -64,6 +76,8 @@ def one_heapify(lst,cur,reverse = False):
lst[prt], lst[chd] = lst[chd], lst[prt] lst[prt], lst[chd] = lst[chd], lst[prt]
cur = prt+1 cur = prt+1
return lst return lst
def heapSort(lst, reverse=False): def heapSort(lst, reverse=False):
lst = lst.copy() lst = lst.copy()
hp = heap(lst, reverse) hp = heap(lst, reverse)

View File

@ -12,12 +12,17 @@
int partition(int *arr, int i, int j) int partition(int *arr, int i, int j)
{ {
int pivot = arr[j], p = i, q = j; int pivot = arr[j], p = i, q = j;
while (p < q) { while (p < q) {
while (p < q && arr[p] <= pivot)++p; while (p < q && arr[p] <= pivot)++p;
if (p < q)arr[q--] = arr[p]; if (p < q)arr[q--] = arr[p];
while (p < q && arr[q] > pivot)--q; while (p < q && arr[q] > pivot)--q;
if (p < q)arr[p++] = arr[q]; if (p < q)arr[p++] = arr[q];
} }
arr[p] = pivot; arr[p] = pivot;
return p; return p;
} }

View File

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

View File

@ -10,6 +10,11 @@
######################################################################### #########################################################################
''' '''
from random import randint
from quickSort import quickSort
from time import time
def radixSort(lst, radix=10): def radixSort(lst, radix=10):
ls = [[] for i in range(radix)] ls = [[] for i in range(radix)]
mx = max(lst) mx = max(lst)
@ -22,6 +27,7 @@ def radixSort(lst,radix=10):
ls = [[] for i in range(radix)] ls = [[] for i in range(radix)]
return lst return lst
def countSort(lst, mn, mx): def countSort(lst, mn, mx):
mark = [0]*(mx-mn+1) mark = [0]*(mx-mn+1)
for i in lst: for i in lst:
@ -31,9 +37,7 @@ def countSort(lst,mn,mx):
ret += [n+mn]*i ret += [n+mn]*i
return ret return ret
from quickSort import quickSort
from time import time
from random import randint
def timer(funcs, span, num=1000000): def timer(funcs, span, num=1000000):
lst = [randint(0, span) for i in range(num)] lst = [randint(0, span) for i in range(num)]
print('range({}), {} items'.format(span, num)) print('range({}), {} items'.format(span, num))

View File

@ -11,16 +11,21 @@
''' '''
from random import randint from random import randint
def select(lst, i): def select(lst, i):
lst = lst.copy() lst = lst.copy()
def partition(a, b): def partition(a, b):
pivot = lst[a] pivot = lst[a]
while a < b: while a < b:
while a<b and lst[b]>pivot: b-=1 while a < b and lst[b] > pivot:
b -= 1
if a < b: if a < b:
lst[a] = lst[b] lst[a] = lst[b]
a += 1 a += 1
while a<b and lst[a]<pivot: a+=1 while a < b and lst[a] < pivot:
a += 1
if a < b: if a < b:
lst[b] = lst[a] lst[b] = lst[a]
b -= 1 b -= 1
@ -28,7 +33,8 @@ def select(lst,i):
return a return a
def _select(a, b): def _select(a, b):
if a>=b: return lst[a] if a >= b:
return lst[a]
# randomized select # randomized select
n = randint(a, b) n = randint(a, b)
lst[a], lst[n] = lst[n], lst[a] lst[a], lst[n] = lst[n], lst[a]
@ -37,7 +43,8 @@ def select(lst,i):
return _select(a, pos-1) return _select(a, pos-1)
elif pos < i: elif pos < i:
return _select(pos+1, b) return _select(pos+1, b)
else:return lst[pos] else:
return lst[pos]
return _select(0, len(lst)-1) return _select(0, len(lst)-1)
@ -46,4 +53,5 @@ if __name__ =='__main__':
st = sorted(lst) st = sorted(lst)
for i in range(10): for i in range(10):
n = randint(0, 99) n = randint(0, 99)
print('select {}th: \nexpect: {}\ngot: {}'.format(n,st[n],select(lst,n))) print('select {}th: \nexpect: {}\ngot: {}'.format(
n, st[n], select(lst, n)))

View File

@ -10,6 +10,7 @@
######################################################################### #########################################################################
''' '''
def shellSort(s, gaps=None): def shellSort(s, gaps=None):
if gaps is None: if gaps is None:
gaps = [127, 63, 31, 15, 7, 3, 1] gaps = [127, 63, 31, 15, 7, 3, 1]
@ -24,6 +25,7 @@ def shellSort(s,gaps=None):
s[cur] = num s[cur] = num
return s return s
if __name__ == '__main__': if __name__ == '__main__':
from random import randint from random import randint
import sys import sys

View File

@ -11,6 +11,7 @@
######################################################################### #########################################################################
''' '''
def getPrefixFunc(s): def getPrefixFunc(s):
'''return the list of prefix function of s''' '''return the list of prefix function of s'''
length = 0 length = 0
@ -30,6 +31,7 @@ def getPrefixFunc(s):
length = ret[length-1] length = ret[length-1]
return ret return ret
def findAll(s, p): def findAll(s, p):
pre = getPrefixFunc(p) pre = getPrefixFunc(p)
i = j = 0 i = j = 0
@ -43,12 +45,17 @@ def findAll(s,p):
ret.append(i-j) ret.append(i-j)
j = pre[j-1] j = pre[j-1]
else: else:
if j==0: i+=1 if j == 0:
else: j = pre[j-1] i += 1
else:
j = pre[j-1]
return ret return ret
def randStr(n=3): def randStr(n=3):
return [randint(ord('a'), ord('z')) for i in range(n)] return [randint(ord('a'), ord('z')) for i in range(n)]
if __name__ == '__main__': if __name__ == '__main__':
from random import randint from random import randint
s = randStr(50) s = randStr(50)

View File

@ -10,6 +10,7 @@
######################################################################### #########################################################################
''' '''
class Solution: class Solution:
def longestPalindrome(self, s): def longestPalindrome(self, s):
""" """
@ -27,12 +28,13 @@ class Solution:
ct[cur] = 1 ct[cur] = 1
while s2[cur-ct[cur]] == s2[cur+ct[cur]]: while s2[cur-ct[cur]] == s2[cur+ct[cur]]:
ct[cur] += 1 ct[cur] += 1
if cur+ct[cur] > mid+ct[mid]:mid = cur if cur+ct[cur] > mid+ct[mid]:
mid = cur
mx = max(ct) mx = max(ct)
idxs = [i for i, j in enumerate(ct) if j == mx] idxs = [i for i, j in enumerate(ct) if j == mx]
p = idxs[0] p = idxs[0]
for i in idxs: for i in idxs:
if s2[i]=='#':p = i if s2[i] == '#':
p = i
rst = s2[p-mx+1:p+mx].replace('#', '') rst = s2[p-mx+1:p+mx].replace('#', '')
return rst return rst

View File

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

View File

@ -27,6 +27,8 @@ When the window is no longer valid, start expanding again using the right pointe
''' '''
from collections import defaultdict from collections import defaultdict
class Solution: class Solution:
def minWindow(self, s: str, t: str) -> str: def minWindow(self, s: str, t: str) -> str:
def expand(j, lacked, dic): def expand(j, lacked, dic):
@ -38,6 +40,7 @@ class Solution:
dic[s[j]] += 1 dic[s[j]] += 1
j += 1 j += 1
return j return j
def contract(left, right): def contract(left, right):
for i in range(left, right): for i in range(left, right):
dic[s[i]] -= 1 dic[s[i]] -= 1

View File

@ -11,14 +11,21 @@
######################################################################### #########################################################################
''' '''
def isPrime(x): def isPrime(x):
for i in range(2, int(x**0.5)+1): for i in range(2, int(x**0.5)+1):
if x%i==0:return False if x % i == 0:
return False
return True return True
def getPrime(x): def getPrime(x):
'''return a prime which is bigger than x''' '''return a prime which is bigger than x'''
for i in range(x, 2*x): for i in range(x, 2*x):
if isPrime(i):return i if isPrime(i):
return i
def findAll(s, p): def findAll(s, p):
'''s: string p: pattern''' '''s: string p: pattern'''
dic = {} dic = {}
@ -30,13 +37,16 @@ def findAll(s,p):
d += 1 d += 1
sm = 0 sm = 0
for c in p: for c in p:
if c not in dic:return [] if c not in dic:
return []
sm = sm*d+dic[c] sm = sm*d+dic[c]
ret = [] ret = []
cur = 0 cur = 0
for i in range(m): cur=cur*d + dic[s[i]] for i in range(m):
if cur==sm:ret.append(0) cur = cur*d + dic[s[i]]
if cur == sm:
ret.append(0)
tmp = n-m tmp = n-m
q = getPrime(m) q = getPrime(m)
cur = cur % q cur = cur % q
@ -48,9 +58,11 @@ def findAll(s,p):
ret.append(i-m+1) ret.append(i-m+1)
return ret return ret
def randStr(n=3): def randStr(n=3):
return [randint(ord('a'), ord('z')) for i in range(n)] return [randint(ord('a'), ord('z')) for i in range(n)]
if __name__ == '__main__': if __name__ == '__main__':
from random import randint from random import randint
s = randStr(50) s = randStr(50)

View File

@ -17,6 +17,7 @@
######################################################################### #########################################################################
''' '''
def rotate(s, k, right=False): def rotate(s, k, right=False):
def reverse(a, b): def reverse(a, b):
while a < b: while a < b:
@ -31,14 +32,15 @@ def rotate(s,k,right=False):
return s return s
def rotate2(s, k, right=False): def rotate2(s, k, right=False):
def swap(a, b, c): def swap(a, b, c):
for i in range(c): for i in range(c):
s[a+i], s[b+i] = s[b+i], s[a+i] s[a+i], s[b+i] = s[b+i], s[a+i]
def _rot(pl, pr): def _rot(pl, pr):
''' swap s[pl,pr) , s[pr:]''' ''' swap s[pl,pr) , s[pr:]'''
if pr==n:return if pr == n:
return
if pr-pl <= n-pr: if pr-pl <= n-pr:
swap(pl, pr, pr-pl) swap(pl, pr, pr-pl)
_rot(pr, 2*pr-pl) _rot(pr, 2*pr-pl)
@ -51,10 +53,10 @@ def rotate2(s,k,right=False):
return s return s
def rotate3(s, k, right=False): def rotate3(s, k, right=False):
def gcd(a, b): def gcd(a, b):
if b==0:return a if b == 0:
return a
return gcd(b, a % b) return gcd(b, a % b)
n = len(s) n = len(s)
@ -72,7 +74,8 @@ def rotate3(s,k,right=False):
def test(): def test():
def f(func, *args, right=False): def f(func, *args, right=False):
print(' '.join(['testing:',func.__name__,str(args),'right=',str(right)])) print(' '.join(['testing:', func.__name__,
str(args), 'right=', str(right)]))
rst = func(*args, right=right) rst = func(*args, right=right)
print('result', rst) print('result', rst)
print() print()

View File

@ -12,13 +12,14 @@
''' '''
def getPos(pattern): def getPos(pattern):
dic = {} dic = {}
for i, j in enumerate(pattern[::-1]): for i, j in enumerate(pattern[::-1]):
if j not in dic: if j not in dic:
dic[j] = i dic[j] = i
return dic return dic
def find(s, p): def find(s, p):
dic = getPos(p) dic = getPos(p)
ps = pp = 0 ps = pp = 0
@ -29,16 +30,20 @@ def find(s,p):
ps, pp = ps+1, pp+1 ps, pp = ps+1, pp+1
else: else:
idx = ps + np-pp idx = ps + np-pp
if idx >=ns:return -1 if idx >= ns:
return -1
ch = s[idx] ch = s[idx]
if ch in dic: if ch in dic:
ps += dic[ch]+1-pp ps += dic[ch]+1-pp
else: else:
ps = idx+1 ps = idx+1
pp = 0 pp = 0
if pp==np:return ps-np if pp == np:
return ps-np
else: else:
return -1 return -1
def findAll(s, p): def findAll(s, p):
ns = len(s) ns = len(s)
np = len(p) np = len(p)
@ -47,7 +52,8 @@ def findAll(s,p):
while s: while s:
print(s, p) print(s, p)
tmp = find(s, p) tmp = find(s, p)
if tmp==-1: break if tmp == -1:
break
ret.append(i+tmp) ret.append(i+tmp)
end = tmp+np end = tmp+np
i += end i += end
@ -55,10 +61,10 @@ def findAll(s,p):
return ret return ret
def randStr(n=3): def randStr(n=3):
return [randint(ord('a'), ord('z')) for i in range(n)] return [randint(ord('a'), ord('z')) for i in range(n)]
def test(n): def test(n):
s = randStr(n) s = randStr(n)
p = randStr(3) p = randStr(3)
@ -70,6 +76,8 @@ def test(n):
print(n1, n2, str_p, str_s) print(n1, n2, str_p, str_s)
return False return False
return True return True
if __name__ == '__main__': if __name__ == '__main__':
from random import randint from random import randint
n = 1000 n = 1000

View File

@ -33,6 +33,7 @@ else : dp[j][i] = dp[j-1][i-1] and s[i] == p[j]
# leetcode: q44 https://leetcode.com/problems/wildcard-matching/description/ # leetcode: q44 https://leetcode.com/problems/wildcard-matching/description/
def isMatch(self, s, p): def isMatch(self, s, p):
""" """
:type s: str :type s: str

View File

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

View File

@ -17,7 +17,8 @@ from config import README
parser = ArgumentParser() parser = ArgumentParser()
parser.add_argument('-p', '--path', default='.', help='path to walk') parser.add_argument('-p', '--path', default='.', help='path to walk')
parser.add_argument('-f','--fileinclude',action='store_true',default=True,help='if has, list files and dirs, else only dirs') parser.add_argument('-f', '--fileinclude', action='store_true',
default=True, help='if has, list files and dirs, else only dirs')
parser.add_argument('-d', '--depth', type=int, default=2) parser.add_argument('-d', '--depth', type=int, default=2)
# 获取参数 # 获取参数
args = parser.parse_args() args = parser.parse_args()

View File

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

View File

@ -17,7 +17,8 @@ from argparse import ArgumentParser
parser = ArgumentParser() parser = ArgumentParser()
parser.add_argument('-p', '--path', default='.', help='path to walk') parser.add_argument('-p', '--path', default='.', help='path to walk')
parser.add_argument('-f','--fileinclude',action='store_true',help='if has, list files and dirs, else only dirs') parser.add_argument('-f', '--fileinclude', action='store_true',
help='if has, list files and dirs, else only dirs')
parser.add_argument('-d', '--depth', type=int, default=2) parser.add_argument('-d', '--depth', type=int, default=2)
# 获取参数 # 获取参数
args = parser.parse_args() args = parser.parse_args()
@ -25,8 +26,11 @@ FILE = args.fileinclude
PATH = args.path PATH = args.path
DEPTH = args.depth DEPTH = args.depth
def mklink(path): def mklink(path):
return '* [{name}]({path})'.format(name=os.path.basename(path), path=path) return '* [{name}]({path})'.format(name=os.path.basename(path), path=path)
def clean(paths): def clean(paths):
ret = [] ret = []
for path in paths: for path in paths:
@ -35,14 +39,18 @@ def clean(paths):
ret.append(path) ret.append(path)
return ret return ret
def tree(path='.', depth=2, showfile=False): def tree(path='.', depth=2, showfile=False):
li = [] li = []
if os.path.isdir(path):li = os.listdir(path) if os.path.isdir(path):
else:li=[path] li = os.listdir(path)
else:
li = [path]
items = [os.path.join(path, i) for i in li if not i.startswith('.')] items = [os.path.join(path, i) for i in li if not i.startswith('.')]
items = clean(items) items = clean(items)
items = sorted(items) items = sorted(items)
if not showfile: items = [i for i in items if os.path.isdir(i)] if not showfile:
items = [i for i in items if os.path.isdir(i)]
if depth == 1: if depth == 1:
return [mklink(path)] + [' '*4 + mklink(i) for i in items] return [mklink(path)] + [' '*4 + mklink(i) for i in items]
else: else:
@ -50,5 +58,6 @@ def tree(path='.',depth=2,showfile=False):
ret = [' '*4 + li for ul in uls for li in ul] ret = [' '*4 + li for ul in uls for li in ul]
return [mklink(path)] + ret return [mklink(path)] + ret
if __name__ == '__main__': if __name__ == '__main__':
print('\n'.join(tree(PATH, DEPTH, FILE))) print('\n'.join(tree(PATH, DEPTH, FILE)))