mirror of
https://github.com/heqin-zhu/algorithm.git
synced 2024-03-22 13:30:46 +08:00
Format codes
This commit is contained in:
parent
985b29ce65
commit
ab86fa483a
10
README.md
10
README.md
|
@ -6,7 +6,7 @@
|
|||
[![repo-size](https://img.shields.io/github/repo-size/mbinary/algorithm.svg)]()
|
||||
[![License](https://img.shields.io/badge/LICENSE-WTFPL-blue.svg)](LICENSE)
|
||||
[![Language](https://img.shields.io/badge/language-python3-orange.svg)]()
|
||||
[![codebeat badge](https://codebeat.co/badges/d52dd17d-a437-4dee-a6ec-cb532e8135bd)](https://codebeat.co/projects/github-com-mbinary-algorithm-master)
|
||||
[![codebeat badge](https://codebeat.co/badges/4ef725b5-405a-4390-a860-a86deefab3f8)](https://codebeat.co/projects/github-com-mbinary-algorithm-master)
|
||||
|
||||
>Notes and codes for learning algorithm and data structures :smiley:
|
||||
|
||||
|
@ -17,12 +17,10 @@ Some pictures and ideas are from `<<Introduction to Algotithm>>`
|
|||
* [.](.)
|
||||
* [LICENSE](./LICENSE)
|
||||
* [README.md](./README.md)
|
||||
* [backtracking](./backtracking)
|
||||
* [dataStructure](./dataStructure)
|
||||
* [LRU](./dataStructure/LRU)
|
||||
* [bTree.py](./dataStructure/bTree.py)
|
||||
* [binaryHeap.py](./dataStructure/binaryHeap.py)
|
||||
* [binaryHeap1.py](./dataStructure/binaryHeap1.py)
|
||||
* [binaryTree.py](./dataStructure/binaryTree.py)
|
||||
* [circularQueue.py](./dataStructure/circularQueue.py)
|
||||
* [graph](./dataStructure/graph)
|
||||
|
@ -32,7 +30,6 @@ Some pictures and ideas are from `<<Introduction to Algotithm>>`
|
|||
* [intervalTree.py](./dataStructure/intervalTree.py)
|
||||
* [leftHeap.py](./dataStructure/leftHeap.py)
|
||||
* [linkedList.py](./dataStructure/linkedList.py)
|
||||
* [loserTree.py](./dataStructure/loserTree.py)
|
||||
* [map.cc](./dataStructure/map.cc)
|
||||
* [polynomial.cpp](./dataStructure/polynomial.cpp)
|
||||
* [polynomial.py](./dataStructure/polynomial.py)
|
||||
|
@ -40,7 +37,7 @@ Some pictures and ideas are from `<<Introduction to Algotithm>>`
|
|||
* [redBlackTree0.py](./dataStructure/redBlackTree0.py)
|
||||
* [splayTree.py](./dataStructure/splayTree.py)
|
||||
* [trie](./dataStructure/trie)
|
||||
* [unionFindSet](./dataStructure/unionFindSet)
|
||||
* [unionFindSet.py](./dataStructure/unionFindSet.py)
|
||||
* [winnerTree.py](./dataStructure/winnerTree.py)
|
||||
* [divideAndConquer](./divideAndConquer)
|
||||
* [min_distance_of_n_points.py](./divideAndConquer/min_distance_of_n_points.py)
|
||||
|
@ -85,8 +82,9 @@ Some pictures and ideas are from `<<Introduction to Algotithm>>`
|
|||
* [PL0-compiler](./parser/PL0-compiler)
|
||||
* [calculator](./parser/calculator)
|
||||
* [declarationParser](./parser/declarationParser)
|
||||
* [poly.c](./poly.c)
|
||||
* [search](./search)
|
||||
* [8Astar.py](./search/8Astar.py)
|
||||
* [Astar.py](./search/Astar.py)
|
||||
* [BFS_knight.hs](./search/BFS_knight.hs)
|
||||
* [binary_search.hs](./search/binary_search.hs)
|
||||
* [bloomFilter.py](./search/bloomFilter.py)
|
||||
|
|
|
@ -10,61 +10,87 @@
|
|||
#########################################################################
|
||||
'''
|
||||
|
||||
|
||||
class node:
|
||||
def __init__(self, keys=None, isLeaf=True, children=None):
|
||||
if keys is None:keys=[]
|
||||
if children is None: children =[]
|
||||
if keys is None:
|
||||
keys = []
|
||||
if children is None:
|
||||
children = []
|
||||
self.keys = keys
|
||||
self.isLeaf = isLeaf
|
||||
self.children = []
|
||||
|
||||
def __getitem__(self, i):
|
||||
return self.keys[i]
|
||||
|
||||
def __delitem__(self, i):
|
||||
del self.keys[i]
|
||||
|
||||
def __setitem__(self, i, k):
|
||||
self.keys[i] = k
|
||||
|
||||
def __len__(self):
|
||||
return len(self.keys)
|
||||
|
||||
def __repr__(self):
|
||||
return str(self.keys)
|
||||
|
||||
def __str__(self):
|
||||
children = ','.join([str(nd.keys) for nd in self.children])
|
||||
return f'keys: {self.keys}\nchildren: {children}\nisLeaf: {self.isLeaf}'
|
||||
|
||||
def getChd(self, i):
|
||||
return self.children[i]
|
||||
|
||||
def delChd(self, i):
|
||||
del self.children[i]
|
||||
|
||||
def setChd(self, i, chd):
|
||||
self.children[i] = chd
|
||||
|
||||
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]
|
||||
|
||||
def findKey(self, key):
|
||||
for i, k in enumerate(self.keys):
|
||||
if k >= key:
|
||||
return i
|
||||
return len(self)
|
||||
|
||||
def update(self, keys=None, isLeaf=None, children=None):
|
||||
if keys is not None:self.keys = keys
|
||||
if children is not None:self.children = children
|
||||
if isLeaf is not None: self.isLeaf = isLeaf
|
||||
if keys is not None:
|
||||
self.keys = keys
|
||||
if children is not None:
|
||||
self.children = children
|
||||
if isLeaf is not None:
|
||||
self.isLeaf = isLeaf
|
||||
|
||||
def insert(self, i, key=None, nd=None):
|
||||
if key is not None:self.keys.insert(i,key)
|
||||
if not self.isLeaf and nd is not None: self.children.insert(i,nd)
|
||||
if key is not None:
|
||||
self.keys.insert(i, key)
|
||||
if not self.isLeaf and nd is not None:
|
||||
self.children.insert(i, nd)
|
||||
|
||||
def isLeafNode(self): return self.isLeaf
|
||||
|
||||
def split(self, prt, t):
|
||||
# form new two nodes
|
||||
k = self[t-1]
|
||||
nd1 = node()
|
||||
nd2 = node()
|
||||
nd1.keys,nd2.keys = self[:t-1], self[t:] # note that t is 1 bigger than key index
|
||||
# note that t is 1 bigger than key index
|
||||
nd1.keys, nd2.keys = self[:t-1], self[t:]
|
||||
nd1.isLeaf = nd2.isLeaf = self.isLeaf
|
||||
if not self.isLeaf:
|
||||
# note that children index is one bigger than key index, and all children included
|
||||
nd1.children, nd2.children = self.children[0:t], self.children[t:]
|
||||
# connect them to parent
|
||||
idx = prt.findKey(k)
|
||||
if prt.children !=[]: prt.children.remove(self) # remove the original node
|
||||
if prt.children != []:
|
||||
prt.children.remove(self) # remove the original node
|
||||
prt.insert(idx, k, nd2)
|
||||
prt.insert(idx, nd=nd1)
|
||||
return prt
|
||||
|
@ -76,20 +102,28 @@ class bTree:
|
|||
self.degree = degree
|
||||
self.nodeNum = 1
|
||||
self.keyNum = 0
|
||||
|
||||
def search(self, key, withpath=False):
|
||||
nd = self.root
|
||||
fathers = []
|
||||
while True:
|
||||
i = nd.findKey(key)
|
||||
if i==len(nd): fathers.append((nd,i-1,i))
|
||||
else: fathers.append((nd,i,i))
|
||||
if i == len(nd):
|
||||
fathers.append((nd, i-1, i))
|
||||
else:
|
||||
fathers.append((nd, i, i))
|
||||
if i < len(nd) and nd[i] == key:
|
||||
if withpath:return nd,i,fathers
|
||||
else:return nd,i
|
||||
if withpath:
|
||||
return nd, i, fathers
|
||||
else:
|
||||
return nd, i
|
||||
if nd.isLeafNode():
|
||||
if withpath:return None,None,None
|
||||
else:return None,None
|
||||
if withpath:
|
||||
return None, None, None
|
||||
else:
|
||||
return None, None
|
||||
nd = nd.getChd(i)
|
||||
|
||||
def insert(self, key):
|
||||
if len(self.root) == self.degree*2-1:
|
||||
self.root = self.root.split(node(isLeaf=False), self.degree)
|
||||
|
@ -97,22 +131,26 @@ class bTree:
|
|||
nd = self.root
|
||||
while True:
|
||||
idx = nd.findKey(key)
|
||||
if idx<len(nd) and nd[idx] == key:return
|
||||
if idx < len(nd) and nd[idx] == key:
|
||||
return
|
||||
if nd.isLeafNode():
|
||||
nd.insert(idx, key)
|
||||
self.keyNum += 1
|
||||
return
|
||||
else:
|
||||
chd = nd.getChd(idx)
|
||||
if len(chd)== self.degree*2-1: #ensure its keys won't excess when its chd split and u
|
||||
# ensure its keys won't excess when its chd split and u
|
||||
if len(chd) == self.degree*2-1:
|
||||
nd = chd.split(nd, self.degree)
|
||||
self.nodeNum += 1
|
||||
else:
|
||||
nd = chd
|
||||
|
||||
def delete(self, key): # to do
|
||||
'''search the key, delete it , and form down to up to rebalance it '''
|
||||
nd, idx, fathers = self.search(key, withpath=True)
|
||||
if nd is None : return
|
||||
if nd is None:
|
||||
return
|
||||
del nd[idx]
|
||||
self.keyNum -= 1
|
||||
if not nd.isLeafNode():
|
||||
|
@ -123,7 +161,9 @@ class bTree:
|
|||
fathers.append((chd, len(chd)-1, len(chd)))
|
||||
nd.insert(idx, chd[-1])
|
||||
del chd[-1]
|
||||
if len(fathers)>1:self.rebalance(fathers)
|
||||
if len(fathers) > 1:
|
||||
self.rebalance(fathers)
|
||||
|
||||
def rebalance(self, fathers):
|
||||
nd, keyIdx, chdIdx = fathers.pop()
|
||||
while len(nd) < self.degree-1: # rebalance tree from down to up
|
||||
|
@ -169,6 +209,7 @@ class bTree:
|
|||
self.nodeNum -= 1
|
||||
break
|
||||
nd, i, j = fathers.pop()
|
||||
|
||||
def __str__(self):
|
||||
head = '\n'+'-'*30+'B Tree'+'-'*30
|
||||
tail = '-'*30+'the end'+'-'*30+'\n'
|
||||
|
@ -190,13 +231,16 @@ class bTree:
|
|||
lst.append([tail])
|
||||
lst = [','.join(li) for li in lst]
|
||||
return '\n'.join(lst)
|
||||
|
||||
def __iter__(self, nd=None):
|
||||
if nd is None: nd = self.root
|
||||
if nd is None:
|
||||
nd = self.root
|
||||
que = [nd]
|
||||
while que != []:
|
||||
nd = que.pop(0)
|
||||
yield nd
|
||||
if nd.isLeafNode():continue
|
||||
if nd.isLeafNode():
|
||||
continue
|
||||
for i in range(len(nd)+1):
|
||||
que.append(nd.getChd(i))
|
||||
|
||||
|
|
|
@ -12,42 +12,62 @@
|
|||
|
||||
|
||||
from collections import Iterable
|
||||
|
||||
|
||||
class node:
|
||||
def __init__(self, val, freq=1):
|
||||
self.val = val
|
||||
self.freq = freq
|
||||
|
||||
def __eq__(self, a):
|
||||
return self.val == a.val
|
||||
|
||||
def __lt__(self, a):
|
||||
return self.val < a.val
|
||||
|
||||
def __le__(self, a):
|
||||
return self.val <= a.val
|
||||
|
||||
def __gt__(self, a):
|
||||
return self.val > a.val
|
||||
|
||||
def __ge__(self, a):
|
||||
return self.val >= a.val
|
||||
|
||||
def __ne__(self, a):
|
||||
return not self == a
|
||||
|
||||
|
||||
class binaryHeap:
|
||||
def __init__(self, s=None, sortByFrequency=False, reverse=False):
|
||||
self.sortByFrequency = sortByFrequency
|
||||
self.reverse = reverse
|
||||
self.data = [node(0)] # make index begin with 1
|
||||
if s==None:return
|
||||
if not isinstance(s,Iterable):s = [s]
|
||||
if s == None:
|
||||
return
|
||||
if not isinstance(s, Iterable):
|
||||
s = [s]
|
||||
for i in s:
|
||||
self.insert(i)
|
||||
|
||||
def __bool__(self):
|
||||
return len(self) != 1
|
||||
|
||||
def _cmp(self, a, b):
|
||||
if self.sortByFrequency:
|
||||
if self.reverse:return a.freq>b.freq
|
||||
else:return a.freq<b.freq
|
||||
if self.reverse:
|
||||
return a.freq > b.freq
|
||||
else:
|
||||
if self.reverse:return a>b
|
||||
else:return a<b
|
||||
return a.freq < b.freq
|
||||
else:
|
||||
if self.reverse:
|
||||
return a > b
|
||||
else:
|
||||
return a < b
|
||||
|
||||
def insert(self, k):
|
||||
if not isinstance(k,node): k = node(k)
|
||||
if not isinstance(k, node):
|
||||
k = node(k)
|
||||
for j in range(self.data[0].val):
|
||||
i = self.data[j+1]
|
||||
if i == k:
|
||||
|
@ -59,13 +79,16 @@ class binaryHeap:
|
|||
self.data.append(k)
|
||||
self.data[0].val += 1
|
||||
self.percolateUp()
|
||||
|
||||
def percolateUp(self, n=None):
|
||||
if n ==None:n=self.data[0].val
|
||||
if n == None:
|
||||
n = self.data[0].val
|
||||
tmp = self.data[n]
|
||||
while n != 1 and self._cmp(tmp, self.data[n//2]):
|
||||
self.data[n] = self.data[n//2]
|
||||
n = n//2
|
||||
self.data[n] = tmp
|
||||
|
||||
def deleteTop(self):
|
||||
tmp = self.data[1]
|
||||
i = self.percolateDown(1)
|
||||
|
@ -73,6 +96,7 @@ class binaryHeap:
|
|||
self.data[0].val -= 1
|
||||
del self.data[-1]
|
||||
return tmp
|
||||
|
||||
def percolateDown(self, i):
|
||||
tmp = self.data[i]
|
||||
while self.data[0].val >= 2*i+1:
|
||||
|
@ -84,8 +108,10 @@ class binaryHeap:
|
|||
i = 2*i+1
|
||||
self.data[i] = tmp
|
||||
return i
|
||||
|
||||
def __len__(self):
|
||||
return self.data[0].val
|
||||
|
||||
def Nth(self, n=1):
|
||||
tmp = []
|
||||
for i in range(n):
|
||||
|
@ -93,14 +119,17 @@ class binaryHeap:
|
|||
for i in tmp:
|
||||
self.insert(i)
|
||||
return tmp[-1]
|
||||
|
||||
def display(self):
|
||||
val = self.data[0].val+1
|
||||
if self.sortByFrequency:
|
||||
info = 'heapSort by Frequency:'
|
||||
else:info = 'heapSort by Value:'
|
||||
else:
|
||||
info = 'heapSort by Value:'
|
||||
if self.reverse:
|
||||
info += ' From big to small'
|
||||
else:info +=' From small to big'
|
||||
else:
|
||||
info += ' From small to big'
|
||||
print('*'*15)
|
||||
print(info)
|
||||
print('total items:%d\nval\tfreq' % (val-1))
|
||||
|
@ -108,6 +137,8 @@ class binaryHeap:
|
|||
for i in range(1, val):
|
||||
print(fmt.format(self.data[i].val, self.data[i].freq))
|
||||
print('*'*15)
|
||||
|
||||
|
||||
class Test:
|
||||
def topKFrequent(self, words, k):
|
||||
hp = binaryHeap(sortByFrequency=True, reverse=True)
|
||||
|
@ -131,8 +162,12 @@ class Test:
|
|||
for j in mp[i]:
|
||||
rst.append(j)
|
||||
count += 1
|
||||
if count == k:return rst
|
||||
if count == k:
|
||||
return rst
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
s=["plpaboutit","jnoqzdute","sfvkdqf","mjc","nkpllqzjzp","foqqenbey","ssnanizsav","nkpllqzjzp","sfvkdqf","isnjmy","pnqsz","hhqpvvt","fvvdtpnzx","jkqonvenhx","cyxwlef","hhqpvvt","fvvdtpnzx","plpaboutit","sfvkdqf","mjc","fvvdtpnzx","bwumsj","foqqenbey","isnjmy","nkpllqzjzp","hhqpvvt","foqqenbey","fvvdtpnzx","bwumsj","hhqpvvt","fvvdtpnzx","jkqonvenhx","jnoqzdute","foqqenbey","jnoqzdute","foqqenbey","hhqpvvt","ssnanizsav","mjc","foqqenbey","bwumsj","ssnanizsav","fvvdtpnzx","nkpllqzjzp","jkqonvenhx","hhqpvvt","mjc","isnjmy","bwumsj","pnqsz","hhqpvvt","nkpllqzjzp","jnoqzdute","pnqsz","nkpllqzjzp","jnoqzdute","foqqenbey","nkpllqzjzp","hhqpvvt","fvvdtpnzx","plpaboutit","jnoqzdute","sfvkdqf","fvvdtpnzx","jkqonvenhx","jnoqzdute","nkpllqzjzp","jnoqzdute","fvvdtpnzx","jkqonvenhx","hhqpvvt","isnjmy","jkqonvenhx","ssnanizsav","jnoqzdute","jkqonvenhx","fvvdtpnzx","hhqpvvt","bwumsj","nkpllqzjzp","bwumsj","jkqonvenhx","jnoqzdute","pnqsz","foqqenbey","sfvkdqf","sfvkdqf"]
|
||||
s = ["plpaboutit", "jnoqzdute", "sfvkdqf", "mjc", "nkpllqzjzp", "foqqenbey", "ssnanizsav", "nkpllqzjzp", "sfvkdqf", "isnjmy", "pnqsz", "hhqpvvt", "fvvdtpnzx", "jkqonvenhx", "cyxwlef", "hhqpvvt", "fvvdtpnzx", "plpaboutit", "sfvkdqf", "mjc", "fvvdtpnzx", "bwumsj", "foqqenbey", "isnjmy", "nkpllqzjzp", "hhqpvvt", "foqqenbey", "fvvdtpnzx", "bwumsj", "hhqpvvt", "fvvdtpnzx", "jkqonvenhx", "jnoqzdute", "foqqenbey", "jnoqzdute", "foqqenbey", "hhqpvvt", "ssnanizsav", "mjc", "foqqenbey", "bwumsj", "ssnanizsav", "fvvdtpnzx", "nkpllqzjzp",
|
||||
"jkqonvenhx", "hhqpvvt", "mjc", "isnjmy", "bwumsj", "pnqsz", "hhqpvvt", "nkpllqzjzp", "jnoqzdute", "pnqsz", "nkpllqzjzp", "jnoqzdute", "foqqenbey", "nkpllqzjzp", "hhqpvvt", "fvvdtpnzx", "plpaboutit", "jnoqzdute", "sfvkdqf", "fvvdtpnzx", "jkqonvenhx", "jnoqzdute", "nkpllqzjzp", "jnoqzdute", "fvvdtpnzx", "jkqonvenhx", "hhqpvvt", "isnjmy", "jkqonvenhx", "ssnanizsav", "jnoqzdute", "jkqonvenhx", "fvvdtpnzx", "hhqpvvt", "bwumsj", "nkpllqzjzp", "bwumsj", "jkqonvenhx", "jnoqzdute", "pnqsz", "foqqenbey", "sfvkdqf", "sfvkdqf"]
|
||||
test = Test()
|
||||
print(test.topKFrequent(s, 5))
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
from functools import total_ordering
|
||||
|
||||
|
||||
@total_ordering
|
||||
class node:
|
||||
def __init__(self, val, left=None, right=None, freq=1):
|
||||
|
@ -19,54 +20,78 @@ class node:
|
|||
self.left = left
|
||||
self.right = right
|
||||
self.freq = freq
|
||||
|
||||
def __lt__(self, nd):
|
||||
return self.val < nd.val
|
||||
|
||||
def __eq__(self, nd):
|
||||
return self.val == nd.val
|
||||
|
||||
def __repr__(self):
|
||||
return 'node({})'.format(self.val)
|
||||
|
||||
|
||||
class binaryTree:
|
||||
def __init__(self):
|
||||
self.root = None
|
||||
|
||||
def add(self, val):
|
||||
def _add(nd, newNode):
|
||||
if nd < newNode:
|
||||
if nd.right is None:nd.right = newNode
|
||||
else:_add(nd.right,newNode)
|
||||
if nd.right is None:
|
||||
nd.right = newNode
|
||||
else:
|
||||
_add(nd.right, newNode)
|
||||
elif nd > newNode:
|
||||
if nd.left is None:nd.left = newNode
|
||||
else : _add(nd.left,newNode)
|
||||
else:nd.freq +=1
|
||||
if nd.left is None:
|
||||
nd.left = newNode
|
||||
else:
|
||||
_add(nd.left, newNode)
|
||||
else:
|
||||
nd.freq += 1
|
||||
_add(self.root, node(val))
|
||||
|
||||
def find(self, val):
|
||||
prt = self._findPrt(self.root, node(val), None)
|
||||
if prt.left and prt.left.val == val:
|
||||
return prt.left
|
||||
elif prt.right and prt.right.val==val:return prt.right
|
||||
else :return None
|
||||
elif prt.right and prt.right.val == val:
|
||||
return prt.right
|
||||
else:
|
||||
return None
|
||||
|
||||
def _findPrt(self, nd, tgt, prt):
|
||||
if nd==tgt or nd is None:return prt
|
||||
elif nd<tgt:return self._findPrt(nd.right,tgt,nd)
|
||||
else:return self._findPrt(nd.left,tgt,nd)
|
||||
if nd == tgt or nd is None:
|
||||
return prt
|
||||
elif nd < tgt:
|
||||
return self._findPrt(nd.right, tgt, nd)
|
||||
else:
|
||||
return self._findPrt(nd.left, tgt, nd)
|
||||
|
||||
def delete(self, val):
|
||||
prt = self._findPrt(self.root, node(val), None)
|
||||
if prt.left and prt.left.val == val:
|
||||
l = prt.left
|
||||
if l.left is None:prt.left = l.right
|
||||
elif l.right is None : prt.left = l.left
|
||||
if l.left is None:
|
||||
prt.left = l.right
|
||||
elif l.right is None:
|
||||
prt.left = l.left
|
||||
else:
|
||||
nd = l.left
|
||||
while nd.right is not None:nd = nd.right
|
||||
while nd.right is not None:
|
||||
nd = nd.right
|
||||
nd.right = l.right
|
||||
prt.left = l.left
|
||||
elif prt.right and prt.right.val == val:
|
||||
r = prt.right
|
||||
if r.right is None:prt.right = r.right
|
||||
elif r.right is None : prt.right = r.left
|
||||
if r.right is None:
|
||||
prt.right = r.right
|
||||
elif r.right is None:
|
||||
prt.right = r.left
|
||||
else:
|
||||
nd = r.left
|
||||
while nd.right is not None:nd = nd.right
|
||||
while nd.right is not None:
|
||||
nd = nd.right
|
||||
nd.right = r.right
|
||||
prt.left = r.left
|
||||
|
||||
|
@ -77,6 +102,8 @@ class binaryTree:
|
|||
_p(nd.left)
|
||||
_p(nd.right)
|
||||
_p(self.root)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
t = binaryTree()
|
||||
for i in range(10):
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
# Description:
|
||||
#########################################################################
|
||||
'''
|
||||
|
||||
|
||||
class MyCircularQueue:
|
||||
|
||||
def __init__(self, k):
|
||||
|
@ -31,6 +33,7 @@ class MyCircularQueue:
|
|||
self.data[self.rear] = value
|
||||
self.rear = (self.rear+1) % self.size
|
||||
return True
|
||||
|
||||
def deQueue(self):
|
||||
"""
|
||||
Delete an element from the circular queue. Return true if the operation is successful.
|
||||
|
@ -50,7 +53,6 @@ class MyCircularQueue:
|
|||
return -1
|
||||
return self.data[self.head]
|
||||
|
||||
|
||||
def Rear(self):
|
||||
"""
|
||||
Get the last item from the queue.
|
||||
|
@ -67,7 +69,6 @@ class MyCircularQueue:
|
|||
"""
|
||||
return self.head == self.rear
|
||||
|
||||
|
||||
def isFull(self):
|
||||
"""
|
||||
Checks whether the circular queue is full or not.
|
||||
|
@ -76,7 +77,6 @@ class MyCircularQueue:
|
|||
return (self.head - self.rear) % self.size == 1
|
||||
|
||||
|
||||
|
||||
# Your MyCircularQueue object will be instantiated and called as such:
|
||||
# obj = MyCircularQueue(k)
|
||||
# param_1 = obj.enQueue(value)
|
||||
|
|
|
@ -10,18 +10,23 @@
|
|||
#########################################################################
|
||||
'''
|
||||
|
||||
|
||||
class item:
|
||||
def __init__(self, key, val, nextItem=None):
|
||||
self.key = key
|
||||
self.val = val
|
||||
self.next = nextItem
|
||||
|
||||
def to(self, it):
|
||||
self.next = it
|
||||
|
||||
def __eq__(self, it):
|
||||
'''using keyword <in> '''
|
||||
return self.key == it.key
|
||||
|
||||
def __bool__(self):
|
||||
return self.key is not None
|
||||
|
||||
def __str__(self):
|
||||
li = []
|
||||
nd = self
|
||||
|
@ -29,17 +34,22 @@ class item:
|
|||
li.append(f'({nd.key}:{nd.val})')
|
||||
nd = nd.next
|
||||
return ' -> '.join(li)
|
||||
|
||||
def __repr__(self):
|
||||
return f'item({self.key},{self.val})'
|
||||
|
||||
|
||||
class hashTable:
|
||||
def __init__(self, size=100):
|
||||
self.size = size
|
||||
self.slots = [item(None, None) for i in range(self.size)]
|
||||
|
||||
def __setitem__(self, key, val):
|
||||
nd = self.slots[self.myhash(key)]
|
||||
while nd.next:
|
||||
if nd.key == key:
|
||||
if nd.val!=val: nd.val=val
|
||||
if nd.val != val:
|
||||
nd.val = val
|
||||
return
|
||||
nd = nd.next
|
||||
nd.next = item(key, val)
|
||||
|
@ -50,6 +60,7 @@ class hashTable:
|
|||
if not isinstance(key, int):
|
||||
key = hash(key)
|
||||
return key % self.size
|
||||
|
||||
def __iter__(self):
|
||||
'''when using keyword <in>, such as ' if key in dic',
|
||||
the dic's __iter__ method will be called,(if hasn't, calls __getitem__
|
||||
|
@ -60,13 +71,15 @@ class hashTable:
|
|||
while nd:
|
||||
yield nd.key
|
||||
nd = nd.next
|
||||
|
||||
def __getitem__(self, key):
|
||||
nd = self.slots[self.myhash(key)].next
|
||||
while nd:
|
||||
if nd.key == key:
|
||||
return nd.val
|
||||
nd = nd.next
|
||||
raise Exception(f'[KeyError]: {self.__class__.__name__} has no key {key}')
|
||||
raise Exception(
|
||||
f'[KeyError]: {self.__class__.__name__} has no key {key}')
|
||||
|
||||
def __delitem__(self, key):
|
||||
'''note that None item and item(None,None) differ with each other,
|
||||
|
@ -78,13 +91,16 @@ class hashTable:
|
|||
if nd.key == key:
|
||||
if nd.next is None:
|
||||
self.slots[n] = item(None, None) # be careful
|
||||
else:self.slots[n] = nd.next
|
||||
else:
|
||||
self.slots[n] = nd.next
|
||||
return
|
||||
while nd:
|
||||
if nd.next is None: break # necessary
|
||||
if nd.next is None:
|
||||
break # necessary
|
||||
if nd.next.key == key:
|
||||
nd.next = nd.next.next
|
||||
nd = nd.next
|
||||
|
||||
def __str__(self):
|
||||
li = ['\n\n'+'-'*5+'hashTable'+'-'*5]
|
||||
for i, nd in enumerate(self.slots):
|
||||
|
|
|
@ -30,36 +30,47 @@ void cat(string s)
|
|||
{
|
||||
FILE* f = fopen(s.c_str(), "rb");
|
||||
cout << "file content" << endl;
|
||||
|
||||
while (!feof(f)) {
|
||||
cout << fgetc(f);
|
||||
}
|
||||
|
||||
cout << endl;
|
||||
}
|
||||
string uniFileName(string file)
|
||||
{
|
||||
FILE * check = fopen(file.c_str(), "rb");
|
||||
|
||||
if (check) {
|
||||
char c;
|
||||
cout << "the file " << file << " already exists! continue? [Y/n]:" << flush;
|
||||
c = cin.get();
|
||||
|
||||
if (c == 'n')exit(0);
|
||||
|
||||
int p, q;
|
||||
p = file.find('(');
|
||||
q = file.rfind('.');
|
||||
|
||||
if (q == string::npos)q = file.size();
|
||||
|
||||
if (p == string::npos)p = q;
|
||||
|
||||
string name = file.substr(0, p), suffix = file.substr(q, file.size());
|
||||
int n = 0;
|
||||
|
||||
while (true) {
|
||||
char s[3];
|
||||
n += 1;
|
||||
snprintf(s, 3, "%d", n);
|
||||
file = (name + "(" + s + ")" + suffix);
|
||||
FILE* f = fopen(file.c_str(), "rb");
|
||||
|
||||
if (!f)break;
|
||||
else fclose(f);
|
||||
}
|
||||
}
|
||||
|
||||
return file;
|
||||
}
|
||||
template<class t1, class t2>
|
||||
|
@ -76,9 +87,19 @@ class node
|
|||
wt val;
|
||||
bool visited;
|
||||
node * left, *right;
|
||||
node(const node &a){val = a.val;key= a.key;visited = a.visited;left= a.left;right=a.right;}
|
||||
node(const node &a)
|
||||
{
|
||||
val = a.val;
|
||||
key = a.key;
|
||||
visited = a.visited;
|
||||
left = a.left;
|
||||
right = a.right;
|
||||
}
|
||||
node(ky k = 0, wt v = 0): key(k), val(v), visited(false), left(NULL), right(NULL) {};
|
||||
bool operator<(const node<ky,wt> & a)const{return val>a.val;};
|
||||
bool operator<(const node<ky, wt> & a)const
|
||||
{
|
||||
return val > a.val;
|
||||
};
|
||||
};
|
||||
template<typename ky, typename wt>
|
||||
class huffman
|
||||
|
@ -87,7 +108,10 @@ private:
|
|||
node<ky, wt> root;
|
||||
string res;
|
||||
public:
|
||||
long total(){return root.val;}
|
||||
long total()
|
||||
{
|
||||
return root.val;
|
||||
}
|
||||
map<ky, string> encode_map;
|
||||
map<string, ky> decode_map;
|
||||
huffman(map<ky, wt>& mp);
|
||||
|
@ -104,15 +128,20 @@ huffman<ky,wt>::huffman(map<ky,wt>& mp)
|
|||
root = NULL;
|
||||
return ;
|
||||
}
|
||||
|
||||
priority_queue<node<ky, wt> > hp;
|
||||
|
||||
for (typename map<ky, wt>::iterator i = mp.begin(); i != mp.end(); ++i) {
|
||||
hp.push(node<ky, wt>(i->first, i->second));
|
||||
}
|
||||
|
||||
int n = hp.size();
|
||||
|
||||
if (n == 1) {
|
||||
root = hp.top();
|
||||
return;
|
||||
}
|
||||
|
||||
while (--n >= 1) {
|
||||
node<ky, wt> *a = new node<ky, wt>(hp.top());
|
||||
hp.pop();
|
||||
|
@ -122,6 +151,7 @@ huffman<ky,wt>::huffman(map<ky,wt>& mp)
|
|||
tmp->left = a, tmp->right = b;
|
||||
hp.push(*tmp);
|
||||
}
|
||||
|
||||
root = hp.top();
|
||||
preOrder(&root, string());
|
||||
}
|
||||
|
@ -134,6 +164,7 @@ void huffman<ky,wt>::preOrder(node<ky, wt>* nd,string s)
|
|||
delete nd;
|
||||
return ;
|
||||
}
|
||||
|
||||
preOrder(nd->left, s + '0');
|
||||
preOrder(nd->right, s + '1');
|
||||
delete nd;
|
||||
|
@ -146,9 +177,13 @@ string huffman<ky,wt>::decode(string zipfile_name,long &charNum)
|
|||
char file_name[nameLength];
|
||||
fgets(file_name, nameLength, src);
|
||||
int ct = -1;
|
||||
|
||||
while (file_name[++ct] != '\n');
|
||||
|
||||
int pos = zipfile_name.find('.');
|
||||
|
||||
if (pos == string::npos)pos = zipfile_name.size();
|
||||
|
||||
string name(zipfile_name.substr(0, pos)), suffix(file_name, file_name + ct), file(name + suffix);
|
||||
file = uniFileName(file);
|
||||
cout << "extracting compressed file :" << zipfile_name << endl;
|
||||
|
@ -159,36 +194,46 @@ string huffman<ky,wt>::decode(string zipfile_name,long &charNum)
|
|||
char code[sz];
|
||||
fread(code, sz, 1, src);
|
||||
int idx = 0;
|
||||
|
||||
for (int i = 0; i < sz; ++i) {
|
||||
if (code[i] == ' ') {
|
||||
decode_map[string(code + idx, code + i)] = code[++i];
|
||||
idx = i + 1;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < starNum; ++i)cout << "@";
|
||||
|
||||
cout << endl;
|
||||
char c;
|
||||
long cur = charNum, gap = charNum / starNum;
|
||||
|
||||
while (cur) {
|
||||
c = fgetc(src);
|
||||
|
||||
if (!((--cur) % gap))cout << "@" << flush;
|
||||
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
if (c & (1 << i))res.append(1, '1');
|
||||
else res.append(1, '0');
|
||||
|
||||
if (decode_map.count(res) != 0) {
|
||||
fputc(decode_map[res], f);
|
||||
res.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cout << endl;
|
||||
c = fgetc(src);
|
||||
int dgt = fgetc(src);
|
||||
cout << feof(f);
|
||||
|
||||
if ((int)dgt != -1) {
|
||||
for (int i = 0; i < dgt; ++i) {
|
||||
if (c & (1 << i))res.append(1, '1');
|
||||
else res.append(1, '0');
|
||||
|
||||
if (decode_map.count(res) != 0) {
|
||||
fputc(decode_map[res], f);
|
||||
res.clear();
|
||||
|
@ -196,6 +241,7 @@ string huffman<ky,wt>::decode(string zipfile_name,long &charNum)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose(src);
|
||||
fclose(f);
|
||||
cout << "get " << file << " successfully" << endl;
|
||||
|
@ -207,7 +253,9 @@ string huffman<ky,wt>::encode(string file_name,long &charNum)
|
|||
charNum = 0;
|
||||
string uniFileName(string);
|
||||
int pos = file_name.rfind('.');
|
||||
|
||||
if (pos == string::npos)pos = file_name.size();
|
||||
|
||||
string zipfile = file_name.substr(0, pos) + string(".zzip");
|
||||
zipfile = uniFileName(zipfile);
|
||||
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);
|
||||
fputc('\n', dst);
|
||||
string data;
|
||||
|
||||
for (class map<string, ky>::iterator i = decode_map.begin(); i != decode_map.end() ; ++i) {
|
||||
data.append((i->first));
|
||||
data.append(" ");
|
||||
data += (i->second);
|
||||
}
|
||||
|
||||
int data_size = data.size(); // calculate the size of the code_data
|
||||
char sz[numDigit];
|
||||
snprintf(sz, numDigit, "%d", data_size);
|
||||
int ct = 0;
|
||||
|
||||
for (; sz[ct]; ++ct)fputc(sz[ct], dst);
|
||||
|
||||
fputc('\n', dst);
|
||||
fwrite(data.c_str(), data_size, 1, dst);
|
||||
int sum = 0, digit = 0, num;
|
||||
string code8;
|
||||
|
||||
for (int i = 0; i < starNum; ++i)cout << "@";
|
||||
|
||||
cout << endl;
|
||||
long gap = root.val / starNum, cur = 0;
|
||||
|
||||
while (!feof(f)) {
|
||||
code8 = encode_map[fgetc(f)];
|
||||
|
||||
if (!((++cur) % gap))cout << "@";
|
||||
|
||||
for (int i = 0; i < code8.size(); ++i) {
|
||||
if (code8[i] == '1')sum += 1 << (digit); //mistake if(tmp[j])
|
||||
|
||||
++digit;
|
||||
|
||||
if (digit == 8) {
|
||||
++charNum;
|
||||
fputc(sum, dst);
|
||||
|
@ -246,11 +305,14 @@ string huffman<ky,wt>::encode(string file_name,long &charNum)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
cout << endl;
|
||||
|
||||
if (digit != 0) { //mark
|
||||
fputc(sum, dst);
|
||||
fputc(digit, dst);
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
fclose(dst);
|
||||
cout << "compress " << file_name << " successfully" << endl;
|
||||
|
@ -260,6 +322,7 @@ template<typename ky,typename wt>
|
|||
void huffman<ky, wt>::display()
|
||||
{
|
||||
cout << "the encoding map,huffman codes are as bellow:" << endl;
|
||||
|
||||
for (typename map<ky, string>::iterator i = encode_map.begin(); i != encode_map.end() ; ++i)
|
||||
cout << i->first << "(" << (int)i->first << "):" << i->second << endl;
|
||||
}
|
||||
|
@ -268,21 +331,25 @@ bool handle_one(string file_name,vector<long> &origin,vector<long> &compressed)
|
|||
int name_length = file_name.size();
|
||||
FILE *src = fopen(file_name.c_str(), "rb");
|
||||
cout << "opening " << file_name << "..." << endl;
|
||||
|
||||
if (!src) {
|
||||
cout << "Path Error! Opening " << file_name << " Failed" << endl;
|
||||
origin.push_back(0);
|
||||
compressed.push_back(0);
|
||||
return false;
|
||||
}
|
||||
|
||||
char cur;
|
||||
map<char, long> mp;
|
||||
|
||||
while (!feof(src)) {
|
||||
fread(&cur, sizeof(char), 1, src);
|
||||
|
||||
if (mp.count(cur)) {
|
||||
mp[cur] += 1;
|
||||
} else mp[cur] = 1;
|
||||
}
|
||||
else mp[cur]=1;
|
||||
}
|
||||
|
||||
fclose(src);
|
||||
huffman<char, long> hf(mp);
|
||||
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);
|
||||
cout << "\ncontinue to uncompress? [Y/n]" << endl;
|
||||
char c = cin.get();
|
||||
|
||||
if (c == 'n')return true;
|
||||
|
||||
hf.decode(s, sz);
|
||||
return true;
|
||||
}
|
||||
|
@ -301,13 +370,17 @@ bool isSep(char c)
|
|||
void splitToVec(char * s, vector<string>& v)
|
||||
{
|
||||
int i = 0, last = 0;
|
||||
|
||||
for (; s[i]; ++i) {
|
||||
if (isSep(s[i])) {
|
||||
v.push_back(string(s + last, s + i));
|
||||
|
||||
while (s[++i] && isSep(s[i]));
|
||||
|
||||
last = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (s[last])v.push_back(string(s + last, s + i));
|
||||
}
|
||||
bool lenStr(string &a, string &b)
|
||||
|
@ -321,6 +394,7 @@ void go(vector<string> & names)
|
|||
double last;
|
||||
vector<bool> indicator;
|
||||
bool bl;
|
||||
|
||||
for (vector<string>::iterator i = names.begin(); i != names.end(); ++i) {
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
|
@ -330,15 +404,21 @@ void go(vector<string> & names)
|
|||
gettimeofday(&tv, NULL);
|
||||
deltaTime.push_back(tv.tv_sec - last);
|
||||
}
|
||||
|
||||
cout << "\nDealt file number " << originSize.size() << fixed << setprecision(2) << endl;
|
||||
vector<string>::iterator p = max_element(names.begin(), names.end(), lenStr);
|
||||
int len = p->size() + 2;
|
||||
|
||||
for (int i = 0; i < names.size(); ++i) {
|
||||
if(! indicator[i]){continue;}
|
||||
if (! indicator[i]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
cout << names[i] << string(len - names[i].size(), ' ');
|
||||
cout << deltaTime[i] << "s " << compressedSize[i] / 1024.0 << "KB/" << originSize[i] / 1024.0 << "KB :";
|
||||
cout << compressedSize[i] * 100.0 / originSize[i] << "%" << endl;
|
||||
}
|
||||
|
||||
cout << endl;
|
||||
system("pause");
|
||||
}
|
||||
|
@ -348,28 +428,37 @@ int main(int argv,char ** argc)
|
|||
cout << getcwd(cwd, 50) << endl;
|
||||
vector<string> names;
|
||||
string file;
|
||||
|
||||
if (argv > 1) {
|
||||
for (int i = 1; i < argv; ++i) {
|
||||
names.push_back(argc[i]);
|
||||
}
|
||||
|
||||
go(names);
|
||||
names.clear();
|
||||
}
|
||||
|
||||
char mk;
|
||||
|
||||
while (1) {
|
||||
char s[201];
|
||||
cout << "Input file names separated by space " << endl;
|
||||
|
||||
if (cin.peek() == '\n')names.push_back(file);
|
||||
else {
|
||||
cin.getline(s, 200);
|
||||
splitToVec(s, names);
|
||||
}
|
||||
|
||||
cout << endl;
|
||||
go(names);
|
||||
cout << "Continue? [Y/n]:" << flush;
|
||||
mk = cin.get();
|
||||
|
||||
if (mk == 'n')break;
|
||||
|
||||
names.clear();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#######################################################################
|
||||
'''
|
||||
|
||||
|
||||
class RandomizedCollection:
|
||||
def __init__(self):
|
||||
|
||||
|
@ -27,6 +28,7 @@ class RandomizedCollection:
|
|||
else:
|
||||
self.index[val] = {len(self.vals)-1}
|
||||
return True
|
||||
|
||||
def removeAll(self, val: int) -> bool:
|
||||
if val not in self.index:
|
||||
return False
|
||||
|
@ -40,6 +42,7 @@ class RandomizedCollection:
|
|||
self.index[self.vals[idx]].add(idx)
|
||||
self.vals = self.vals[:begin]
|
||||
return True
|
||||
|
||||
def remove(self, val):
|
||||
if val not in self.index:
|
||||
return False
|
||||
|
@ -53,6 +56,7 @@ class RandomizedCollection:
|
|||
self.index[self.vals[idx]].add(idx)
|
||||
self.vals.pop()
|
||||
return True
|
||||
|
||||
def getRandom(self) -> int:
|
||||
if self.vals:
|
||||
return self.vals[random.randint(0, len(self.vals)-1)]
|
||||
|
|
|
@ -9,10 +9,12 @@
|
|||
# Description:
|
||||
#########################################################################
|
||||
'''
|
||||
from random import randint, shuffle
|
||||
from redBlackTree import redBlackTree
|
||||
|
||||
from functools import total_ordering
|
||||
|
||||
|
||||
@total_ordering
|
||||
class node:
|
||||
def __init__(self, low, high, left=None, right=None, isBlack=False):
|
||||
|
@ -23,45 +25,63 @@ class node:
|
|||
self.right = right
|
||||
self.parent = None
|
||||
self.isBlack = isBlack
|
||||
|
||||
def __lt__(self, nd):
|
||||
return self.val < nd.val
|
||||
|
||||
def __eq__(self, nd):
|
||||
return nd is not None and self.val == nd.val
|
||||
|
||||
def setChild(self, nd, isLeft=True):
|
||||
if isLeft: self.left = nd
|
||||
else: self.right = nd
|
||||
if nd is not None: nd.parent = self
|
||||
if isLeft:
|
||||
self.left = nd
|
||||
else:
|
||||
self.right = nd
|
||||
if nd is not None:
|
||||
nd.parent = self
|
||||
|
||||
def getChild(self, isLeft):
|
||||
if isLeft: return self.left
|
||||
else: return self.right
|
||||
if isLeft:
|
||||
return self.left
|
||||
else:
|
||||
return self.right
|
||||
|
||||
def __bool__(self):
|
||||
return self.val is not None
|
||||
|
||||
def __str__(self):
|
||||
color = 'B' if self.isBlack else 'R'
|
||||
return f'{color}[{self.val},{self.high}]-{self.max}'
|
||||
|
||||
def __repr__(self):
|
||||
return f'intervalNode({self.val},{self.high},{self.max},isBlack={self.isBlack})'
|
||||
|
||||
def overlap(self, low, high):
|
||||
return self.val <= high and self.high >= low
|
||||
|
||||
def setMax(self):
|
||||
l = 0 if self.left is None else self.left.max
|
||||
r = 0 if self.right is None else self.right.max
|
||||
self.max = max(self.high, l, r)
|
||||
return self.max
|
||||
|
||||
|
||||
class intervalTree(redBlackTree):
|
||||
def search(self, low, high):
|
||||
nd = self.root
|
||||
while nd is not None and not nd.overlap(low, high):
|
||||
if nd.left is not None and nd.left.max >= low:
|
||||
nd = nd.left
|
||||
else:nd = nd.right
|
||||
else:
|
||||
nd = nd.right
|
||||
return nd
|
||||
|
||||
def insert(self, nd):
|
||||
super(intervalTree, self).insert(nd)
|
||||
while nd is not None:
|
||||
nd.setMax()
|
||||
nd = nd.parent
|
||||
|
||||
def delete(self, val):
|
||||
nd = self.find(val)
|
||||
if nd is not None:
|
||||
|
@ -71,19 +91,19 @@ class intervalTree(redBlackTree):
|
|||
tmp.setMax()
|
||||
tmp = tmp.parent
|
||||
super(intervalTree, self).delete(val)
|
||||
|
||||
def rotate(self, prt, chd):
|
||||
'''rotate prt, and return new prt, namyly the original chd'''
|
||||
super(intervalTree, self).rotate(prt, chd)
|
||||
prt.setMax()
|
||||
chd.setMax()
|
||||
|
||||
def copyNode(self, src, des):
|
||||
des.val = src.val
|
||||
des.high = src.high
|
||||
des.setMax()
|
||||
|
||||
|
||||
|
||||
from random import randint, shuffle
|
||||
def genNum(n=10, upper=10):
|
||||
nums = {}
|
||||
for i in range(n):
|
||||
|
@ -94,6 +114,7 @@ def genNum(n =10,upper=10):
|
|||
break
|
||||
return nums.values()
|
||||
|
||||
|
||||
def buildTree(n=10, nums=None, visitor=None):
|
||||
#if nums is None or nums ==[]: nums = genNum(n)
|
||||
tree = intervalTree()
|
||||
|
@ -103,6 +124,8 @@ def buildTree(n=10,nums=None,visitor=None):
|
|||
if visitor:
|
||||
visitor(tree, i)
|
||||
return tree, nums
|
||||
|
||||
|
||||
def testInsert(nums=None):
|
||||
def visitor(t, val):
|
||||
print('inserting', val)
|
||||
|
@ -113,11 +136,13 @@ def testInsert(nums=None):
|
|||
print(f'{i+1}: {j}')
|
||||
return tree
|
||||
|
||||
|
||||
def testSuc(nums=None):
|
||||
tree, nums = buildTree(nums=nums)
|
||||
for i in tree.sort():
|
||||
print(f'{i}\'s suc is {tree.getSuccessor(i)}')
|
||||
|
||||
|
||||
def testDelete(nums=None):
|
||||
tree, nums = buildTree(nums=nums)
|
||||
print(tree)
|
||||
|
@ -127,8 +152,10 @@ def testDelete(nums=None):
|
|||
print(tree)
|
||||
return tree
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
lst = [(0,3),(5,8),(6,10),(26,26),(25,30),(8,9),(19,20),(15,23),(16,21),(17,19)]
|
||||
lst = [(0, 3), (5, 8), (6, 10), (26, 26), (25, 30),
|
||||
(8, 9), (19, 20), (15, 23), (16, 21), (17, 19)]
|
||||
#lst = None
|
||||
# testSuc(lst)
|
||||
tree = testInsert(lst)
|
||||
|
|
|
@ -11,8 +11,9 @@
|
|||
'''
|
||||
|
||||
from functools import total_ordering
|
||||
@total_ordering
|
||||
|
||||
|
||||
@total_ordering
|
||||
class node:
|
||||
def __init__(self, val, freq=1, s=1, left=None, right=None):
|
||||
self.val = val
|
||||
|
@ -27,22 +28,30 @@ class node:
|
|||
self.left = left
|
||||
self.right = right
|
||||
self.s += self.right.s
|
||||
|
||||
def __eq__(self, nd):
|
||||
return self.val == nd.val
|
||||
|
||||
def __lt__(self, nd):
|
||||
return self.val < nd.val
|
||||
|
||||
def __repr__(self):
|
||||
return 'node(val=%d,freq=%d,s=%d)' % (self.val, self.freq, self.s)
|
||||
|
||||
|
||||
class leftHeap:
|
||||
def __init__(self, root=None):
|
||||
self.root = root
|
||||
|
||||
def __bool__(self):
|
||||
return self.root is not None
|
||||
|
||||
@staticmethod
|
||||
def _merge(root, t): # -> int
|
||||
if root is None:return t
|
||||
if t is None:return root
|
||||
if root is None:
|
||||
return t
|
||||
if t is None:
|
||||
return root
|
||||
if root < t:
|
||||
root, t = t, root
|
||||
root.right = leftHeap._merge(root.right, t)
|
||||
|
@ -55,8 +64,10 @@ class leftHeap:
|
|||
root.left, root.right = root.right, root.left
|
||||
root.s = root.right.s+1
|
||||
return root
|
||||
|
||||
def insert(self, nd):
|
||||
if not isinstance(nd,node):nd = node(nd)
|
||||
if not isinstance(nd, node):
|
||||
nd = node(nd)
|
||||
if self.root is None:
|
||||
self.root = nd
|
||||
return
|
||||
|
@ -69,9 +80,12 @@ class leftHeap:
|
|||
else:
|
||||
if prt.left == nd:
|
||||
prt.left.freq += 1
|
||||
else:prt.right.freq+=1
|
||||
else:
|
||||
prt.right.freq += 1
|
||||
|
||||
def remove(self, nd):
|
||||
if not isinstance(nd,node):nd = node(nd)
|
||||
if not isinstance(nd, node):
|
||||
nd = node(nd)
|
||||
if self.root == nd:
|
||||
self.root = leftHeap._merge(self.root.left, self.root.right)
|
||||
else:
|
||||
|
@ -80,25 +94,38 @@ class leftHeap:
|
|||
if prt.left == nd:
|
||||
prt.left = leftHeap._merge(prt.left.left, prt.left.right)
|
||||
else:
|
||||
prt.right=leftHeap._merge(prt.right.left,prt.right.right)
|
||||
prt.right = leftHeap._merge(
|
||||
prt.right.left, prt.right.right)
|
||||
|
||||
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)
|
||||
if prt is None or prt==nd:return prt
|
||||
elif prt.left==nd:return prt.left
|
||||
else:return prt.right
|
||||
if prt is None or prt == nd:
|
||||
return prt
|
||||
elif prt.left == nd:
|
||||
return prt.left
|
||||
else:
|
||||
return prt.right
|
||||
|
||||
def _findPrt(self, root, nd, parent):
|
||||
if not isinstance(nd,node):nd = node(nd)
|
||||
if root is None or root<nd:return None
|
||||
if root==nd:return parent
|
||||
if not isinstance(nd, node):
|
||||
nd = node(nd)
|
||||
if root is None or root < nd:
|
||||
return None
|
||||
if root == nd:
|
||||
return parent
|
||||
l = self._findPrt(root.left, nd, root)
|
||||
return l if l is not None else self._findPrt(root.right, nd, root)
|
||||
|
||||
def getTop(self):
|
||||
return self.root
|
||||
|
||||
def pop(self):
|
||||
nd = self.root
|
||||
self.remove(self.root.val)
|
||||
return nd
|
||||
|
||||
def levelTraverse(self):
|
||||
li = [(self.root, 0)]
|
||||
cur = 0
|
||||
|
@ -108,10 +135,12 @@ class leftHeap:
|
|||
cur = lv
|
||||
print()
|
||||
print(nd, end=' ')
|
||||
else:print(nd,end=' ')
|
||||
if nd.left is not None:li.append((nd.left,lv+1))
|
||||
if nd.right is not None:li.append((nd.right,lv+1))
|
||||
|
||||
else:
|
||||
print(nd, end=' ')
|
||||
if nd.left is not None:
|
||||
li.append((nd.left, lv+1))
|
||||
if nd.right is not None:
|
||||
li.append((nd.right, lv+1))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
@ -123,7 +152,8 @@ if __name__ == '__main__':
|
|||
print()
|
||||
for i in data:
|
||||
print(lh.getTop())
|
||||
if lh.find(i) is not None:lh.remove(i)
|
||||
if lh.find(i) is not None:
|
||||
lh.remove(i)
|
||||
'''
|
||||
data = [(i-10)**2 for i in range(20)]
|
||||
node(100,freq=1,s=3)
|
||||
|
|
|
@ -9,10 +9,14 @@
|
|||
# Description:
|
||||
#########################################################################
|
||||
'''
|
||||
|
||||
|
||||
class node:
|
||||
def __init__(self, val, follow=None):
|
||||
self.val = val
|
||||
self.follow = follow
|
||||
|
||||
|
||||
class MyLinkedList:
|
||||
|
||||
def __init__(self):
|
||||
|
@ -31,7 +35,8 @@ class MyLinkedList:
|
|||
nd = self.head
|
||||
for i in range(index+1):
|
||||
nd = nd.follow
|
||||
if nd is None:return -1
|
||||
if nd is None:
|
||||
return -1
|
||||
return nd.val
|
||||
|
||||
def addAtHead(self, val):
|
||||
|
@ -42,7 +47,9 @@ class MyLinkedList:
|
|||
"""
|
||||
nd = node(val, self.head.follow)
|
||||
self.head .follow = nd
|
||||
if self.tail.val is None:self.tail = nd
|
||||
if self.tail.val is None:
|
||||
self.tail = nd
|
||||
|
||||
def addAtTail(self, val):
|
||||
"""
|
||||
Append a node of value val to the last element of the linked list.
|
||||
|
@ -52,7 +59,6 @@ class MyLinkedList:
|
|||
self.tail.follow = node(val)
|
||||
self.tail = self.tail.follow
|
||||
|
||||
|
||||
def addAtIndex(self, index, val):
|
||||
"""
|
||||
Add a node of value val before the index-th node in the linked list. If index equals to the length of linked list, the node will be appended to the end of linked list. If index is greater than the length, the node will not be inserted.
|
||||
|
@ -70,7 +76,6 @@ class MyLinkedList:
|
|||
if self.tail == nd:
|
||||
self.tail = new
|
||||
|
||||
|
||||
def deleteAtIndex(self, index):
|
||||
"""
|
||||
Delete the index-th node in the linked list, if the index is valid.
|
||||
|
@ -80,10 +85,12 @@ class MyLinkedList:
|
|||
nd = self.head
|
||||
for i in range(index):
|
||||
nd = nd.follow
|
||||
if nd is None:return
|
||||
if self.tail == nd.follow:self.tail = nd
|
||||
if nd.follow:nd.follow = nd.follow.follow
|
||||
|
||||
if nd is None:
|
||||
return
|
||||
if self.tail == nd.follow:
|
||||
self.tail = nd
|
||||
if nd.follow:
|
||||
nd.follow = nd.follow.follow
|
||||
|
||||
|
||||
# Your MyLinkedList object will be instantiated and called as such:
|
||||
|
|
|
@ -44,7 +44,8 @@ class map
|
|||
int size();
|
||||
};
|
||||
template<class t1, class t2>
|
||||
map<t1,t2>::map(){
|
||||
map<t1, t2>::map()
|
||||
{
|
||||
n = 0;
|
||||
cur = -1;
|
||||
last_visit = &head;
|
||||
|
@ -55,6 +56,7 @@ template<class t1,class t2>
|
|||
map<t1, t2>::~map()
|
||||
{
|
||||
pair<t1, t2> *p, *q = &head;
|
||||
|
||||
while (q != NULL) {
|
||||
p = q->next;
|
||||
delete q;
|
||||
|
@ -65,10 +67,13 @@ template<class t1,class t2>
|
|||
bool map<t1, t2>::has(t1 key)
|
||||
{
|
||||
pair<t1, t2> *p = head.next;
|
||||
|
||||
for (int i = 0; i < n && p->first <= key; ++i) {
|
||||
if (isZero(p->first - key)) return 1;
|
||||
|
||||
p = p->next;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
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");
|
||||
return head;
|
||||
}
|
||||
|
||||
if (cur > index) {
|
||||
last_visit = &head;
|
||||
cur = -1;
|
||||
}
|
||||
|
||||
while (cur < index) {
|
||||
last_visit = last_visit->next;
|
||||
++cur;
|
||||
}
|
||||
|
||||
return *last_visit;
|
||||
}
|
||||
template<class t1, class t2>
|
||||
|
@ -97,11 +105,16 @@ template<class t1,class t2>
|
|||
t2& map<t1, t2>::operator[](t1 key)
|
||||
{
|
||||
pair<t1, t2> * p = &head;
|
||||
|
||||
while (p->next != NULL) {
|
||||
if (isZero(p->next->first - key)) return p->next->second;
|
||||
else if(p->next->first>key){break;}
|
||||
else if (p->next->first > key) {
|
||||
break;
|
||||
}
|
||||
|
||||
p = p->next;
|
||||
}
|
||||
|
||||
cur = -1;
|
||||
last_visit = &head;
|
||||
pair<t1, t2> *tmp = new pair<t1, t2>;
|
||||
|
@ -115,6 +128,7 @@ template<class t1,class t2>
|
|||
void map<t1, t2>::erase(t1 key)
|
||||
{
|
||||
pair<t1, t2> *p = &head;
|
||||
|
||||
while (p->next != NULL) {
|
||||
if (isZero(p->next->first - key)) {
|
||||
pair<t1, t2> *q = p->next;
|
||||
|
@ -123,8 +137,10 @@ void map<t1,t2>::erase(t1 key)
|
|||
--n;
|
||||
break;
|
||||
}
|
||||
|
||||
p = p->next;
|
||||
}
|
||||
|
||||
cur = -1;
|
||||
last_visit = &head;
|
||||
}
|
||||
|
@ -133,18 +149,22 @@ void map<t1,t2>::erase(t1 key)
|
|||
int main()
|
||||
{
|
||||
map<double, float> b;
|
||||
|
||||
for (int i = 0; i < 40; ++i) {
|
||||
b[i] = i;
|
||||
|
||||
if (i % 3) {
|
||||
b[i] = 1;
|
||||
}
|
||||
|
||||
if (i % 2) {
|
||||
b.erase(i);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for (int i = 0; i < b.size(); ++i) {
|
||||
printf("item %d %g:%g\n", i, b.locate(i).first, b.locate(i).second);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ bool isZero(double a)
|
|||
{
|
||||
if ((a < 0.00001) && -a < 0.00001)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
class node
|
||||
|
@ -66,9 +67,11 @@ polynomial::~polynomial()
|
|||
double polynomial::cal(double x)
|
||||
{
|
||||
double rst = 0;
|
||||
|
||||
for (int i = 0; i < n; ++i) {
|
||||
rst += pow(x, p[i].index) * p[i].coefficient;
|
||||
}
|
||||
|
||||
return rst;
|
||||
}
|
||||
polynomial::polynomial(const polynomial &a)
|
||||
|
@ -76,6 +79,7 @@ polynomial::polynomial(const polynomial &a)
|
|||
p = (node*) new node[50];
|
||||
memset(p, 0, sizeof(p));
|
||||
n = a.n;
|
||||
|
||||
for (int i = 0; i < a.n; ++i) {
|
||||
p[i].index = a.p[i].index;
|
||||
p[i].coefficient = a.p[i].coefficient;
|
||||
|
@ -84,33 +88,42 @@ polynomial::polynomial(const polynomial &a)
|
|||
polynomial polynomial::operator=(const polynomial& a)
|
||||
{
|
||||
n = a.n;
|
||||
|
||||
for (int i = 0; i < a.n; ++i) {
|
||||
p[i].index = a.p[i].index;
|
||||
p[i].coefficient = a.p[i].coefficient;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
void polynomial::display()
|
||||
{
|
||||
node * tmp = p;
|
||||
|
||||
if (n == 0) {
|
||||
printf("0\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// char *fmt = ("x"); printf(fmt,...);
|
||||
for (int i = n - 1; i >= 0; --i) {
|
||||
double t = tmp[i].coefficient;
|
||||
double idx = tmp[i].index;
|
||||
|
||||
if (isZero(idx)) {
|
||||
printf("%+g", t);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isZero(t - 1)) printf("+");
|
||||
else if (isZero(t + 1))printf("-");
|
||||
else printf("%+g", t);
|
||||
|
||||
printf("x");
|
||||
|
||||
if (!isZero(idx - 1)) printf("^%g", idx);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
void polynomial::getData()
|
||||
|
@ -120,22 +133,26 @@ void polynomial::getData()
|
|||
map<double, double> mp;
|
||||
double idx;
|
||||
double coef;
|
||||
|
||||
while (scanf("%lf%lf", &coef, &idx) != EOF) {
|
||||
if (isZero(coef)) continue;
|
||||
|
||||
if (mp.count(idx) == 0) {
|
||||
mp[idx] = coef;
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
mp[idx] += coef;
|
||||
|
||||
if (isZero(mp[idx])) {
|
||||
mp.erase(idx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mp.size() > SIZE) {
|
||||
SIZE *= 2;
|
||||
p = (node*)realloc(p, sizeof(node) * SIZE) ;
|
||||
}
|
||||
|
||||
for (map<double, double>::iterator it = mp.begin(); it != mp.end(); ++it) {
|
||||
p[n].index = it->first;
|
||||
p[n++].coefficient = it->second;
|
||||
|
@ -147,6 +164,7 @@ polynomial polynomial::operator+(const polynomial & a)
|
|||
int p1 = 0, p2 = 0, p3 = 0;
|
||||
double exp1 = p[p1].index;
|
||||
double exp2 = a.p[p2].index;
|
||||
|
||||
while (p1 < n && p2 < a.n) {
|
||||
while (p1 < n && exp1 < exp2) {
|
||||
rst.p[p3].index = exp1;
|
||||
|
@ -154,38 +172,41 @@ polynomial polynomial::operator+(const polynomial & a)
|
|||
++p1, ++p3;
|
||||
exp1 = p[p1].index;;
|
||||
}
|
||||
|
||||
while (p2 < a.n && exp1 > exp2) {
|
||||
rst.p[p3].index = exp2;
|
||||
rst.p[p3].coefficient = a.p[p2].coefficient;
|
||||
++p2, ++p3;
|
||||
exp2 = a.p[p2].index;;
|
||||
}
|
||||
|
||||
if (isZero(exp1 - exp2)) {
|
||||
double tmp = p[p1].coefficient + a.p[p2].coefficient;
|
||||
|
||||
if (isZero(tmp)) {
|
||||
++p1, ++p2;
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
rst.p[p3].index = p[p1].index;
|
||||
rst.p[p3].coefficient = tmp;
|
||||
++p1, ++p2, ++p3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (p1 == n) {
|
||||
while (p2 < a.n) {
|
||||
rst.p[p3].index = a.p[p2].index;
|
||||
rst.p[p3].coefficient = a.p[p2].coefficient;
|
||||
++p2, ++p3;
|
||||
}
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
while (p1 < n) {
|
||||
rst.p[p3].index = p[p1].index;
|
||||
rst.p[p3].coefficient = p[p1].coefficient;
|
||||
++p1, ++p3;
|
||||
}
|
||||
}
|
||||
|
||||
rst.n = p3;
|
||||
return rst;
|
||||
}
|
||||
|
@ -193,40 +214,50 @@ polynomial polynomial::operator-(const polynomial & a)
|
|||
{
|
||||
polynomial rst(a) ;
|
||||
int i = 0;
|
||||
|
||||
while (i < rst.n) {
|
||||
rst.p[i].coefficient = -rst.p[i].coefficient;
|
||||
++i;
|
||||
}
|
||||
|
||||
return (*this + rst);
|
||||
}
|
||||
polynomial polynomial::operator*(const polynomial & a)
|
||||
{
|
||||
map<double, double> mp;
|
||||
|
||||
for (int i = 0; i < n; ++i) {
|
||||
double idx = p[i].index;
|
||||
double coef = p[i].coefficient;
|
||||
|
||||
for (int j = 0; j < a.n; ++j) {
|
||||
double index = idx + a.p[j].index;
|
||||
|
||||
if (mp.count(index) == 0) {
|
||||
mp[index] = coef * a.p[j].coefficient;
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
mp[index] += coef * a.p[j].coefficient;
|
||||
|
||||
if (isZero(mp[index])) {
|
||||
mp.erase(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int sz = 50;
|
||||
|
||||
while (mp.size() > sz) {
|
||||
sz *= 2;
|
||||
}
|
||||
|
||||
polynomial rst(sz);
|
||||
|
||||
for (map<double, double>::iterator it = mp.begin(); it != mp.end(); ++it) {
|
||||
rst.p[rst.n].index = it->first;
|
||||
rst.p[rst.n++].coefficient = it->second;
|
||||
}
|
||||
|
||||
return rst;
|
||||
}
|
||||
int num = 0;
|
||||
|
@ -250,93 +281,93 @@ void menu()
|
|||
void loop()
|
||||
{
|
||||
int op;
|
||||
|
||||
while (scanf("%d", &op) != EOF) {
|
||||
if (op == 0) {
|
||||
pl[num].getData();
|
||||
++num;
|
||||
printf("You've created polynomial %d:\n", num);
|
||||
pl[num - 1].display();
|
||||
}
|
||||
else if(op==1||op==2||op==3){
|
||||
} else if (op == 1 || op == 2 || op == 3) {
|
||||
if (num < 2) {
|
||||
printf("Oops! you've got less two polynomial\nPlease choose another operation\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
printf("input two nums of the two polynomial to be operated.eg: 1 2\n");
|
||||
int t1 = 100, t2 = 100;
|
||||
|
||||
while (1) {
|
||||
scanf("%d%d", &t1, &t2);
|
||||
|
||||
if (t1 > num || t2 > num || t1 < 0 || t2 < 0) {
|
||||
printf("wrong num ,please input again\n");
|
||||
} else break;
|
||||
}
|
||||
else break;
|
||||
}
|
||||
|
||||
printf("the rst is:\n");
|
||||
t1 -= 1, t2 -= 1;
|
||||
|
||||
if (op == 1) {
|
||||
(pl[t1] + pl[t2]).display();
|
||||
}
|
||||
else if(op == 2){
|
||||
} else if (op == 2) {
|
||||
(pl[t1] - pl[t2]).display();
|
||||
}
|
||||
else (pl[t1]*pl[t2]).display();
|
||||
}
|
||||
else if(op == 4){
|
||||
} else (pl[t1]*pl[t2]).display();
|
||||
} else if (op == 4) {
|
||||
printf("input a polynomial's num to display it\n");
|
||||
int tmp;
|
||||
scanf("%d", &tmp);
|
||||
|
||||
if (tmp > num) {
|
||||
printf("wrong num");
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
printf("info of polynomial %d\n", tmp);
|
||||
pl[tmp - 1].display();
|
||||
}
|
||||
}
|
||||
else if(op == 9){
|
||||
} else if (op == 9) {
|
||||
for (int i = 0; i < num; ++i) {
|
||||
printf("polynomial %d : ", i + 1);
|
||||
pl[i].display();
|
||||
}
|
||||
}
|
||||
else if(op == 5){
|
||||
} else if (op == 5) {
|
||||
menu();
|
||||
}
|
||||
else if(op == 6){
|
||||
} else if (op == 6) {
|
||||
if (LINUX) system("clear");
|
||||
else system("cls");
|
||||
|
||||
menu();
|
||||
}
|
||||
else if(op == 10){
|
||||
} else if (op == 10) {
|
||||
double x;
|
||||
int t;
|
||||
printf("choose a polynomial\n");
|
||||
scanf("%d", &t);
|
||||
|
||||
if (t > num || t < 0) {
|
||||
printf("wrong num\n");
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
printf("input a value\n");
|
||||
scanf("%lf", &x);
|
||||
pl[t - 1].display();
|
||||
printf("%g\n", pl[t - 1].cal(x));
|
||||
}
|
||||
}
|
||||
else if(op == 8){
|
||||
} else if (op == 8) {
|
||||
if (num == 0) {
|
||||
printf("you have'nt any polynomial tp copy\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
int n = num + 1;
|
||||
|
||||
while (n > num) {
|
||||
printf("input the number of an existing polynomial you want to copy\n");
|
||||
scanf("%d", &n);
|
||||
}
|
||||
|
||||
(pl[num] = pl[n - 1]);
|
||||
printf("You've copyed this polynomial:\n");
|
||||
pl[num++].display();
|
||||
}
|
||||
else exit(0);
|
||||
} else exit(0);
|
||||
|
||||
printf("select an operation\n");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,17 +16,21 @@
|
|||
|
||||
# to be implemented
|
||||
|
||||
|
||||
class polynomial:
|
||||
pls = []
|
||||
n = 0
|
||||
|
||||
def dictize(pl):
|
||||
if isinstance(pl, int) or isinstance(pl, float):
|
||||
pl = {0: pl}
|
||||
if isinstance(pl, polynomial):
|
||||
pl = pl.polynomial.copy()
|
||||
return pl
|
||||
|
||||
def isZero(n):
|
||||
return abs(n) < 0.000001
|
||||
|
||||
def __init__(self, s='0 0'):
|
||||
polynomial.pls.append(self)
|
||||
polynomial.n += 1
|
||||
|
@ -53,18 +57,24 @@ class polynomial:
|
|||
index = li[i+1]
|
||||
if index in self.polynomial.keys():
|
||||
self.polynomial[index] += li[i]
|
||||
else:self.polynomial[index] = li[i]
|
||||
else:
|
||||
self.polynomial[index] = li[i]
|
||||
i += 2
|
||||
if not self.polynomial:
|
||||
self.polynomial = {0: 0}
|
||||
|
||||
def __iter__(self):
|
||||
return iter(list(self.polynomial.keys()))
|
||||
|
||||
def __getitem__(self, key):
|
||||
return self.polynomial[key]
|
||||
|
||||
def __setitem__(self, key, val):
|
||||
self.polynomial[key] = val
|
||||
|
||||
def __delitem__(self, k):
|
||||
del self.polynomial[k]
|
||||
|
||||
def __add__(self, pl):
|
||||
pl = polynomial.dictize(pl)
|
||||
rst = self.polynomial.copy()
|
||||
|
@ -76,6 +86,7 @@ class polynomial:
|
|||
if polynomial.isZero(rst[i]):
|
||||
del rst[i]
|
||||
return polynomial(rst)
|
||||
|
||||
def __iadd__(self, pl):
|
||||
pl = polynomial.dictize(pl)
|
||||
for i in pl:
|
||||
|
@ -86,10 +97,12 @@ class polynomial:
|
|||
if polynomial.isZero(self[i]):
|
||||
del self[i]
|
||||
return self
|
||||
|
||||
def __sub__(self, pl):
|
||||
pl = polynomial.dictize(pl)
|
||||
tmp = {i: -j for i, j in pl.items()}
|
||||
return self + tmp
|
||||
|
||||
def __mul__(self, pl):
|
||||
pl = polynomial.dictize(pl)
|
||||
dic = dict()
|
||||
|
@ -98,18 +111,23 @@ class polynomial:
|
|||
index = i+j
|
||||
if index in dic:
|
||||
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)})
|
||||
|
||||
def __imul__(self, pl):
|
||||
self = self*pl
|
||||
return self
|
||||
|
||||
def __pow__(self, n):
|
||||
rst = polynomial({0: 1})
|
||||
for i in range(n):
|
||||
rst *= self.polynomial
|
||||
return rst
|
||||
|
||||
def __repr__(self):
|
||||
return self.__str__()
|
||||
|
||||
def __str__(self):
|
||||
output = ''
|
||||
if self.polynomial:
|
||||
|
@ -122,19 +140,25 @@ class polynomial:
|
|||
if not polynomial.isZero(self[i]-1):
|
||||
if not polynomial.isZero(self[i]+1):
|
||||
output += "%+g" % self[i]
|
||||
else:output +='-'
|
||||
else:output +='+'
|
||||
if not polynomial.isZero(i): output +='x'
|
||||
if not polynomial.isZero(i-1):output +='^%g'%i
|
||||
else:
|
||||
output += '-'
|
||||
else:
|
||||
output += '+'
|
||||
if not polynomial.isZero(i):
|
||||
output += 'x'
|
||||
if not polynomial.isZero(i-1):
|
||||
output += '^%g' % i
|
||||
|
||||
if output[0] == '+':
|
||||
return output[1:]
|
||||
return output
|
||||
|
||||
def iterPolynomial(self, s):
|
||||
rst = polynomial({0: 0})
|
||||
for i in self:
|
||||
rst += s**int(i)*self[i]
|
||||
return rst
|
||||
|
||||
def __call__(self, s):
|
||||
if isinstance(s, polynomial):
|
||||
return self.iterPolynomial(s)
|
||||
|
@ -142,16 +166,21 @@ class polynomial:
|
|||
for i in self:
|
||||
sum += self[i] * s**i
|
||||
return sum
|
||||
|
||||
def __xor__(self, n):
|
||||
tmp = polynomial(self)
|
||||
for i in range(n):
|
||||
self = self.iterPolynomial(tmp)
|
||||
return self
|
||||
|
||||
def save(self):
|
||||
polynomial.pls.append(self)
|
||||
polynomial.n += 1
|
||||
|
||||
def delPlynomial(self, n):
|
||||
return polynomial.pls.pop(n-1)
|
||||
|
||||
|
||||
def menu():
|
||||
print('polynomial operations')
|
||||
print('1.create')
|
||||
|
@ -166,5 +195,6 @@ def menu():
|
|||
print('10.menu')
|
||||
print('11.exit')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
pass
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
from functools import total_ordering
|
||||
from random import randint, shuffle
|
||||
|
||||
|
||||
@total_ordering
|
||||
class node:
|
||||
def __init__(self, val, left=None, right=None, isBlack=False):
|
||||
|
@ -20,26 +21,39 @@ class node:
|
|||
self.right = right
|
||||
self.parent = None
|
||||
self.isBlack = isBlack
|
||||
|
||||
def __lt__(self, nd):
|
||||
return self.val < nd.val
|
||||
|
||||
def __eq__(self, nd):
|
||||
return nd is not None and self.val == nd.val
|
||||
|
||||
def setChild(self, nd, isLeft):
|
||||
if isLeft: self.left = nd
|
||||
else: self.right = nd
|
||||
if nd is not None: nd.parent = self
|
||||
if isLeft:
|
||||
self.left = nd
|
||||
else:
|
||||
self.right = nd
|
||||
if nd is not None:
|
||||
nd.parent = self
|
||||
|
||||
def getChild(self, isLeft):
|
||||
if isLeft: return self.left
|
||||
else: return self.right
|
||||
if isLeft:
|
||||
return self.left
|
||||
else:
|
||||
return self.right
|
||||
|
||||
def __bool__(self):
|
||||
return self.val is not None
|
||||
|
||||
def __str__(self):
|
||||
color = 'B' if self.isBlack else 'R'
|
||||
val = '-' if self.parent == None else self.parent.val
|
||||
return f'{color}-{self.val}'
|
||||
|
||||
def __repr__(self):
|
||||
return f'node({self.val},isBlack={self.isBlack})'
|
||||
|
||||
|
||||
class redBlackTree:
|
||||
def __init__(self, unique=False):
|
||||
'''if unique is True, all node'vals are unique, else there may be equal vals'''
|
||||
|
@ -49,15 +63,20 @@ class redBlackTree:
|
|||
@staticmethod
|
||||
def checkBlack(nd):
|
||||
return nd is None or nd.isBlack
|
||||
|
||||
@staticmethod
|
||||
def setBlack(nd, isBlack):
|
||||
if nd is not None:
|
||||
if isBlack is None or isBlack:
|
||||
nd.isBlack = True
|
||||
else:nd.isBlack = False
|
||||
else:
|
||||
nd.isBlack = False
|
||||
|
||||
def setRoot(self, nd):
|
||||
if nd is not None: nd.parent=None
|
||||
if nd is not None:
|
||||
nd.parent = None
|
||||
self.root = nd
|
||||
|
||||
def find(self, val):
|
||||
nd = self.root
|
||||
while nd:
|
||||
|
@ -65,6 +84,7 @@ class redBlackTree:
|
|||
return nd
|
||||
else:
|
||||
nd = nd.getChild(nd.val > val)
|
||||
|
||||
def getSuccessor(self, nd):
|
||||
if nd:
|
||||
if nd.right:
|
||||
|
@ -76,6 +96,7 @@ class redBlackTree:
|
|||
while nd.parent is not None and nd.parent.right is nd:
|
||||
nd = nd.parent
|
||||
return None if nd is self.root else nd.parent
|
||||
|
||||
def rotate(self, prt, chd):
|
||||
'''rotate prt with the center of chd'''
|
||||
if self.root is prt:
|
||||
|
@ -87,7 +108,8 @@ class redBlackTree:
|
|||
chd.setChild(prt, not isLeftChd)
|
||||
|
||||
def insert(self, nd):
|
||||
if nd.isBlack: nd.isBlack = False
|
||||
if nd.isBlack:
|
||||
nd.isBlack = False
|
||||
|
||||
if self.root is None:
|
||||
self.setRoot(nd)
|
||||
|
@ -95,7 +117,8 @@ class redBlackTree:
|
|||
else:
|
||||
parent = self.root
|
||||
while parent:
|
||||
if parent == nd : return None
|
||||
if parent == nd:
|
||||
return None
|
||||
isLeft = parent > nd
|
||||
chd = parent.getChild(isLeft)
|
||||
if chd is None:
|
||||
|
@ -104,6 +127,7 @@ class redBlackTree:
|
|||
else:
|
||||
parent = chd
|
||||
self.fixUpInsert(parent, nd)
|
||||
|
||||
def fixUpInsert(self, parent, nd):
|
||||
''' adjust color and level, there are two red nodes: the new one and its parent'''
|
||||
while not self.checkBlack(parent):
|
||||
|
@ -143,12 +167,16 @@ class redBlackTree:
|
|||
data exclude left, right , isBlack
|
||||
'''
|
||||
des.val = src.val
|
||||
|
||||
def delete(self, val):
|
||||
'''delete node in a binary search tree'''
|
||||
if isinstance(val,node): val = val.val
|
||||
if isinstance(val, node):
|
||||
val = val.val
|
||||
nd = self.find(val)
|
||||
if nd is None: return
|
||||
if nd is None:
|
||||
return
|
||||
self._delete(nd)
|
||||
|
||||
def _delete(self, nd):
|
||||
y = None
|
||||
if nd.left and nd.right:
|
||||
|
@ -163,7 +191,8 @@ class redBlackTree:
|
|||
py.setChild(x, py.left is y)
|
||||
if 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):
|
||||
''' adjust colors and rotate '''
|
||||
|
@ -211,7 +240,8 @@ class redBlackTree:
|
|||
def sort(self, reverse=False):
|
||||
''' return a generator of sorted data'''
|
||||
def inOrder(root):
|
||||
if root is None:return
|
||||
if root is None:
|
||||
return
|
||||
if reverse:
|
||||
yield from inOrder(root.right)
|
||||
else:
|
||||
|
@ -225,8 +255,10 @@ class redBlackTree:
|
|||
|
||||
def display(self):
|
||||
def getHeight(nd):
|
||||
if nd is None:return 0
|
||||
if nd is None:
|
||||
return 0
|
||||
return max(getHeight(nd.left), getHeight(nd.right)) + 1
|
||||
|
||||
def levelVisit(root):
|
||||
from collections import deque
|
||||
lst = deque([root])
|
||||
|
@ -238,7 +270,8 @@ class redBlackTree:
|
|||
nd = lst.popleft()
|
||||
if ct >= 2**lv:
|
||||
lv += 1
|
||||
if lv>h:break
|
||||
if lv > h:
|
||||
break
|
||||
level.append([])
|
||||
level[-1].append(str(nd))
|
||||
if nd is not None:
|
||||
|
@ -246,6 +279,7 @@ class redBlackTree:
|
|||
else:
|
||||
lst += [None, None]
|
||||
return level
|
||||
|
||||
def addBlank(lines):
|
||||
width = 1+len(str(self.root))
|
||||
sep = ' '*width
|
||||
|
@ -266,6 +300,7 @@ class redBlackTree:
|
|||
begin = '\n' + 'red-black-tree'.rjust(length+14, '-') + '-'*(length)
|
||||
end = '-'*(length*2+14)+'\n'
|
||||
return '\n'.join([begin, *li, end])
|
||||
|
||||
def __str__(self):
|
||||
return self.display()
|
||||
|
||||
|
@ -280,8 +315,10 @@ def genNum(n =10):
|
|||
break
|
||||
return nums
|
||||
|
||||
|
||||
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()
|
||||
print(f'build a red-black tree using {nums}')
|
||||
for i in nums:
|
||||
|
@ -290,6 +327,8 @@ def buildTree(n=10,nums=None,visitor=None):
|
|||
if visitor:
|
||||
visitor(rbtree, i)
|
||||
return rbtree, nums
|
||||
|
||||
|
||||
def testInsert(nums=None):
|
||||
def visitor(t, val):
|
||||
print('inserting', val)
|
||||
|
@ -299,11 +338,13 @@ def testInsert(nums=None):
|
|||
for i, j in enumerate(rbtree.sort()):
|
||||
print(f'{i+1}: {j}')
|
||||
|
||||
|
||||
def testSuc(nums=None):
|
||||
rbtree, nums = buildTree(nums=nums)
|
||||
for i in rbtree.sort():
|
||||
print(f'{i}\'s suc is {rbtree.getSuccessor(i)}')
|
||||
|
||||
|
||||
def testDelete(nums=None):
|
||||
rbtree, nums = buildTree(nums=nums)
|
||||
print(rbtree)
|
||||
|
@ -312,6 +353,7 @@ def testDelete(nums=None):
|
|||
rbtree.delete(i)
|
||||
print(rbtree)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
lst = [45, 30, 64, 36, 95, 38, 76, 34, 50, 1]
|
||||
lst = [0, 3, 5, 6, 26, 25, 8, 19, 15, 16, 17]
|
||||
|
|
|
@ -12,30 +12,46 @@
|
|||
|
||||
from collections import deque, Iterable
|
||||
# use isinstance(obj,Iterable) to judge if an obj is iterable
|
||||
|
||||
|
||||
class node:
|
||||
def __init__(self, val=None, left=None, right=None, parent=None):
|
||||
self.val = val
|
||||
if val :self.freq = 1
|
||||
else :self.freq = 0
|
||||
if val:
|
||||
self.freq = 1
|
||||
else:
|
||||
self.freq = 0
|
||||
self.left = left
|
||||
self.right = right
|
||||
self.parent = parent
|
||||
|
||||
def getChild(self, s=0):
|
||||
if isinstance(s,int):s =[s]
|
||||
if isinstance(s, int):
|
||||
s = [s]
|
||||
last = self
|
||||
for i in s:
|
||||
if not last:return None
|
||||
if i == 0: last = last.left
|
||||
else:last = last.right
|
||||
if not last:
|
||||
return None
|
||||
if i == 0:
|
||||
last = last.left
|
||||
else:
|
||||
last = last.right
|
||||
return last
|
||||
|
||||
def setChild(self, child, s=0):
|
||||
if isinstance(s, Iterable):
|
||||
i = s[0]
|
||||
del s[0]
|
||||
if i == 0:self.left.setChild(child,s)
|
||||
else:self.right.setChild(child,s)
|
||||
elif s:self.right = child
|
||||
else:self.left = child
|
||||
if i == 0:
|
||||
self.left.setChild(child, s)
|
||||
else:
|
||||
self.right.setChild(child, s)
|
||||
elif s:
|
||||
self.right = child
|
||||
else:
|
||||
self.left = child
|
||||
|
||||
|
||||
class splayTree:
|
||||
def __init__(self, s=[]):
|
||||
s = list(s)
|
||||
|
@ -43,9 +59,13 @@ class splayTree:
|
|||
s = sorted(s, reverse=True)
|
||||
for i in s:
|
||||
self.insert(self.root, i)
|
||||
|
||||
def insert(self, k):
|
||||
if not self.root :self.root = node(k)
|
||||
else:self._insert(self.root,k)
|
||||
if not self.root:
|
||||
self.root = node(k)
|
||||
else:
|
||||
self._insert(self.root, k)
|
||||
|
||||
def _insert(self, root, k):
|
||||
if root.val == k:
|
||||
root.freq += 1
|
||||
|
@ -53,30 +73,38 @@ class splayTree:
|
|||
if not root.right:
|
||||
root.right = node(k)
|
||||
root.right.parent = root
|
||||
else:self._insert(root.right,k)
|
||||
else:
|
||||
self._insert(root.right, k)
|
||||
else:
|
||||
if not root.left:
|
||||
root.left = node(k)
|
||||
root.left.parent = root
|
||||
else:self._insert(root.left,k)
|
||||
else:
|
||||
self._insert(root.left, k)
|
||||
|
||||
def _zigzagRotate(self, i, j, root, parent, grand):
|
||||
parent.setChild(root.getChild(i), j)
|
||||
root.setChild(parent, i)
|
||||
grand.setChild(root.getChild(j), i)
|
||||
root.setChild(grand, j)
|
||||
if root.parent:root.parent = grand.parent
|
||||
if root.parent:
|
||||
root.parent = grand.parent
|
||||
parent.parent = root
|
||||
grand.parent = root
|
||||
|
||||
def _lineRotate(self, i, root, parent, grand):
|
||||
grand.setChild(parent.getChild(i ^ 1), i)
|
||||
parent.setChild(grand, i ^ 1)
|
||||
parent.setChild(root.getChild(i ^ 1), i)
|
||||
root.setChild(parent, i ^ 1)
|
||||
if root.parent:root.parent = grand.parent
|
||||
if root.parent:
|
||||
root.parent = grand.parent
|
||||
parent.parent = root
|
||||
grand.parent = parent
|
||||
|
||||
def _rotate(self, root):
|
||||
if root == self.root:return
|
||||
if root == self.root:
|
||||
return
|
||||
if root.parent == self.root:
|
||||
for i in range(2):
|
||||
if root.parent.getChild(i) == root:
|
||||
|
@ -102,8 +130,10 @@ class splayTree:
|
|||
elif i == j and grand.getChild([i, i]) == root:
|
||||
self._lineRotate(i, root, parent, grand)
|
||||
self._rotate(root)
|
||||
|
||||
def _find(self, root, k):
|
||||
if not root:return 0
|
||||
if not root:
|
||||
return 0
|
||||
if root.val > k:
|
||||
return self._find(root.left, k)
|
||||
elif root.val < k:
|
||||
|
@ -111,18 +141,24 @@ class splayTree:
|
|||
else:
|
||||
self._rotate(root)
|
||||
return root.freq
|
||||
|
||||
def _maxmin(self, root, i=0):
|
||||
if not root:return None
|
||||
if not root:
|
||||
return None
|
||||
if root.getChild(i):
|
||||
return self._maxmin(root.getChild(i))
|
||||
return root
|
||||
|
||||
def Max(self):
|
||||
return self._maxmin(self.root, 1)
|
||||
|
||||
def Min(self):
|
||||
return self._maxmin(self.root, 0)
|
||||
|
||||
def remove(self, k):
|
||||
tmp = self.find(k)
|
||||
if not tmp:raise ValueError
|
||||
if not tmp:
|
||||
raise ValueError
|
||||
else:
|
||||
if self.root.left:
|
||||
r = self.root.right
|
||||
|
@ -134,8 +170,10 @@ class splayTree:
|
|||
r.parent = Max
|
||||
else:
|
||||
self.root = self.root.right
|
||||
|
||||
def find(self, k):
|
||||
return self._find(self.root, k)
|
||||
|
||||
def levelTraverse(self):
|
||||
q = deque()
|
||||
q.append((self.root, 0))
|
||||
|
@ -143,15 +181,19 @@ class splayTree:
|
|||
while q:
|
||||
tmp, n = q.popleft()
|
||||
rst.append(tmp)
|
||||
if tmp.left:q.append((tmp.left,n+1))
|
||||
if tmp.right:q.append((tmp.right,n+1))
|
||||
if tmp.left:
|
||||
q.append((tmp.left, n+1))
|
||||
if tmp.right:
|
||||
q.append((tmp.right, n+1))
|
||||
return rst
|
||||
|
||||
def display(self):
|
||||
data = self.levelTraverse()
|
||||
for i in data:
|
||||
print(i.val, end=' ')
|
||||
print('')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
a = splayTree()
|
||||
a.insert(5)
|
||||
|
|
12
dataStructure/unionFindSet.py
Normal file
12
dataStructure/unionFindSet.py
Normal 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
|
|
@ -1,99 +0,0 @@
|
|||
#coding: utf-8
|
||||
''' mbinary
|
||||
#######################################################################
|
||||
# File : accountsMerge.py
|
||||
# Author: mbinary
|
||||
# Mail: zhuheqin1@gmail.com
|
||||
# Blog: https://mbinary.xyz
|
||||
# Github: https://github.com/mbinary
|
||||
# Created Time: 2018-12-18 17:07
|
||||
# Description:
|
||||
给定一个列表 accounts,每个元素 accounts[i] 是一个字符串列表,其中第一个元素 accounts[i][0] 是 名称 (name),其余元素是 emails 表示该帐户的邮箱地址。
|
||||
|
||||
现在,我们想合并这些帐户。如果两个帐户都有一些共同的邮件地址,则两个帐户必定属于同一个人。请注意,即使两个帐户具有相同的名称,它们也可能属于不同的人,因为人们可能具有相同的名称。一个人最初可以拥有任意数量的帐户,但其所有帐户都具有相同的名称。
|
||||
|
||||
合并帐户后,按以下格式返回帐户:每个帐户的第一个元素是名称,其余元素是按顺序排列的邮箱地址。accounts 本身可以以任意顺序返回。
|
||||
|
||||
例子 1:
|
||||
|
||||
Input:
|
||||
accounts = [["John", "johnsmith@mail.com", "john00@mail.com"], ["John", "johnnybravo@mail.com"], ["John", "johnsmith@mail.com", "john_newyork@mail.com"], ["Mary", "mary@mail.com"]]
|
||||
Output: [["John", 'john00@mail.com', 'john_newyork@mail.com', 'johnsmith@mail.com'], ["John", "johnnybravo@mail.com"], ["Mary", "mary@mail.com"]]
|
||||
Explanation:
|
||||
第一个和第三个 John 是同一个人,因为他们有共同的电子邮件 "johnsmith@mail.com"。
|
||||
第二个 John 和 Mary 是不同的人,因为他们的电子邮件地址没有被其他帐户使用。
|
||||
#######################################################################
|
||||
'''
|
||||
|
||||
class Solution(object):
|
||||
def accountsMerge(self, accounts):
|
||||
"""
|
||||
:type accounts: List[List[str]]
|
||||
:rtype: List[List[str]]
|
||||
"""
|
||||
mailDic = {}
|
||||
for ct,i in enumerate(accounts):
|
||||
for j in i[1:]:
|
||||
mailDic[j] = (ct,i[0])
|
||||
mails = {mail:idx for idx,mail in enumerate(mailDic.keys())}
|
||||
mailNum = len(mails)
|
||||
self.findSet = [i for i in range(mailNum)]
|
||||
for li in accounts:
|
||||
n = len(li)
|
||||
for i in range(1,n-1):
|
||||
for j in range(i+1,n):
|
||||
self.union(mails[li[i]],mails[li[j]])
|
||||
dic = {}
|
||||
mails = {j:i for i,j in mails.items()}
|
||||
for i in range(mailNum):
|
||||
mail = mails[i]
|
||||
n = mailDic[mails[self.find(i)]][0]
|
||||
if n in dic:
|
||||
dic[n].append(mail)
|
||||
else:
|
||||
dic[n] = [mail]
|
||||
nameId = {i[0]:i[1] for i in mailDic.values()}
|
||||
return [[nameId[i]]+sorted(mail) for i,mail in dic.items()]
|
||||
def find(self,i):
|
||||
if self.findSet[i]!=i:
|
||||
n = self.find(self.findSet[i])
|
||||
self.findSet[i] = n
|
||||
return self.findSet[i]
|
||||
def union(self,i,j):
|
||||
if i!=j:
|
||||
n = self.find(i)
|
||||
if n!=self.find(j):
|
||||
self.findSet[n] = self.findSet[j]
|
||||
|
||||
class Solution2:
|
||||
'''并查映射'''
|
||||
def accountsMerge(self, accounts):
|
||||
"""
|
||||
:type accounts: List[List[str]]
|
||||
:rtype: List[List[str]]
|
||||
"""
|
||||
mailDic = {j:ct for ct,i in enumerate(accounts) for j in i[1:]}
|
||||
self.findSet = {i:i for i in mailDic}
|
||||
for li in accounts:
|
||||
n = len(li)
|
||||
for i in range(1,n-1):
|
||||
for j in range(i+1,n):
|
||||
self.union(li[i],li[j])
|
||||
dic = {}
|
||||
for mail in self.findSet:
|
||||
n = mailDic[self.find(mail)]
|
||||
if n in dic:
|
||||
dic[n].append(mail)
|
||||
else:
|
||||
dic[n] = [mail]
|
||||
return [[accounts[i][0]]+sorted(mail) for i,mail in dic.items()]
|
||||
def find(self,i):
|
||||
if self.findSet[i]!=i:
|
||||
n = self.find(self.findSet[i])
|
||||
self.findSet[i] = n
|
||||
return self.findSet[i]
|
||||
def union(self,i,j):
|
||||
if i!=j:
|
||||
n = self.find(i)
|
||||
if n!=self.find(j):
|
||||
self.findSet[n] = self.findSet[j]
|
|
@ -1,42 +0,0 @@
|
|||
#coding: utf-8
|
||||
''' mbinary
|
||||
#######################################################################
|
||||
# File : unionFind.py
|
||||
# Author: mbinary
|
||||
# Mail: zhuheqin1@gmail.com
|
||||
# Blog: https://mbinary.xyz
|
||||
# Github: https://github.com/mbinary
|
||||
# Created Time: 2018-12-18 14:53
|
||||
# Description:
|
||||
班上有 N 名学生。其中有些人是朋友,有些则不是。他们的友谊具有是传递性。如果已知 A 是 B 的朋友,B 是 C 的朋友,那么我们可以认为 A 也是 C 的朋友。所谓的朋友圈,是指所有朋友的集合。
|
||||
|
||||
给定一个 N * N 的矩阵 M,表示班级中学生之间的朋友关系。如果 M[i][j] = 1,表示已知第 i 个和 j 个学生互为朋友关系,否则为不知道。你必须输出所有学生中的已知的朋友圈总数。
|
||||
#######################################################################
|
||||
'''
|
||||
|
||||
|
||||
class Solution(object):
|
||||
def findCircleNum(self, M):
|
||||
"""
|
||||
:type M: List[List[int]]
|
||||
:rtype: int
|
||||
"""
|
||||
n = len(M)
|
||||
self.data = [i for i in range(n)]
|
||||
for i in range(n):
|
||||
for j in range(n):
|
||||
if M[i][j]==1:
|
||||
self.union(i,j)
|
||||
ret = set()
|
||||
for i in range(n):
|
||||
ret.add(self.find(i))
|
||||
return len(ret)
|
||||
def find(self,i):
|
||||
if self.data[i]!=i:
|
||||
self.data[i] = self.find(self.data[i])
|
||||
return self.data[i]
|
||||
def union(self,i,j):
|
||||
if i!=j:
|
||||
n = self.find(i)
|
||||
if n!=self.find(j):
|
||||
self.data[n]= self.data[j]
|
|
@ -10,6 +10,7 @@
|
|||
#########################################################################
|
||||
'''
|
||||
|
||||
|
||||
class winnerTree:
|
||||
'''if i<lowExt p = (i+offset)//2
|
||||
else p = (i+n-1-lowExt)//2
|
||||
|
@ -18,6 +19,7 @@ class winnerTree:
|
|||
i is the index of players
|
||||
lowExt is the double node num of the lowest layer of the tree
|
||||
'''
|
||||
|
||||
def __init__(self, players, reverse=False):
|
||||
self.n = len(players)
|
||||
self.tree = [0]*self.n
|
||||
|
@ -26,9 +28,11 @@ class winnerTree:
|
|||
self.reverse = reverse
|
||||
self.getNum()
|
||||
self.initTree(1)
|
||||
|
||||
def getNum(self):
|
||||
i = 1
|
||||
while 2*i< self.n:i=i*2
|
||||
while 2*i < self.n:
|
||||
i = i*2
|
||||
if 2*i == self. n:
|
||||
self.lowExt = 0
|
||||
self.s = 2*i-1
|
||||
|
@ -36,12 +40,16 @@ class winnerTree:
|
|||
self.lowExt = (self.n-i)*2
|
||||
self.s = i-1
|
||||
self.offset = 2*i-1
|
||||
|
||||
def treeToArray(self, p):
|
||||
return 2*p-self.offset if p > self.s else 2*p+self.lowExt-self.n+1
|
||||
|
||||
def arrayToTree(self, i):
|
||||
return (i+self.offset)//2 if i <= self.lowExt else (i-self.lowExt + self.n-1)//2
|
||||
|
||||
def win(self, a, b):
|
||||
return a < b if self.reverse else a > b
|
||||
|
||||
def initTree(self, p):
|
||||
if p >= self.n:
|
||||
delta = p % 2 # !!! good job notice delta mark the lchild or rchlid
|
||||
|
@ -50,6 +58,7 @@ class winnerTree:
|
|||
r = self.initTree(2*p+1)
|
||||
self.tree[p] = l if self.win(l, r) else r
|
||||
return self.tree[p]
|
||||
|
||||
def winner(self):
|
||||
idx = 1
|
||||
while 2*idx < self.n:
|
||||
|
@ -57,14 +66,18 @@ class winnerTree:
|
|||
num = self.treeToArray(idx)
|
||||
num = num+1 if self.players[num] != self.tree[1] else num
|
||||
return self.tree[1], num
|
||||
|
||||
def getOppo(self, i, x, p):
|
||||
oppo = None
|
||||
if 2*p<self.n:oppo=self.tree[2*p]
|
||||
elif i<=self.lowExt:oppo=self.players[i-1+i%2*2]
|
||||
if 2*p < self.n:
|
||||
oppo = self.tree[2*p]
|
||||
elif i <= self.lowExt:
|
||||
oppo = self.players[i-1+i % 2*2]
|
||||
else:
|
||||
lpl = self.players[2*p+self.lowExt-self.n+1]
|
||||
oppo = lpl if lpl != x else self.players[2*p+self.lowExt-self.n+2]
|
||||
return oppo
|
||||
|
||||
def update(self, i, x):
|
||||
''' i is 1-indexed which is the num of player
|
||||
and x is the new val of the player '''
|
||||
|
@ -76,13 +89,14 @@ class winnerTree:
|
|||
while p:
|
||||
l = self.tree[p*2]
|
||||
r = None
|
||||
if 2*p+1<self.n:r=self.tree[p*2+1] #notice this !!!
|
||||
else:r = self.players[2*p+self.lowExt-self.n+1]
|
||||
if 2*p+1 < self.n:
|
||||
r = self.tree[p*2+1] # notice this !!!
|
||||
else:
|
||||
r = self.players[2*p+self.lowExt-self.n+1]
|
||||
self.tree[p] = l if self.win(l, r) else r
|
||||
p = p//2
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
s = [4, 1, 6, 7, 9, 5234, 0, 2, 7, 4, 123]
|
||||
t = winnerTree(s)
|
||||
|
|
|
@ -13,34 +13,47 @@ from random import randint
|
|||
from time import time
|
||||
from functools import total_ordering
|
||||
|
||||
|
||||
@total_ordering
|
||||
class point:
|
||||
def __init__(self, x, y):
|
||||
self.x = x
|
||||
self.y = y
|
||||
|
||||
def __neg__(self):
|
||||
return pont(-self.x, -self.y)
|
||||
|
||||
def __len__(self):
|
||||
return self.norm(2)
|
||||
|
||||
def __lt__(self, p):
|
||||
return self.x < p.x or (self.x == p.x and self.y < p.y)
|
||||
|
||||
def __eq__(self, p):
|
||||
return self.x == p.x and self.y == p.y
|
||||
|
||||
def __hash__(self):
|
||||
return hash((self.x, self.y))
|
||||
|
||||
def __repr__(self):
|
||||
return 'point({},{})'.format(self.x, self.y)
|
||||
|
||||
def __str__(self):
|
||||
return self.__repr__()
|
||||
|
||||
def norm(self, n=2):
|
||||
if n<=0: return max(abs(self.x),abs(self.y))
|
||||
if n <= 0:
|
||||
return max(abs(self.x), abs(self.y))
|
||||
return (abs(self.x)**n+abs(self.y)**n)**(1/n)
|
||||
|
||||
def distance(self, p):
|
||||
return ((self.x-p.x)**2+(self.y-p.y)**2)**0.5
|
||||
|
||||
|
||||
def minDistance_n2(points):
|
||||
n = len(points)
|
||||
if n<=1: return 0
|
||||
if n <= 1:
|
||||
return 0
|
||||
p, q = points[:2]
|
||||
minD = points[0].distance(points[1])
|
||||
for i in range(n-1):
|
||||
|
@ -52,6 +65,7 @@ def minDistance_n2(points):
|
|||
q = points[j]
|
||||
return minD, p, q
|
||||
|
||||
|
||||
def findif(points, f, reverse=False):
|
||||
n = len(points)
|
||||
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.copy() # note that don't return exactly points, return a copy one
|
||||
|
||||
|
||||
def floatEql(f1, f2, epsilon=1e-6):
|
||||
return abs(f1-f2) < epsilon
|
||||
|
||||
|
||||
def minDistance_nlogn(n_points):
|
||||
def _min(pts):
|
||||
n = len(pts)
|
||||
if n==2: return pts[0].distance(pts[1]) , pts[0],pts[1]
|
||||
if n == 2:
|
||||
return pts[0].distance(pts[1]), pts[0], pts[1]
|
||||
if n == 3:
|
||||
minD = pts[0].distance(pts[1])
|
||||
p, q = pts[0], pts[1]
|
||||
|
@ -75,8 +92,10 @@ def minDistance_nlogn(n_points):
|
|||
minD = d2
|
||||
p, q = pts[1], pts[2]
|
||||
d2 = pts[0].distance(pts[2])
|
||||
if minD>d2: return d2, pts[0],pts[2]
|
||||
else : return minD, p,q
|
||||
if minD > d2:
|
||||
return d2, pts[0], pts[2]
|
||||
else:
|
||||
return minD, p, q
|
||||
n2 = n//2
|
||||
mid = (pts[n2].x + pts[n2-1].x)/2
|
||||
s1 = pts[:n2]
|
||||
|
@ -110,6 +129,7 @@ def minDistance_nlogn(n_points):
|
|||
return minD, p, q
|
||||
return _min(sorted(n_points))
|
||||
|
||||
|
||||
def test(f=minDistance_n2):
|
||||
print('\ntest : ', f.__name__)
|
||||
begin = time()
|
||||
|
@ -117,6 +137,7 @@ def test(f=minDistance_n2):
|
|||
print('time : {:.6f} s'.format(time()-begin))
|
||||
print('result: {:.2f} {} {}\n'.format(minD, p, q))
|
||||
|
||||
|
||||
def genData(n, unique=True):
|
||||
upper = 1000000
|
||||
if unique:
|
||||
|
@ -124,7 +145,9 @@ def genData(n,unique=True):
|
|||
for i in range(n):
|
||||
points.add(point(randint(1, upper), randint(1, upper)))
|
||||
return list(points)
|
||||
else:return [point(randint(1,upper),randint(1,upper)) for i in range(n)]
|
||||
else:
|
||||
return [point(randint(1, upper), randint(1, upper)) for i in range(n)]
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
n = 1000
|
||||
|
|
|
@ -21,6 +21,7 @@ leetcode 1049: https://leetcode-cn.com/problems/last-stone-weight-ii/
|
|||
#######################################################################
|
||||
'''
|
||||
|
||||
|
||||
class Solution:
|
||||
def lastStoneWeightII(self, stones: List[int]) -> int:
|
||||
sm = sum(stones)
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#########################################################################
|
||||
'''
|
||||
|
||||
|
||||
def lcs(a, b):
|
||||
'''time: O(mn); space: O(mn)'''
|
||||
m, n = len(a), len(b)
|
||||
|
@ -24,6 +25,7 @@ def lcs(a,b):
|
|||
board[i+1][j+1] = board[i][1+j]
|
||||
return board[m][n]
|
||||
|
||||
|
||||
def lcs2(a, b):
|
||||
'''time: O(mn); space: O(m)'''
|
||||
m, n = len(a), len(b)
|
||||
|
@ -39,6 +41,7 @@ def lcs2(a,b):
|
|||
upperLevel = tmp
|
||||
return board[n]
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
a = 'ABCBDAB'
|
||||
b = 'BDCABA'
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
给两个整数数组 A 和 B ,返回两个数组中公共的、长度最长的子数组的长度。
|
||||
#######################################################################
|
||||
'''
|
||||
|
||||
|
||||
def findLength(A, B):
|
||||
n, m = len(A), len(B)
|
||||
dp = [[0]*(m+1) for i in range(n+1)]
|
||||
|
|
|
@ -17,17 +17,20 @@
|
|||
( including the original length if possible)
|
||||
'''
|
||||
|
||||
|
||||
def count(n, prices):
|
||||
def best(cur):
|
||||
# note that copying the list or create a new list in the following new_stripes codes
|
||||
if cur in values: return values[cur],stripes[cur]
|
||||
if cur in values:
|
||||
return values[cur], stripes[cur]
|
||||
maxPrice = 0
|
||||
new_stripes = []
|
||||
for i, j in prices.items():
|
||||
if i <= cur:
|
||||
p, tmp = best(cur-i)
|
||||
if maxPrice < p+j:
|
||||
new_stripes = tmp+[i] # if the list is not copyed, create a new list, don't use append
|
||||
# if the list is not copyed, create a new list, don't use append
|
||||
new_stripes = tmp+[i]
|
||||
maxPrice = p+j
|
||||
values[cur] = maxPrice
|
||||
stripes[cur] = new_stripes
|
||||
|
@ -37,9 +40,9 @@ def count(n,prices):
|
|||
return best(n)
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
li = [(1,1),(2,5),(3,8),(4,9),(5,10),(6,17),(7,17),(8,20),(9,24),(10,30)]
|
||||
li = [(1, 1), (2, 5), (3, 8), (4, 9), (5, 10),
|
||||
(6, 17), (7, 17), (8, 20), (9, 24), (10, 30)]
|
||||
prices = {i: j for i, j in li}
|
||||
n = 40
|
||||
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
leetcode-cn 877: https://leetcode-cn.com/problems/stone-game/
|
||||
#######################################################################
|
||||
'''
|
||||
|
||||
|
||||
def stoneGame(li):
|
||||
'''li: list, len(li)%2==0, sum(li)%2==1'''
|
||||
def f(p,q):
|
||||
|
|
|
@ -9,18 +9,23 @@
|
|||
# Description:
|
||||
#########################################################################
|
||||
*/
|
||||
class Solution {
|
||||
class Solution
|
||||
{
|
||||
public:
|
||||
map<Node*, Node*> st;
|
||||
Node *cloneGraph(Node *node){
|
||||
Node *cloneGraph(Node *node)
|
||||
{
|
||||
Node* ret = new Node(node->val, vector<Node*>());
|
||||
st[node] = ret;
|
||||
|
||||
for (auto x : node->neighbors) {
|
||||
auto p = st.find(x);
|
||||
|
||||
if (p == st.end()) {
|
||||
ret->neighbors.push_back(cloneGraph(x));
|
||||
} else ret->neighbors.push_back(p->second);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#######################################################################
|
||||
'''
|
||||
|
||||
|
||||
class Solution:
|
||||
def longestStrChain(self, words: List[str]) -> int:
|
||||
def isAdj(s1, s2):
|
||||
|
@ -67,4 +68,3 @@ class Solution:
|
|||
for nd in lenDic[lens[i]]:
|
||||
ans = max(ans, dfs(nd))
|
||||
return ans
|
||||
|
||||
|
|
|
@ -23,8 +23,11 @@ def isBipartite(self, graph):
|
|||
self.node = graph
|
||||
self.color = {i: None for i in range(n)}
|
||||
return all(self.dfs(i, True) for i in range(n) if self.color[i] is None)
|
||||
|
||||
|
||||
def dfs(self, n, col=True):
|
||||
if self.color[n] is None:
|
||||
self.color[n] = col
|
||||
return all(self.dfs(i, not col) for i in self.node[n])
|
||||
else:return col==self.color[n]
|
||||
else:
|
||||
return col == self.color[n]
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#######################################################################
|
||||
'''
|
||||
|
||||
|
||||
def fastPow(a, n):
|
||||
'''a^n'''
|
||||
rst = 1
|
||||
|
@ -21,6 +22,7 @@ def fastPow(a,n):
|
|||
a *= a
|
||||
return rst
|
||||
|
||||
|
||||
def fastMul(a, b):
|
||||
'''a*b'''
|
||||
rst = 0
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#######################################################################
|
||||
'''
|
||||
|
||||
|
||||
def fib(n):
|
||||
"""Calculates the nth Fibonacci number"""
|
||||
mat, p = (1, 1, 1, 0), n-2
|
||||
|
@ -18,6 +19,8 @@ def fib(n):
|
|||
mat = (0, 1, 1, -1), 2-n
|
||||
li = matrix_pow((0, 1, 1, -1), 1-n)
|
||||
return li[0]+li[1]
|
||||
|
||||
|
||||
def matrix_pow(mat, n):
|
||||
ans = (1, 0, 0, 1) # element matrix
|
||||
while n > 0:
|
||||
|
@ -27,6 +30,7 @@ def matrix_pow(mat,n):
|
|||
mat = matrix_mul(mat, mat)
|
||||
return ans
|
||||
|
||||
|
||||
def matrix_mul(a, b):
|
||||
'''a,b are four-item tuple, represent matrix [[a[0],a[1]],[a[2],a[3]]]'''
|
||||
return a[0]*b[0]+a[1]*b[2], a[0]*b[1]+a[1]*b[3], a[2]*b[0]+a[3]*b[2], a[2]*b[1]+a[3]*b[3]
|
||||
|
|
|
@ -23,6 +23,7 @@ eg
|
|||
'''
|
||||
from nega import nega
|
||||
|
||||
|
||||
def addNegaBin(arr1: list, arr2: list) -> list:
|
||||
if len(arr1) < len(arr2):
|
||||
arr1, arr2 = arr2, arr1
|
||||
|
@ -47,6 +48,7 @@ def addNegaBin(arr1: list, arr2: list) -> list:
|
|||
arr1.pop(0)
|
||||
return arr1
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
while 1:
|
||||
print("input q to quit or input x1 x2: ")
|
||||
|
|
|
@ -10,8 +10,11 @@
|
|||
#########################################################################
|
||||
'''
|
||||
|
||||
|
||||
def covert(s, basefrom=10, baseto=2):
|
||||
return d2n(n2d(s, basefrom), baseto)
|
||||
|
||||
|
||||
def n2d(s, base=16):
|
||||
''' num of base_n(n<36) to decimal'''
|
||||
dic = {chr(i+ord('0')): i for i in range(10)}
|
||||
|
@ -26,6 +29,7 @@ def n2d(s,base=16):
|
|||
rst = dic[i]+rst*base
|
||||
return rst
|
||||
|
||||
|
||||
def d2n(n, base=16):
|
||||
''' num of base_n(n<36) to decimal'''
|
||||
dic = {i: chr(i+ord('0')) for i in range(10)}
|
||||
|
@ -39,7 +43,6 @@ def d2n(n,base=16):
|
|||
return ''.join(rst[::-1])
|
||||
|
||||
|
||||
|
||||
'''
|
||||
>>> n2d(str(d2n(4001)))
|
||||
4001
|
||||
|
|
|
@ -9,10 +9,13 @@
|
|||
# Description:
|
||||
#########################################################################
|
||||
'''
|
||||
|
||||
|
||||
def nega(n: int, base=-2: int)->: list:
|
||||
'''return list of num, the first is the highest digit'''
|
||||
if base > -2:
|
||||
raise Exception(f"[Error]: invalid base: {base}, base should be no more than -2")
|
||||
raise Exception(
|
||||
f"[Error]: invalid base: {base}, base should be no more than -2")
|
||||
ans = []
|
||||
while n:
|
||||
k = n % base
|
||||
|
|
|
@ -17,17 +17,20 @@ from factor import factor
|
|||
from collections import Counter
|
||||
from functools import reduce
|
||||
from operator import mul
|
||||
|
||||
|
||||
def phi(n):
|
||||
st = set(factor(n))
|
||||
return round(reduce(mul, (1-1/p for p in st), n))
|
||||
|
||||
|
||||
def sigma(n):
|
||||
ct = Counter(factor(n))
|
||||
return reduce(mul, (round((p**(ct[p]+1)-1)/(p-1)) for p in ct), 1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
while 1:
|
||||
n = int(input('n: '))
|
||||
print('phi(n):', phi(n))
|
||||
print('sigma(n):', sigma(n))
|
||||
|
||||
|
|
|
@ -15,18 +15,23 @@ from random import randint
|
|||
from isPrime import isPrime
|
||||
from gcd import gcd
|
||||
|
||||
|
||||
def factor(n):
|
||||
'''pollard's rho algorithm'''
|
||||
if n<1:raise Exception('[Error]: {} is less than 1'.format(n))
|
||||
if n==1: return []
|
||||
if isPrime(n):return [n]
|
||||
if n < 1:
|
||||
raise Exception('[Error]: {} is less than 1'.format(n))
|
||||
if n == 1:
|
||||
return []
|
||||
if isPrime(n):
|
||||
return [n]
|
||||
fact = 1
|
||||
cycle_size = 2
|
||||
x = x_fixed = 2
|
||||
c = randint(1, n)
|
||||
while fact == 1:
|
||||
for i in range(cycle_size):
|
||||
if fact>1:break
|
||||
if fact > 1:
|
||||
break
|
||||
x = (x*x+c) % n
|
||||
if x == x_fixed:
|
||||
c = randint(1, n)
|
||||
|
@ -35,6 +40,8 @@ def factor(n):
|
|||
cycle_size *= 2
|
||||
x_fixed = x
|
||||
return factor(fact)+factor(n//fact)
|
||||
|
||||
|
||||
def fact(n):
|
||||
f = 2
|
||||
ret = []
|
||||
|
@ -43,7 +50,8 @@ def fact(n):
|
|||
ret.append(f)
|
||||
n//f
|
||||
f += 1
|
||||
if n>1:ret.append(n)
|
||||
if n > 1:
|
||||
ret.append(n)
|
||||
return ret
|
||||
|
||||
|
||||
|
|
|
@ -11,23 +11,28 @@
|
|||
#######################################################################
|
||||
'''
|
||||
|
||||
|
||||
def gcd(a, b):
|
||||
while b != 0:
|
||||
a, b = b, a % b
|
||||
return a
|
||||
|
||||
|
||||
def lcm(a, b):
|
||||
return int(a*b/gcd(a, b))
|
||||
|
||||
|
||||
def xgcd(a, b):
|
||||
'''return gcd(a,b), x,y where ax+by=gcd(a,b)'''
|
||||
if b==0:return a,1,0
|
||||
if b == 0:
|
||||
return a, 1, 0
|
||||
g, x, y = xgcd(b, a % b)
|
||||
return g, y, x-a//b*y
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
while 1:
|
||||
a = int(input('a: '))
|
||||
b = int(input('b: '))
|
||||
print('gcd :', gcd(a, b))
|
||||
print('xgcd:', xgcd(a, b))
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#######################################################################
|
||||
'''
|
||||
|
||||
|
||||
def hammingDistance(a, b):
|
||||
if isinstance(a, int):
|
||||
n = a ^ b
|
||||
|
@ -28,10 +29,12 @@ def hammingDistance(a,b):
|
|||
ret += i == j
|
||||
return ret+abs(n-m)
|
||||
|
||||
|
||||
def totalHammingDistance(lst):
|
||||
'''return sum of any two items(num or lst( str)) in lst'''
|
||||
length = len(lst)
|
||||
if length ==0:return 0
|
||||
if length == 0:
|
||||
return 0
|
||||
if isinstance(lst[0], int):
|
||||
bits = [0] * len(bin(max(lst)))
|
||||
for n in lst:
|
||||
|
|
|
@ -22,6 +22,7 @@ def quickMulMod(a,b,m):
|
|||
a = (a+a) % m
|
||||
return ret
|
||||
|
||||
|
||||
def quickPowMod(a, b, m):
|
||||
'''a^b %m, quick, O(logn)'''
|
||||
ret = 1
|
||||
|
@ -41,7 +42,8 @@ def isPrime(n,t=5):
|
|||
if n < 2:
|
||||
print('[Error]: {} can\'t be classed with prime or composite'.format(n))
|
||||
return
|
||||
if n==2: return True
|
||||
if n == 2:
|
||||
return True
|
||||
d = n-1
|
||||
r = 0
|
||||
while d % 2 == 0:
|
||||
|
@ -54,14 +56,17 @@ def isPrime(n,t=5):
|
|||
a = randint(2, n-2)
|
||||
tested.add(a)
|
||||
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):
|
||||
x = quickMulMod(x, x, n)
|
||||
if x==n-1:break
|
||||
if x == n-1:
|
||||
break
|
||||
else:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
'''
|
||||
we shouldn't use Fermat's little theory
|
||||
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
|
||||
'''
|
||||
|
||||
class primeSieve:
|
||||
'''sieve of Eratosthenes, It will be more efficient when judging many times'''
|
||||
primes = [2,3,5,7,11,13]
|
||||
def isPrime(self,x):
|
||||
if x<=primes[-1]:
|
||||
return twoDivideFind(x,self.primes)
|
||||
while x>self.primes[-1]:
|
||||
left = self.primes[-1]
|
||||
right = (left+1)**2
|
||||
lst = []
|
||||
for i in range(left,right):
|
||||
for j in self.primes:
|
||||
if i%j==0:break
|
||||
else:lst.append(i)
|
||||
self.primes+=lst
|
||||
return twoDivideFind(x,lst)
|
||||
def nPrime(n):
|
||||
'''return the n-th prime'''
|
||||
i=n-len(self.primes)
|
||||
last = self.primes[-1]
|
||||
for _ in range(i):
|
||||
while 1:
|
||||
last +=2
|
||||
for p in self.primes:
|
||||
if last%p==0:
|
||||
break
|
||||
else:
|
||||
self.primes.append(last)
|
||||
break
|
||||
return self.primes[n-1]
|
||||
|
||||
def twoDivideFind(x, li):
|
||||
a, b = 0, len(li)
|
||||
while a <= b:
|
||||
mid = (a+b)//2
|
||||
if li[mid]<x:a=mid+1
|
||||
elif li[mid]>x: b= mid-1
|
||||
else:return mid
|
||||
if li[mid] < x:
|
||||
a = mid+1
|
||||
elif li[mid] > x:
|
||||
b = mid-1
|
||||
else:
|
||||
return mid
|
||||
return -1
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
n = 100
|
||||
print('prime numbers below', n)
|
||||
|
|
|
@ -18,11 +18,13 @@ from euler import phi
|
|||
from isPrime import isPrime
|
||||
from factor import factor
|
||||
|
||||
|
||||
def ind(m, g):
|
||||
''' mod m ,primary root g -> {n:indg n}'''
|
||||
return {j:i for i in range(m-1) \
|
||||
return {j: i for i in range(m-1)
|
||||
for j in range(m) if (g**i-j) % m == 0}
|
||||
|
||||
|
||||
def gs(m, num=100):
|
||||
'''return list of m's primary roots below num'''
|
||||
p = phi(m)
|
||||
|
@ -30,25 +32,31 @@ def gs(m,num=100):
|
|||
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)]
|
||||
|
||||
|
||||
def minG(m):
|
||||
p = phi(m)
|
||||
mp = factor(p)
|
||||
checkLst = [p//i for i in mp]
|
||||
i = 2
|
||||
while 1:
|
||||
if all((i**n-1)%m !=0 for n in checkLst):return i
|
||||
if all((i**n-1) % m != 0 for n in checkLst):
|
||||
return i
|
||||
i += 1
|
||||
|
||||
|
||||
class solve:
|
||||
def __init__(self, equ=None):
|
||||
self.linearPat = re.compile(r'\s*(\d+)\s*--\s*(\d+)[\s\(]*mod\s*(\d+)')
|
||||
self.sol = []
|
||||
#self.m = m
|
||||
#self.ind_mp = ind(m,minG(m))
|
||||
|
||||
def noSol(self):
|
||||
print('equation {equ} has no solution'.format(equ=self.equ))
|
||||
|
||||
def error(self):
|
||||
print("Error! The divisor m must be postive integer")
|
||||
|
||||
def solveLinear(self, a, b, m):
|
||||
'''ax--b(mod m): solve linear equation with one unknown
|
||||
return ([x1,x2,...],m)
|
||||
|
@ -63,19 +71,23 @@ class solve:
|
|||
sols = [(sol+i*m0) % m for i in range(g)]
|
||||
print('{}x--{}(mod {}), solution: {} mod {}'.format(a, b, m, sols, m))
|
||||
return (sols, m)
|
||||
|
||||
def check(self, a, b, m):
|
||||
if m <= 0:
|
||||
self.error()
|
||||
return None
|
||||
if a<0:a,b=-a,-b ## important
|
||||
if b<0:b+= -b//m * m
|
||||
if a < 0:
|
||||
a, b = -a, -b # important
|
||||
if b < 0:
|
||||
b += -b//m * m
|
||||
return a, b, m
|
||||
|
||||
def solveHigh(self, a, n, b, m):
|
||||
''' ax^n -- b (mod m) ind_mp is a dict of m's {n: indg n}'''
|
||||
ind_mp = ind(m, minG(m))
|
||||
tmp = ind_mp[b] - ind_mp[a]
|
||||
if tmp < 0:tmp+=m
|
||||
if tmp < 0:
|
||||
tmp += m
|
||||
sol = self.solveLinear(n, tmp, phi(m))
|
||||
re_mp = {j: i for i, j in ind_mp.items()}
|
||||
sols = [re_mp[i] for i in sol[0]]
|
||||
|
@ -95,7 +107,8 @@ class solve:
|
|||
if mp[m][0]*b != mp[m][1]*a:
|
||||
self.noSol()
|
||||
return
|
||||
else:mp[m] = (a,b)
|
||||
else:
|
||||
mp[m] = (a, b)
|
||||
product = 1
|
||||
for i in mp.keys():
|
||||
product *= i
|
||||
|
@ -111,6 +124,7 @@ class solve:
|
|||
sol = [i % product for i in sol]
|
||||
print('final solution: {} mod {}'.format(sol, product))
|
||||
return sol, product
|
||||
|
||||
def __call__(self):
|
||||
s = input('输入同余方程,用--代表同于号,形如3--5(mod 7)代表3x模7同余于5')
|
||||
li = self.linearPat.findall(s)
|
||||
|
|
56
math/numberTheory/sievePrime.py
Normal file
56
math/numberTheory/sievePrime.py
Normal 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)
|
|
@ -29,6 +29,7 @@ from operator import mul
|
|||
X = sympy.Symbol('x')
|
||||
point = namedtuple('point', ['x', 'y'])
|
||||
|
||||
|
||||
class interplotion:
|
||||
def __init__(self, points):
|
||||
self.points = [point(x, y) for x, y in points]
|
||||
|
@ -41,9 +42,12 @@ class interplotion:
|
|||
qs = [li[0].y]
|
||||
|
||||
def quoDiff(begin, end):
|
||||
if begin == end:return li[begin].y
|
||||
q = (quoDiff(begin+1,end)-quoDiff(begin,end-1))/(li[end].x-li[begin].x)
|
||||
if begin == a:qs.append(q)
|
||||
if begin == end:
|
||||
return li[begin].y
|
||||
q = (quoDiff(begin+1, end)-quoDiff(begin, end-1)) / \
|
||||
(li[end].x-li[begin].x)
|
||||
if begin == a:
|
||||
qs.append(q)
|
||||
return q
|
||||
|
||||
quoDiff(a, b)
|
||||
|
@ -52,12 +56,14 @@ class interplotion:
|
|||
poly += q*base
|
||||
base *= X-li[i].x
|
||||
return poly, base*qs[-1]
|
||||
|
||||
def lagrange(self, points=None):
|
||||
xs = None
|
||||
if points is None:
|
||||
xs = self.xs
|
||||
points = self.points
|
||||
else: xs =[x for x,y in points]
|
||||
else:
|
||||
xs = [x for x, y in points]
|
||||
product = reduce(mul, [X-x for x in xs], 1)
|
||||
poly = 0
|
||||
for x, y in points:
|
||||
|
@ -67,7 +73,8 @@ class interplotion:
|
|||
return poly
|
||||
|
||||
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
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
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
|
||||
t = y.free_symbols
|
||||
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.\
|
||||
Maybe this function havsn't zeropoint\n".format(ct))
|
||||
return li, val
|
||||
if abs(x-x0)<epsilon:return li,vals
|
||||
if abs(x-x0) < epsilon:
|
||||
return li, vals
|
||||
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
|
||||
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
|
||||
x0, x1 = float(x0), float(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.\
|
||||
Maybe this function havsn't zeropoint\n".format(ct))
|
||||
return li, vals
|
||||
if abs(x0-x1)<epsilon:return li,vals
|
||||
if abs(x0-x1) < epsilon:
|
||||
return li, vals
|
||||
x0 = x
|
||||
|
||||
|
||||
|
@ -79,7 +83,8 @@ def solveNonlinearEquations(funcs:[sympy.core],init_dic:dict,epsilon:float=0.001
|
|||
ct = 0
|
||||
while 1:
|
||||
ys = np.array([f.subs(init_dic) for f in funcs], dtype='float')
|
||||
mat = np.matrix([[i.diff(x).subs(init_dic) for x in li] for i in funcs ],dtype = 'float')
|
||||
mat = np.matrix([[i.diff(x).subs(init_dic) for x in li]
|
||||
for i in funcs], dtype='float')
|
||||
delt = np.linalg.solve(mat, -ys)
|
||||
for i, j in enumerate(delt):
|
||||
init_dic[li[i]] += j
|
||||
|
@ -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.\
|
||||
Maybe this function havsn't zeropoint\n".format(ct))
|
||||
return init_dic
|
||||
if sqrt(sum(i**2 for i in delta.values()))<epsilon:return init_dic
|
||||
if sqrt(sum(i**2 for i in delta.values())) < epsilon:
|
||||
return init_dic
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
@ -97,11 +103,9 @@ if __name__ =='__main__':
|
|||
res, res2 = newton(x**5-9, 2, 0.01)
|
||||
print(res, res2)
|
||||
|
||||
|
||||
res, res2 = secant(x**3-3*x-2, 1, 3, 1e-3)
|
||||
print(res, res2)
|
||||
|
||||
|
||||
funcs = [x**2+y**2-1, x**3-y]
|
||||
init = {x: 0.8, y: 0.6}
|
||||
res_dic = solveNonlinearEquations(funcs, init, 0.001)
|
||||
|
|
|
@ -20,11 +20,10 @@
|
|||
************************************************************************'''
|
||||
|
||||
|
||||
|
||||
|
||||
import re
|
||||
import numpy as np
|
||||
|
||||
|
||||
|
||||
def solveConflitEqualtion(A, y):
|
||||
'''solve equation like this: Av = y,
|
||||
A:m*n v:n*1 y:m*1
|
||||
|
@ -37,6 +36,7 @@ def solveConflitEqualtion(A,y):
|
|||
print(ata)
|
||||
return np.linalg.solve(ata, A.T*y) # note that is numpy.linalg.solve
|
||||
|
||||
|
||||
def solveLinear(point, index):
|
||||
y = [[i[1]] 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)]
|
||||
print('phi(x) = ', ' + '.join(items))
|
||||
|
||||
|
||||
def handleInput(s=None, y=None):
|
||||
# numPt = re.compile (r'\d*\.{0,1}\d+')
|
||||
if not s: s = input('input matrix A:m*n //m>=n\n')
|
||||
if not s:
|
||||
s = input('input matrix A:m*n //m>=n\n')
|
||||
s = s.replace(' ', '')
|
||||
li = re.findall(r'(\[(\d+)(,(\d+))+\])', s)
|
||||
li = [parseLst(i[0]) for i in li]
|
||||
if not y:y = input('input a vector y:n*1\n')
|
||||
if not y:
|
||||
y = input('input a vector y:n*1\n')
|
||||
y = parseLst(y)
|
||||
print('Equation: Av = y:')
|
||||
|
||||
|
@ -70,6 +73,8 @@ def handleInput(s=None,y=None):
|
|||
print('result v is as follows: ')
|
||||
res = solveConflitEqualtion(li, y)
|
||||
print(res)
|
||||
|
||||
|
||||
def parseLst(s):
|
||||
s = s.strip('[]')
|
||||
li = s.split(',')
|
||||
|
|
|
@ -19,6 +19,9 @@
|
|||
> Created Time: 2018-04-20 08:32
|
||||
************************************************************************'''
|
||||
|
||||
|
||||
|
||||
|
||||
import numpy as np
|
||||
def getLU(A):
|
||||
'''doolittle : A = LU,
|
||||
|
@ -26,7 +29,8 @@ def getLU(A):
|
|||
U is in up-triangle form
|
||||
'''
|
||||
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])
|
||||
U = np.zeros([m, m])
|
||||
|
@ -37,7 +41,8 @@ def getLU(A):
|
|||
for i in range(1, m):
|
||||
for j in range(i, m):
|
||||
U[i, j] = A[i, j] - sum(L[i, k]*U[k, j] for k in range(i))
|
||||
L[j,i] = (A[j,i] - sum(L[j,k]*U[k,i] for k in range(i)))/U[i,i]
|
||||
L[j, i] = (A[j, i] - sum(L[j, k]*U[k, i]
|
||||
for k in range(i)))/U[i, i]
|
||||
print(L)
|
||||
print(U)
|
||||
return L, U
|
||||
|
@ -46,14 +51,19 @@ def getLU(A):
|
|||
def gauss_prior_elimination(A):
|
||||
'''using guass elimination,get up_trianglge form of A'''
|
||||
m, n = A.shape
|
||||
if m!=n:raise Exception("[Error]: matrix is not inversable")
|
||||
B = np.matrix(A,dtype=float) # necessary,otherwise when the dtype of A is int, then it will be wrong
|
||||
if m != n:
|
||||
raise Exception("[Error]: matrix is not inversable")
|
||||
# necessary,otherwise when the dtype of A is int, then it will be wrong
|
||||
B = np.matrix(A, dtype=float)
|
||||
for i in range(m-1):
|
||||
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()
|
||||
if mx==0: raise Exception("[Error]: matrix is not inversable")
|
||||
if mx == 0:
|
||||
raise Exception("[Error]: matrix is not inversable")
|
||||
pos = i+col.argmax()
|
||||
if pos != i : B[[pos,i],:] = B[[i,pos],:] # note how to swap cols/rows
|
||||
if pos != i:
|
||||
B[[pos, i], :] = B[[i, pos], :] # note how to swap cols/rows
|
||||
B[i, :] = 1/mx*B[i, :]
|
||||
for j in range(i+1, m):
|
||||
# print(B)
|
||||
|
@ -61,6 +71,7 @@ def gauss_prior_elimination(A):
|
|||
print(B)
|
||||
return B
|
||||
|
||||
|
||||
def solveDown(A, b):
|
||||
'''A is a matrix in down-triangle form'''
|
||||
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]
|
||||
return sol
|
||||
|
||||
|
||||
def solveUp(A, b):
|
||||
'''A is a matrix in up-triangle form'''
|
||||
sol = np.zeros(b.shape)
|
||||
n = b.shape[0]
|
||||
for i in range(n-1, -1, -1):
|
||||
sol[i,0] = (b[i,0]-sum(A[i,j]*sol[j,0] for j in range(n-1,i,-1)))/A[i,i]
|
||||
sol[i, 0] = (b[i, 0]-sum(A[i, j]*sol[j, 0]
|
||||
for j in range(n-1, i, -1)))/A[i, i]
|
||||
return sol
|
||||
|
||||
|
||||
def doolittle(A, b):
|
||||
L, U = getLU(A)
|
||||
y = solveDown(L, b)
|
||||
|
@ -82,6 +97,8 @@ def doolittle(A,b):
|
|||
print(y)
|
||||
print(x)
|
||||
return x
|
||||
|
||||
|
||||
def ldlt(A, b):
|
||||
L, U = getLU(A)
|
||||
D = np.diag(np.diag(U))
|
||||
|
@ -93,6 +110,8 @@ def ldlt(A,b):
|
|||
x = np.linalg.solve(L.T, y)
|
||||
print(x, "x")
|
||||
return x
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
A = np.matrix([[10, 5, 0, 0],
|
||||
[2, 2, 1, 0],
|
||||
|
@ -115,4 +134,3 @@ if __name__ == '__main__':
|
|||
b = np.matrix([[4],[6],[5]])
|
||||
doolittle(A,b)
|
||||
'''
|
||||
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
''' mbinary
|
||||
#########################################################################
|
||||
# File : numerical_differential.py
|
||||
# Author: mbinary
|
||||
# Mail: zhuheqin1@gmail.com
|
||||
# Blog: https://mbinary.xyz
|
||||
# Github: https://github.com/mbinary
|
||||
# Created Time: 2018-10-02 21:14
|
||||
# Description:
|
||||
#########################################################################
|
||||
'''
|
||||
|
||||
|
|
@ -24,8 +24,9 @@
|
|||
#########################################################################
|
||||
|
||||
|
||||
|
||||
import numpy as np
|
||||
|
||||
|
||||
def trapezoidal(a, b, h, fs):
|
||||
'''梯形积分公式'''
|
||||
xs = [i for i in np.arange(a, b+h, h)]
|
||||
|
@ -55,13 +56,15 @@ def romberg(a,b,f,epcilon):
|
|||
h /= 2
|
||||
k += 1
|
||||
lst2 = []
|
||||
lst2.append((lst1[0]+h*2*sum(f(a+(2*i-1)*h) for i in range(1,2**(k-2)+1)))/2)
|
||||
lst2.append((lst1[0]+h*2*sum(f(a+(2*i-1)*h)
|
||||
for i in range(1, 2**(k-2)+1)))/2)
|
||||
for j in range(0, k-1):
|
||||
lst2.append(lst2[j]+(lst2[j]-lst1[j])/(4**(j+1)-1))
|
||||
delta = abs(lst2[-1]-lst1[-1])
|
||||
lst1 = lst2
|
||||
print(lst1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
a, b, h = 0.6, 1.8, 0.2
|
||||
fs = [5.7, 4.6, 3.5, 3.7, 4.9, 5.2, 5.5]
|
||||
|
|
|
@ -21,18 +21,25 @@
|
|||
# Description:
|
||||
#########################################################################
|
||||
'''
|
||||
|
||||
|
||||
|
||||
|
||||
import numpy as np
|
||||
from operator import le, lt
|
||||
|
||||
def jacob(A, b, x, accuracy=None, times=6):
|
||||
''' Ax=b, arg x is the init val, times is the time of iterating'''
|
||||
A, b, x = np.matrix(A), np.matrix(b), np.matrix(x)
|
||||
n, m = A.shape
|
||||
if n!=m:raise Exception("Not square matrix: {A}".format(A=A))
|
||||
if b.shape !=( n,1) : raise Exception('Error: {b} must be {n} x1 in dimension'.format(b = b,n=n))
|
||||
if n != m:
|
||||
raise Exception("Not square matrix: {A}".format(A=A))
|
||||
if b.shape != (n, 1):
|
||||
raise Exception(
|
||||
'Error: {b} must be {n} x1 in dimension'.format(b=b, n=n))
|
||||
D = np.diag(np.diag(A))
|
||||
DI = np.zeros([n, n])
|
||||
for i in range(n):DI[i,i]= 1/D[i,i]
|
||||
for i in range(n):
|
||||
DI[i, i] = 1/D[i, i]
|
||||
R = np.eye(n) - DI * A
|
||||
g = DI * b
|
||||
print('R =\n{}'.format(R))
|
||||
|
@ -45,7 +52,8 @@ def jacob(A,b,x,accuracy=None,times=6):
|
|||
tmp = x-last
|
||||
last = x
|
||||
mx = max(abs(i) for i in tmp)
|
||||
if mx<accuracy:return x
|
||||
if mx < accuracy:
|
||||
return x
|
||||
x = R*x+g
|
||||
print('x{ct} =\n{x}'.format(ct=ct, x=x))
|
||||
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('isLimitd: {}'.format(isLimited(A)))
|
||||
return x
|
||||
|
||||
|
||||
def gauss_seidel(A, b, x, accuracy=None, times=6):
|
||||
''' Ax=b, arg x is the init val, times is the time of iterating'''
|
||||
A, b, x = np.matrix(A), np.matrix(b), np.matrix(x)
|
||||
n, m = A.shape
|
||||
if n!=m:raise Exception("Not square matrix: {A}".format(A=A))
|
||||
if b.shape !=( n,1) : raise Exception('Error: {b} must be {n} x1 in dimension'.format(b = b,n=n))
|
||||
if n != m:
|
||||
raise Exception("Not square matrix: {A}".format(A=A))
|
||||
if b.shape != (n, 1):
|
||||
raise Exception(
|
||||
'Error: {b} must be {n} x1 in dimension'.format(b=b, n=n))
|
||||
D = np. matrix(np.diag(np.diag(A)))
|
||||
L = np.tril(A) - D # L = np.triu(D.T) - D
|
||||
U = np.triu(A) - D
|
||||
|
@ -76,7 +89,8 @@ def gauss_seidel(A,b,x,accuracy=None,times=6):
|
|||
tmp = x-last
|
||||
last = x
|
||||
mx = max(abs(i) for i in tmp)
|
||||
if mx<accuracy:return x
|
||||
if mx < accuracy:
|
||||
return x
|
||||
x = S*x+f
|
||||
print('x{ct} =\n{x}'.format(ct=ct, x=x))
|
||||
else:
|
||||
|
@ -91,18 +105,25 @@ def isLimited(A,strict=False):
|
|||
'''通过检查A是否是[严格]对角优来判断迭代是否收敛, 即对角线上的值是否都大于对应行(或者列)的值'''
|
||||
diag = np.diag(A)
|
||||
op = lt if strict else le
|
||||
if op(A.max(axis=0),diag).all(): return True
|
||||
if op(A.max(axis=1), diag).all(): return True
|
||||
if op(A.max(axis=0), diag).all():
|
||||
return True
|
||||
if op(A.max(axis=1), diag).all():
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
testcase = []
|
||||
|
||||
|
||||
def test():
|
||||
for func, A, b, x, *args in testcase:
|
||||
acc = None
|
||||
times = 6
|
||||
if args != []:
|
||||
if isinstance(args[0],int):times = args[0]
|
||||
else : acc = args[0]
|
||||
if isinstance(args[0], int):
|
||||
times = args[0]
|
||||
else:
|
||||
acc = args[0]
|
||||
return func(A, b, x, acc, times)
|
||||
|
||||
|
||||
|
|
|
@ -19,26 +19,34 @@ from functools import reduce
|
|||
class obj():
|
||||
def __init__(self, data):
|
||||
self.data = np.array(data)
|
||||
|
||||
def __add__(self, x):
|
||||
data = x.data if self.__class__ == x.__class__ else x
|
||||
return self.__class__(self.data + data)
|
||||
|
||||
def __radd__(self, x):
|
||||
data = x.data if self.__class__ == x.__class__ else x
|
||||
return self.__class__(data + self.data)
|
||||
|
||||
def __iadd__(self, x):
|
||||
data = x.data if self.__class__ == x.__class__ else x
|
||||
self.data += data
|
||||
|
||||
def __mul__(self, x):
|
||||
data = x.data if self.__class__ == x.__class__ else x
|
||||
return self.__class__(self.data * data)
|
||||
|
||||
def __imul__(self, x):
|
||||
data = x.data if self.__class__ == x.__class__ else x
|
||||
self.data *= data
|
||||
|
||||
def __rmul__(self, x):
|
||||
data = x.data if self.__class__ == x.__class__ else x
|
||||
return self.__class__(data * self.data)
|
||||
|
||||
def __neg__(self):
|
||||
return neg(self)
|
||||
|
||||
def __abs__(self):
|
||||
return abs(self.data)
|
||||
'''
|
||||
|
@ -49,11 +57,14 @@ class obj():
|
|||
def data(self,s):
|
||||
self.data = s
|
||||
'''
|
||||
|
||||
def norm(self, n=0):
|
||||
'''the default is +oo norm'''
|
||||
absolute = abs(self.data)
|
||||
if n < 1 :return max(absolute)
|
||||
if n < 1:
|
||||
return max(absolute)
|
||||
return (sum(absolute**n))**(1/n)
|
||||
|
||||
def hasNorm(self):
|
||||
'''check norm's three necessary conditions:
|
||||
1. not neg
|
||||
|
@ -65,18 +76,22 @@ class obj():
|
|||
bl = reduce(and_, [self.norm(i) >= 0 for i in range(3)])
|
||||
if bl:
|
||||
n = randint(2, 100)
|
||||
bl = reduce(and_,[n*(self.norm(i))==(n*self).norm(i) for i in range(3)])
|
||||
bl = reduce(and_, [n*(self.norm(i)) == (n*self).norm(i)
|
||||
for i in range(3)])
|
||||
if bl:
|
||||
another = self*randint(2, 10)-randint(1, 100)
|
||||
return reduce(and_, [(another+self).norm(i) <= another.norm(i)+self.norm(i) for i in range(3)])
|
||||
return False
|
||||
|
||||
|
||||
class vector(obj):
|
||||
def __init__(self, arr):
|
||||
''' arr: iterable'''
|
||||
self.data = np.array(arr)
|
||||
|
||||
def innerProduct(self, x):
|
||||
return sum(self.data*x)
|
||||
|
||||
def outerProduct(self, x):
|
||||
pass
|
||||
|
||||
|
@ -104,8 +119,10 @@ class matrix(obj):
|
|||
def I(self,s):
|
||||
self.I = s
|
||||
'''
|
||||
|
||||
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)
|
||||
|
||||
def norm(self, n=0):
|
||||
|
@ -113,22 +130,27 @@ class matrix(obj):
|
|||
if n < 1:
|
||||
# max of one row sum
|
||||
return max([sum(i) for i in absolute])
|
||||
if n==1:return self.norm1()
|
||||
elif n==2:return self.norm2()
|
||||
if n == 1:
|
||||
return self.norm1()
|
||||
elif n == 2:
|
||||
return self.norm2()
|
||||
|
||||
def norm1(self):
|
||||
''' max of sum of cols'''
|
||||
absolute = abs(self.data)
|
||||
return max(absolute.sum(axis=0))
|
||||
|
||||
def norm2(self):
|
||||
''' max of sum of rows'''
|
||||
absolute = abs(self.data)
|
||||
return max(absolute.sum(axis=1))
|
||||
|
||||
def norm_f(self):
|
||||
return sum((self.data**2).sum(axis=1))**0.5
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
v1 = vector([1, -2, 3, 4])
|
||||
v2 = vector([0, 2, 0, 5])
|
||||
m1 = matrix([v1, v2, v2, v1])
|
||||
print([v1.norm(i) for i in range(3)])
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ void calFac(int n)
|
|||
{
|
||||
int i;
|
||||
fac[0] = 1;
|
||||
|
||||
for (i = 1; i <= n; i++) {
|
||||
fac[i] = i * fac[i - 1];
|
||||
}
|
||||
|
@ -27,17 +28,21 @@ void permute(int *arr,int n,int sum)
|
|||
/*sum表示全排列由小到大排序后的名次,从0 开始计数, 由名次求出 n位的排列存储到 arr 中*/
|
||||
int i, j, ct = 0, k, ct2;
|
||||
int flag[n];
|
||||
|
||||
for (i = 0; i < n; i++)flag[i] = 1;
|
||||
|
||||
for (i = n - 1; i >= 0; i--) {
|
||||
for (j = i; j >= 0; j--) {
|
||||
if (j * fac[i] <= sum) {
|
||||
ct2 = 0;
|
||||
|
||||
for (k = 0; k < n; ++k) {
|
||||
//printf("i%d j%d k%d\n",i,j,k);
|
||||
if (flag[k] == 1)ct2++;
|
||||
|
||||
if (ct2 > j)break;
|
||||
}
|
||||
|
||||
arr[ct++] = k;
|
||||
flag[k] = 0;
|
||||
sum -= j * fac[i];
|
||||
|
@ -50,6 +55,7 @@ void permute(int *arr,int n,int sum)
|
|||
void printArr(int *p, int n)
|
||||
{
|
||||
for (int i = 0; i < n; ++i)printf("%d, ", p[i]);
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
@ -57,11 +63,13 @@ int main()
|
|||
{
|
||||
int n = 5, arr[n];
|
||||
calFac(n);
|
||||
|
||||
for (int i = 0; i < 5; ++i)arr[i] = i;
|
||||
|
||||
for (int i = 0; i < fac[n]; ++i) {
|
||||
printArr(arr, n);
|
||||
permute(arr, n, i);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
''' mbinary
|
||||
#########################################################################
|
||||
# File : 8Astar.py
|
||||
# File : Astar.py
|
||||
# Author: mbinary
|
||||
# Mail: zhuheqin1@gmail.com
|
||||
# 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
|
||||
fac = [1, 1, 2, 6, 24, 120, 720, 5040, 40320]
|
||||
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],
|
||||
[4, 3, 2, 3, 2, 1, 2, 1, 0]]
|
||||
|
||||
|
||||
def cantor(s):
|
||||
sum = 0
|
||||
ls = len(s)
|
||||
for i in range(ls):
|
||||
count = 0
|
||||
for j in range(i+1, ls):
|
||||
if s[i] > s[j]: count +=1
|
||||
if s[i] > s[j]:
|
||||
count += 1
|
||||
sum += count*fac[lf-i-1]
|
||||
return sum
|
||||
|
||||
|
||||
que = []
|
||||
dir = {-3: 'u', 1: 'r', 3: 'd', -1: 'l'}
|
||||
|
||||
|
||||
class state:
|
||||
flag = True
|
||||
|
||||
def __init__(self, s, x, f, step=0, last=0):
|
||||
self.x = x
|
||||
self.s = list(s)
|
||||
|
@ -44,6 +51,7 @@ class state:
|
|||
self.path = []
|
||||
self.last = last
|
||||
self.f = f
|
||||
|
||||
def can(self):
|
||||
cans = [-1, 1, 3, -3]
|
||||
if self.last in cans:
|
||||
|
@ -57,6 +65,7 @@ class state:
|
|||
if self.x % 3 is 2:
|
||||
cans.remove(1)
|
||||
return cans
|
||||
|
||||
def move(self):
|
||||
cans = self.can()
|
||||
for i in cans:
|
||||
|
@ -67,7 +76,8 @@ class state:
|
|||
ct = cantor(s)
|
||||
if isVisited[ct] != 2:
|
||||
val = int(s[self.x])
|
||||
f = h[8][tmp] +h[val-1][self.x]-h[8][self.x]-h[val-1][tmp]+self.step+1
|
||||
f = h[8][tmp] + h[val-1][self.x] - \
|
||||
h[8][self.x]-h[val-1][tmp]+self.step+1
|
||||
new = state(s, tmp, f, self.step + 1, i)
|
||||
new.path = self.path + [dir[i]]
|
||||
if isVisited[ct] == 1:
|
||||
|
@ -75,21 +85,30 @@ class state:
|
|||
if mew.s == node.s:
|
||||
del que[i]
|
||||
break
|
||||
else:isVisited[ct] = 1
|
||||
else:
|
||||
isVisited[ct] = 1
|
||||
if que == []:
|
||||
que.append(new)
|
||||
continue
|
||||
for i, node in enumerate(que):
|
||||
if new.f <= node.f:
|
||||
que.insert(i, new)
|
||||
|
||||
|
||||
def solvable(s):
|
||||
reverse = 0
|
||||
for i in range(8):
|
||||
if s[i] is '9':continue
|
||||
if s[i] is '9':
|
||||
continue
|
||||
for j in range(i+1, 9):
|
||||
if s[i]>s[j]:reverse +=1
|
||||
if reverse % 2 is 0:return True
|
||||
else:return False
|
||||
if s[i] > s[j]:
|
||||
reverse += 1
|
||||
if reverse % 2 is 0:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
def getPath(s, index):
|
||||
f = 0
|
||||
for i, j in enumerate(s):
|
||||
|
@ -102,6 +121,8 @@ def getPath(s,index):
|
|||
if ct is 0:
|
||||
return cur.path
|
||||
cur.move()
|
||||
|
||||
|
||||
def info():
|
||||
print('input a 3x3 matrix in one line')
|
||||
print('from left to right,from up to down')
|
||||
|
@ -111,8 +132,10 @@ def info():
|
|||
print('1 2 3\n4 5 6\n7 8 x')
|
||||
print('print q to quit')
|
||||
|
||||
from random import shuffle
|
||||
|
||||
case = list('12345678x')
|
||||
|
||||
|
||||
def genCase():
|
||||
tmp = case.copy()
|
||||
shuffle(tmp)
|
||||
|
@ -124,6 +147,8 @@ def genCase():
|
|||
break
|
||||
tmp[index] = '9'
|
||||
return tmp, index
|
||||
|
||||
|
||||
def isValid(li):
|
||||
for i in '123456789':
|
||||
if not i in li:
|
||||
|
@ -131,6 +156,7 @@ def isValid(li):
|
|||
return False
|
||||
return True
|
||||
|
||||
|
||||
def run():
|
||||
while 1:
|
||||
print('\n\n'+'-'*10+'Game Begins' + '-'*10)
|
||||
|
@ -146,7 +172,8 @@ def run():
|
|||
li, index = genCase()
|
||||
if solvable(li):
|
||||
print(''.join(getPath(li, index)))
|
||||
else:print('unsolvable')
|
||||
else:
|
||||
print('unsolvable')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
|
@ -13,6 +13,7 @@ from bitarray import bitarray
|
|||
|
||||
import mmh3
|
||||
|
||||
|
||||
class bloomFilter(set):
|
||||
def __init__(self, size, hash_count):
|
||||
super(bloomFilter, self).__init__()
|
||||
|
@ -20,15 +21,19 @@ class bloomFilter(set):
|
|||
self.bits.setall(0)
|
||||
self.size = size
|
||||
self.hash_count = hash_count
|
||||
|
||||
def __len__(self):
|
||||
return self.size
|
||||
|
||||
def __iter__(self):
|
||||
return iter(self.bits)
|
||||
|
||||
def add(self, item):
|
||||
for i in range(self.hash_count):
|
||||
idx = mmh3.hash(item, i) % self.size
|
||||
self.bits[idx] = 1
|
||||
return self
|
||||
|
||||
def __contains__(self, item):
|
||||
idxs = [mmh3.hash(item, i) % self.size for i in range(self.hash_count)]
|
||||
return all([self.bits[i] == 1 for i in idxs])
|
||||
|
|
|
@ -15,6 +15,10 @@
|
|||
|
||||
设有n个任务由k个可并行工作的机器来完成,完成任务i需要时间为 。试设计一个算法找出完成这n个任务的最佳调度,使完成全部任务的时间最早。
|
||||
'''
|
||||
|
||||
|
||||
|
||||
|
||||
from time import time
|
||||
from functools import total_ordering
|
||||
@total_ordering
|
||||
|
@ -24,23 +28,32 @@ class record:
|
|||
nums = []
|
||||
self.nums = nums
|
||||
self.sum = sum(nums)
|
||||
|
||||
def append(self, x):
|
||||
self.nums.append(x)
|
||||
self.sum += x
|
||||
|
||||
def pop(self):
|
||||
x = self.nums.pop()
|
||||
self.sum -= x
|
||||
return x
|
||||
|
||||
def __repr__(self):
|
||||
return repr(self.nums)
|
||||
|
||||
def __lt__(self, r):
|
||||
return self.sum < r.sum
|
||||
|
||||
def __eq__(self, r):
|
||||
return self.sum == r.sum
|
||||
|
||||
def tolist(self):
|
||||
return self.nums.copy()
|
||||
|
||||
def __hash__(self):
|
||||
return self.sum
|
||||
|
||||
|
||||
def schedule(works, k):
|
||||
def backtrackSearch(i, lsts):
|
||||
nonlocal best, rst
|
||||
|
@ -55,11 +68,13 @@ def schedule(works,k):
|
|||
cur.append(works[i])
|
||||
backtrackSearch(i+1, lsts)
|
||||
cur.pop()
|
||||
|
||||
def findInitial(i, lst):
|
||||
nonlocal best
|
||||
if i == n:
|
||||
cost = max(lst)
|
||||
if best>cost:best = cost
|
||||
if best > cost:
|
||||
best = cost
|
||||
else:
|
||||
mn = lst[0]
|
||||
idx = 0
|
||||
|
@ -74,7 +89,6 @@ def schedule(works,k):
|
|||
findInitial(i+1, lst)
|
||||
lst[idx] -= works[i]
|
||||
|
||||
|
||||
n = len(works)
|
||||
print()
|
||||
print('machine Num:', n)
|
||||
|
@ -93,11 +107,13 @@ def schedule(works,k):
|
|||
print('schedule plan:', rst)
|
||||
return best, rst
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from random import randint
|
||||
schedule([47, 20, 28, 44, 21, 45, 30, 39, 28, 33], 3)
|
||||
schedule([98, 84, 50, 23, 32, 99, 22, 76, 72, 61, 81, 39, 76, 54, 37], 5)
|
||||
schedule([39,39,23,45,100,69,21,81,39,55,20,86,34,53,58,99,36,45,46],8)
|
||||
schedule([39, 39, 23, 45, 100, 69, 21, 81, 39, 55,
|
||||
20, 86, 34, 53, 58, 99, 36, 45, 46], 8)
|
||||
|
||||
'''
|
||||
machine Num: 19
|
||||
|
|
|
@ -12,6 +12,11 @@
|
|||
'''
|
||||
设有n件工作要分配给n个人去完成,将工作i分配给第j个人所需费用为c_ij 。试设计一个算法,为每个人分配1件不同的工作,并使总费用达到最小。
|
||||
'''
|
||||
|
||||
|
||||
|
||||
|
||||
import random
|
||||
def dispatch(mat):
|
||||
'''mat: matrix of c_ij'''
|
||||
def _util(i, arrange, cost):
|
||||
|
@ -35,7 +40,6 @@ def dispatch(mat):
|
|||
return total, rst
|
||||
|
||||
|
||||
import random
|
||||
if __name__ == '__main__':
|
||||
n = 10
|
||||
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('result: ', end='')
|
||||
print(dispatch(mat))
|
||||
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
from functools import total_ordering
|
||||
|
||||
|
||||
@total_ordering
|
||||
class node:
|
||||
def __init__(self, val, left=None, right=None):
|
||||
|
@ -19,28 +20,39 @@ class node:
|
|||
self.frequency = 1
|
||||
self.left = left
|
||||
self.right = right
|
||||
|
||||
def __lt__(self, x):
|
||||
return self.val < x.val
|
||||
|
||||
def __eq__(self, x):
|
||||
return self.val == x.val
|
||||
|
||||
def inc(self):
|
||||
self.val += 1
|
||||
|
||||
def dec(self):
|
||||
self.val -= 1
|
||||
|
||||
def incFreq(self):
|
||||
self.frequency += 1
|
||||
|
||||
def decFreq(self):
|
||||
self.frequency -= 1
|
||||
|
||||
|
||||
class binaryTree:
|
||||
def __init__(self, reverse=True):
|
||||
self.reverse = reverse
|
||||
self.data = None
|
||||
|
||||
def cmp(self, n1, n2):
|
||||
ret = 0
|
||||
if n1 < n2: ret=-1
|
||||
if n1 > n2: ret= 1
|
||||
if n1 < n2:
|
||||
ret = -1
|
||||
if n1 > n2:
|
||||
ret = 1
|
||||
return ret * -1 if self.reverse else ret
|
||||
|
||||
def addNode(self, nd):
|
||||
def _add(prt, chd):
|
||||
if self.cmp(prt, chd) == 0:
|
||||
|
@ -48,7 +60,8 @@ class binaryTree:
|
|||
return
|
||||
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:
|
||||
self.root = node(val)
|
||||
else:
|
||||
|
@ -56,6 +69,7 @@ class binaryTree:
|
|||
self.root.incfreq()
|
||||
else:
|
||||
cur = self.root
|
||||
|
||||
def build(self, lst):
|
||||
dic = {}
|
||||
for i in lst:
|
||||
|
@ -64,5 +78,3 @@ class binaryTree:
|
|||
else:
|
||||
dic[i] = node(i)
|
||||
self.data = list(dic.values())
|
||||
|
||||
|
||||
|
|
|
@ -11,16 +11,23 @@
|
|||
'''
|
||||
|
||||
from functools import partial
|
||||
|
||||
|
||||
class heap:
|
||||
def __init__(self, lst, reverse=False):
|
||||
self.data = heapify(lst, reverse)
|
||||
self.cmp = partial(lambda i,j,r:cmp(self.data[i],self.data[j],r),r= reverse)
|
||||
self.cmp = partial(lambda i, j, r: cmp(
|
||||
self.data[i], self.data[j], r), r=reverse)
|
||||
|
||||
def getTop(self):
|
||||
return self.data[0]
|
||||
|
||||
def __getitem__(self, idx):
|
||||
return self.data[idx]
|
||||
|
||||
def __bool__(self):
|
||||
return self.data != []
|
||||
|
||||
def popTop(self):
|
||||
ret = self.data[0]
|
||||
n = len(self.data)
|
||||
|
@ -46,14 +53,19 @@ class heap:
|
|||
|
||||
def cmp(n1, n2, reverse=False):
|
||||
fac = -1 if reverse else 1
|
||||
if n1 < n2: return -fac
|
||||
elif n1 > n2: return fac
|
||||
if n1 < n2:
|
||||
return -fac
|
||||
elif n1 > n2:
|
||||
return fac
|
||||
return 0
|
||||
|
||||
|
||||
def heapify(lst, reverse=False):
|
||||
for i in range(len(lst)):
|
||||
lst = one_heapify(lst, i, reverse)
|
||||
return lst
|
||||
|
||||
|
||||
def one_heapify(lst, cur, reverse=False):
|
||||
cur += 1
|
||||
while cur > 1:
|
||||
|
@ -64,6 +76,8 @@ def one_heapify(lst,cur,reverse = False):
|
|||
lst[prt], lst[chd] = lst[chd], lst[prt]
|
||||
cur = prt+1
|
||||
return lst
|
||||
|
||||
|
||||
def heapSort(lst, reverse=False):
|
||||
lst = lst.copy()
|
||||
hp = heap(lst, reverse)
|
||||
|
|
|
@ -12,12 +12,17 @@
|
|||
int partition(int *arr, int i, int j)
|
||||
{
|
||||
int pivot = arr[j], p = i, q = j;
|
||||
|
||||
while (p < q) {
|
||||
while (p < q && arr[p] <= pivot)++p;
|
||||
|
||||
if (p < q)arr[q--] = arr[p];
|
||||
|
||||
while (p < q && arr[q] > pivot)--q;
|
||||
|
||||
if (p < q)arr[p++] = arr[q];
|
||||
}
|
||||
|
||||
arr[p] = pivot;
|
||||
return p;
|
||||
}
|
||||
|
|
|
@ -11,6 +11,9 @@
|
|||
'''
|
||||
|
||||
|
||||
from time import time
|
||||
|
||||
|
||||
def quickSort(lst):
|
||||
'''A optimized version of Hoare partition'''
|
||||
|
||||
|
@ -31,7 +34,8 @@ def quickSort(lst):
|
|||
return a
|
||||
|
||||
def _sort(a, b):
|
||||
if a >= b: return
|
||||
if a >= b:
|
||||
return
|
||||
mid = (a + b) // 2
|
||||
# 三数取中值置于第一个作为 pivot
|
||||
if (lst[a] < lst[mid]) ^ (lst[b] < lst[mid]):
|
||||
|
@ -55,12 +59,14 @@ def quickSort2(lst):
|
|||
for i in range(a, b):
|
||||
if lst[i] <= pivot:
|
||||
j += 1
|
||||
if i != j: lst[i], lst[j] = lst[j], lst[i]
|
||||
if i != j:
|
||||
lst[i], lst[j] = lst[j], lst[i]
|
||||
lst[j + 1], lst[b] = lst[b], lst[j + 1]
|
||||
return j + 1
|
||||
|
||||
def _sort(a, b):
|
||||
if a >= b: return
|
||||
if a >= b:
|
||||
return
|
||||
mid = (a + b) // 2
|
||||
# 三数取中值置于第一个作为 pivot
|
||||
if (lst[a] < lst[mid]) ^ (lst[b] < lst[mid]):
|
||||
|
@ -84,7 +90,8 @@ def quickSort3(lst):
|
|||
for i in range(a, b):
|
||||
if lst[i] <= pivot:
|
||||
j += 1
|
||||
if i != j: lst[i], lst[j] = lst[j], lst[i]
|
||||
if i != j:
|
||||
lst[i], lst[j] = lst[j], lst[i]
|
||||
lst[j + 1], lst[b] = lst[b], lst[j + 1]
|
||||
return j + 1
|
||||
|
||||
|
@ -104,9 +111,6 @@ def quickSort3(lst):
|
|||
return lst
|
||||
|
||||
|
||||
from time import time
|
||||
|
||||
|
||||
def timer(func, lst, n=100):
|
||||
t = time()
|
||||
for i in range(n):
|
||||
|
|
|
@ -10,6 +10,11 @@
|
|||
#########################################################################
|
||||
'''
|
||||
|
||||
from random import randint
|
||||
from quickSort import quickSort
|
||||
from time import time
|
||||
|
||||
|
||||
def radixSort(lst, radix=10):
|
||||
ls = [[] for i in range(radix)]
|
||||
mx = max(lst)
|
||||
|
@ -22,6 +27,7 @@ def radixSort(lst,radix=10):
|
|||
ls = [[] for i in range(radix)]
|
||||
return lst
|
||||
|
||||
|
||||
def countSort(lst, mn, mx):
|
||||
mark = [0]*(mx-mn+1)
|
||||
for i in lst:
|
||||
|
@ -31,9 +37,7 @@ def countSort(lst,mn,mx):
|
|||
ret += [n+mn]*i
|
||||
return ret
|
||||
|
||||
from quickSort import quickSort
|
||||
from time import time
|
||||
from random import randint
|
||||
|
||||
def timer(funcs, span, num=1000000):
|
||||
lst = [randint(0, span) for i in range(num)]
|
||||
print('range({}), {} items'.format(span, num))
|
||||
|
|
|
@ -11,16 +11,21 @@
|
|||
'''
|
||||
|
||||
from random import randint
|
||||
|
||||
|
||||
def select(lst, i):
|
||||
lst = lst.copy()
|
||||
|
||||
def partition(a, b):
|
||||
pivot = lst[a]
|
||||
while a < b:
|
||||
while a<b and lst[b]>pivot: b-=1
|
||||
while a < b and lst[b] > pivot:
|
||||
b -= 1
|
||||
if a < b:
|
||||
lst[a] = lst[b]
|
||||
a += 1
|
||||
while a<b and lst[a]<pivot: a+=1
|
||||
while a < b and lst[a] < pivot:
|
||||
a += 1
|
||||
if a < b:
|
||||
lst[b] = lst[a]
|
||||
b -= 1
|
||||
|
@ -28,7 +33,8 @@ def select(lst,i):
|
|||
return a
|
||||
|
||||
def _select(a, b):
|
||||
if a>=b: return lst[a]
|
||||
if a >= b:
|
||||
return lst[a]
|
||||
# randomized select
|
||||
n = randint(a, b)
|
||||
lst[a], lst[n] = lst[n], lst[a]
|
||||
|
@ -37,7 +43,8 @@ def select(lst,i):
|
|||
return _select(a, pos-1)
|
||||
elif pos < i:
|
||||
return _select(pos+1, b)
|
||||
else:return lst[pos]
|
||||
else:
|
||||
return lst[pos]
|
||||
return _select(0, len(lst)-1)
|
||||
|
||||
|
||||
|
@ -46,4 +53,5 @@ if __name__ =='__main__':
|
|||
st = sorted(lst)
|
||||
for i in range(10):
|
||||
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)))
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#########################################################################
|
||||
'''
|
||||
|
||||
|
||||
def shellSort(s, gaps=None):
|
||||
if gaps is None:
|
||||
gaps = [127, 63, 31, 15, 7, 3, 1]
|
||||
|
@ -24,6 +25,7 @@ def shellSort(s,gaps=None):
|
|||
s[cur] = num
|
||||
return s
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from random import randint
|
||||
import sys
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#########################################################################
|
||||
'''
|
||||
|
||||
|
||||
def getPrefixFunc(s):
|
||||
'''return the list of prefix function of s'''
|
||||
length = 0
|
||||
|
@ -30,6 +31,7 @@ def getPrefixFunc(s):
|
|||
length = ret[length-1]
|
||||
return ret
|
||||
|
||||
|
||||
def findAll(s, p):
|
||||
pre = getPrefixFunc(p)
|
||||
i = j = 0
|
||||
|
@ -43,12 +45,17 @@ def findAll(s,p):
|
|||
ret.append(i-j)
|
||||
j = pre[j-1]
|
||||
else:
|
||||
if j==0: i+=1
|
||||
else: j = pre[j-1]
|
||||
if j == 0:
|
||||
i += 1
|
||||
else:
|
||||
j = pre[j-1]
|
||||
return ret
|
||||
|
||||
|
||||
def randStr(n=3):
|
||||
return [randint(ord('a'), ord('z')) for i in range(n)]
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from random import randint
|
||||
s = randStr(50)
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#########################################################################
|
||||
'''
|
||||
|
||||
|
||||
class Solution:
|
||||
def longestPalindrome(self, s):
|
||||
"""
|
||||
|
@ -27,12 +28,13 @@ class Solution:
|
|||
ct[cur] = 1
|
||||
while s2[cur-ct[cur]] == s2[cur+ct[cur]]:
|
||||
ct[cur] += 1
|
||||
if cur+ct[cur] > mid+ct[mid]:mid = cur
|
||||
if cur+ct[cur] > mid+ct[mid]:
|
||||
mid = cur
|
||||
mx = max(ct)
|
||||
idxs = [i for i, j in enumerate(ct) if j == mx]
|
||||
p = idxs[0]
|
||||
for i in idxs:
|
||||
if s2[i]=='#':p = i
|
||||
if s2[i] == '#':
|
||||
p = i
|
||||
rst = s2[p-mx+1:p+mx].replace('#', '')
|
||||
return rst
|
||||
|
|
@ -18,15 +18,16 @@ class markov:
|
|||
def __init__(self, txt):
|
||||
self.words = self.clean(txt)
|
||||
self.dic = self.getDic(self.words)
|
||||
|
||||
def clean(self, text):
|
||||
text = text.replace("\n", " ");
|
||||
text = text.replace("\"", "");
|
||||
text = text.replace("\n", " ")
|
||||
text = text.replace("\"", "")
|
||||
|
||||
# 保证每个标点符号都和前面的单词在一起
|
||||
# 这样不会被剔除,保留在马尔可夫链中
|
||||
punctuation = [',', '.', ';', ':']
|
||||
for symbol in punctuation:
|
||||
text = text.replace(symbol, symbol+" ");
|
||||
text = text.replace(symbol, symbol+" ")
|
||||
|
||||
return re.split(' +', text)
|
||||
|
||||
|
@ -38,17 +39,22 @@ class markov:
|
|||
dic[words[i-1]] = {words[i]: 1}
|
||||
elif words[i] not in dic[words[i-1]]:
|
||||
dic[words[i-1]][words[i]] = 1
|
||||
else: dic[words[i-1]][words[i]] +=1
|
||||
else:
|
||||
dic[words[i-1]][words[i]] += 1
|
||||
return dic
|
||||
|
||||
def getSum(self, dic):
|
||||
if '%size' not in dic:
|
||||
dic['%size'] = sum(list(dic.values()))
|
||||
return dic['%size']
|
||||
|
||||
def nextWord(self, word):
|
||||
k = randint(1, self.getSum(self.dic[word]))
|
||||
for i, j in self.dic[word].items():
|
||||
k -= j
|
||||
if k<=0:return i
|
||||
if k <= 0:
|
||||
return i
|
||||
|
||||
def genSentence(self, begin='I', length=30):
|
||||
li = [begin]
|
||||
nextWord = begin
|
||||
|
|
|
@ -27,6 +27,8 @@ When the window is no longer valid, start expanding again using the right pointe
|
|||
'''
|
||||
|
||||
from collections import defaultdict
|
||||
|
||||
|
||||
class Solution:
|
||||
def minWindow(self, s: str, t: str) -> str:
|
||||
def expand(j, lacked, dic):
|
||||
|
@ -38,6 +40,7 @@ class Solution:
|
|||
dic[s[j]] += 1
|
||||
j += 1
|
||||
return j
|
||||
|
||||
def contract(left, right):
|
||||
for i in range(left, right):
|
||||
dic[s[i]] -= 1
|
||||
|
|
|
@ -11,14 +11,21 @@
|
|||
#########################################################################
|
||||
'''
|
||||
|
||||
|
||||
def isPrime(x):
|
||||
for i in range(2, int(x**0.5)+1):
|
||||
if x%i==0:return False
|
||||
if x % i == 0:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def getPrime(x):
|
||||
'''return a prime which is bigger than x'''
|
||||
for i in range(x, 2*x):
|
||||
if isPrime(i):return i
|
||||
if isPrime(i):
|
||||
return i
|
||||
|
||||
|
||||
def findAll(s, p):
|
||||
'''s: string p: pattern'''
|
||||
dic = {}
|
||||
|
@ -30,13 +37,16 @@ def findAll(s,p):
|
|||
d += 1
|
||||
sm = 0
|
||||
for c in p:
|
||||
if c not in dic:return []
|
||||
if c not in dic:
|
||||
return []
|
||||
sm = sm*d+dic[c]
|
||||
|
||||
ret = []
|
||||
cur = 0
|
||||
for i in range(m): cur=cur*d + dic[s[i]]
|
||||
if cur==sm:ret.append(0)
|
||||
for i in range(m):
|
||||
cur = cur*d + dic[s[i]]
|
||||
if cur == sm:
|
||||
ret.append(0)
|
||||
tmp = n-m
|
||||
q = getPrime(m)
|
||||
cur = cur % q
|
||||
|
@ -48,9 +58,11 @@ def findAll(s,p):
|
|||
ret.append(i-m+1)
|
||||
return ret
|
||||
|
||||
|
||||
def randStr(n=3):
|
||||
return [randint(ord('a'), ord('z')) for i in range(n)]
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from random import randint
|
||||
s = randStr(50)
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#########################################################################
|
||||
'''
|
||||
|
||||
|
||||
def rotate(s, k, right=False):
|
||||
def reverse(a, b):
|
||||
while a < b:
|
||||
|
@ -31,14 +32,15 @@ def rotate(s,k,right=False):
|
|||
return s
|
||||
|
||||
|
||||
|
||||
def rotate2(s, k, right=False):
|
||||
def swap(a, b, c):
|
||||
for i in range(c):
|
||||
s[a+i], s[b+i] = s[b+i], s[a+i]
|
||||
|
||||
def _rot(pl, pr):
|
||||
''' swap s[pl,pr) , s[pr:]'''
|
||||
if pr==n:return
|
||||
if pr == n:
|
||||
return
|
||||
if pr-pl <= n-pr:
|
||||
swap(pl, pr, pr-pl)
|
||||
_rot(pr, 2*pr-pl)
|
||||
|
@ -51,10 +53,10 @@ def rotate2(s,k,right=False):
|
|||
return s
|
||||
|
||||
|
||||
|
||||
def rotate3(s, k, right=False):
|
||||
def gcd(a, b):
|
||||
if b==0:return a
|
||||
if b == 0:
|
||||
return a
|
||||
return gcd(b, a % b)
|
||||
|
||||
n = len(s)
|
||||
|
@ -72,7 +74,8 @@ def rotate3(s,k,right=False):
|
|||
|
||||
def test():
|
||||
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)
|
||||
print('result', rst)
|
||||
print()
|
||||
|
|
|
@ -12,13 +12,14 @@
|
|||
'''
|
||||
|
||||
|
||||
|
||||
def getPos(pattern):
|
||||
dic = {}
|
||||
for i, j in enumerate(pattern[::-1]):
|
||||
if j not in dic:
|
||||
dic[j] = i
|
||||
return dic
|
||||
|
||||
|
||||
def find(s, p):
|
||||
dic = getPos(p)
|
||||
ps = pp = 0
|
||||
|
@ -29,16 +30,20 @@ def find(s,p):
|
|||
ps, pp = ps+1, pp+1
|
||||
else:
|
||||
idx = ps + np-pp
|
||||
if idx >=ns:return -1
|
||||
if idx >= ns:
|
||||
return -1
|
||||
ch = s[idx]
|
||||
if ch in dic:
|
||||
ps += dic[ch]+1-pp
|
||||
else:
|
||||
ps = idx+1
|
||||
pp = 0
|
||||
if pp==np:return ps-np
|
||||
if pp == np:
|
||||
return ps-np
|
||||
else:
|
||||
return -1
|
||||
|
||||
|
||||
def findAll(s, p):
|
||||
ns = len(s)
|
||||
np = len(p)
|
||||
|
@ -47,7 +52,8 @@ def findAll(s,p):
|
|||
while s:
|
||||
print(s, p)
|
||||
tmp = find(s, p)
|
||||
if tmp==-1: break
|
||||
if tmp == -1:
|
||||
break
|
||||
ret.append(i+tmp)
|
||||
end = tmp+np
|
||||
i += end
|
||||
|
@ -55,10 +61,10 @@ def findAll(s,p):
|
|||
return ret
|
||||
|
||||
|
||||
|
||||
def randStr(n=3):
|
||||
return [randint(ord('a'), ord('z')) for i in range(n)]
|
||||
|
||||
|
||||
def test(n):
|
||||
s = randStr(n)
|
||||
p = randStr(3)
|
||||
|
@ -70,6 +76,8 @@ def test(n):
|
|||
print(n1, n2, str_p, str_s)
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from random import randint
|
||||
n = 1000
|
||||
|
|
|
@ -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/
|
||||
|
||||
|
||||
def isMatch(self, s, p):
|
||||
"""
|
||||
:type s: str
|
||||
|
|
|
@ -17,6 +17,8 @@ from translate import Translator as TR
|
|||
FORMULA = re.compile(r'\${1,2}(?P<formula>.+?)\${1,2}', re.DOTALL)
|
||||
Chinese = re.compile(u"(?P<chinese>[\u4e00-\u9fa5]+)")
|
||||
API = 'https://latex.codecogs.com/gif.latex?'
|
||||
|
||||
|
||||
def codecog(f):
|
||||
if os.path.exists(f) and f.endswith('.md'):
|
||||
with open(f) as fp:
|
||||
|
@ -26,18 +28,23 @@ def codecog(f):
|
|||
else:
|
||||
s = re.sub(FORMULA, covert, f)
|
||||
print(s)
|
||||
|
||||
|
||||
def covert(matched):
|
||||
s = matched.group('formula').strip('$ ')
|
||||
s = re.sub(Chinese, zh2en, s)
|
||||
s = re.sub(r'\r+|\n+|\\n', ' ', s)
|
||||
s = re.sub(' +', '&space;', s)
|
||||
return '![]({})'.format(API+s)
|
||||
|
||||
|
||||
def zh2en(txt):
|
||||
s = txt.group('chinese').strip()
|
||||
tran = TR(to_lang='en', from_lang='zh')
|
||||
en = tran.translate(s)
|
||||
return re.sub(' +', '-', en)
|
||||
|
||||
|
||||
def handle(path):
|
||||
if os.path.isdir(path):
|
||||
for p, ds, fs in os.walk(path):
|
||||
|
@ -47,6 +54,7 @@ def handle(path):
|
|||
else:
|
||||
codecog(path)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
args = sys.argv[1:]
|
||||
if not args:
|
||||
|
|
|
@ -17,7 +17,8 @@ from config import README
|
|||
parser = ArgumentParser()
|
||||
|
||||
parser.add_argument('-p', '--path', default='.', help='path to walk')
|
||||
parser.add_argument('-f','--fileinclude',action='store_true',default=True,help='if has, list files and dirs, else only dirs')
|
||||
parser.add_argument('-f', '--fileinclude', action='store_true',
|
||||
default=True, help='if has, list files and dirs, else only dirs')
|
||||
parser.add_argument('-d', '--depth', type=int, default=2)
|
||||
# 获取参数
|
||||
args = parser.parse_args()
|
||||
|
|
|
@ -15,10 +15,13 @@ import sys
|
|||
import time
|
||||
from config import HEAD
|
||||
count = 0
|
||||
|
||||
|
||||
def handleFile(path):
|
||||
global count
|
||||
head = getHead(path)
|
||||
if head =='': return
|
||||
if head == '':
|
||||
return
|
||||
with open(path, 'r', encoding='utf8', errors='ignore') as f:
|
||||
s = f.read()
|
||||
if 'mbinary' in s:
|
||||
|
@ -29,10 +32,12 @@ def handleFile(path):
|
|||
with open(path, 'w') as f:
|
||||
f.write(head+s)
|
||||
|
||||
|
||||
def getHead(path):
|
||||
name = os.path.basename(path)
|
||||
# skip self or hidden file
|
||||
if name == os.path.basename(__file__) or name[0]=='.': return ''
|
||||
if name == os.path.basename(__file__) or name[0] == '.':
|
||||
return ''
|
||||
suf = name[name.rfind('.')+1:]
|
||||
begin = end = ''
|
||||
if suf == 'py':
|
||||
|
@ -41,18 +46,24 @@ def getHead(path):
|
|||
begin, end = '/*', '*/'
|
||||
elif suf == 'sh':
|
||||
begin = end = '#'
|
||||
else:return ''
|
||||
else:
|
||||
return ''
|
||||
timeStamp = time.localtime(os.stat(path).st_ctime)
|
||||
ctime = time.strftime('%Y-%m-%d %H:%M', timeStamp)
|
||||
return HEAD.format(begin=begin, end=end, ctime=ctime, name=name)
|
||||
|
||||
|
||||
def handleDir(dirPath):
|
||||
gen = os.walk(dirPath)
|
||||
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__':
|
||||
works = sys.argv[1:]
|
||||
if works==[] : works = ['.']
|
||||
if works == []:
|
||||
works = ['.']
|
||||
for one in works:
|
||||
if not os.path.exists(one):
|
||||
print('[PathError]: {one} not exists'.format(one=one))
|
||||
|
|
|
@ -17,7 +17,8 @@ from argparse import ArgumentParser
|
|||
parser = ArgumentParser()
|
||||
|
||||
parser.add_argument('-p', '--path', default='.', help='path to walk')
|
||||
parser.add_argument('-f','--fileinclude',action='store_true',help='if has, list files and dirs, else only dirs')
|
||||
parser.add_argument('-f', '--fileinclude', action='store_true',
|
||||
help='if has, list files and dirs, else only dirs')
|
||||
parser.add_argument('-d', '--depth', type=int, default=2)
|
||||
# 获取参数
|
||||
args = parser.parse_args()
|
||||
|
@ -25,8 +26,11 @@ FILE = args.fileinclude
|
|||
PATH = args.path
|
||||
DEPTH = args.depth
|
||||
|
||||
|
||||
def mklink(path):
|
||||
return '* [{name}]({path})'.format(name=os.path.basename(path), path=path)
|
||||
|
||||
|
||||
def clean(paths):
|
||||
ret = []
|
||||
for path in paths:
|
||||
|
@ -35,14 +39,18 @@ def clean(paths):
|
|||
ret.append(path)
|
||||
return ret
|
||||
|
||||
|
||||
def tree(path='.', depth=2, showfile=False):
|
||||
li = []
|
||||
if os.path.isdir(path):li = os.listdir(path)
|
||||
else:li=[path]
|
||||
if os.path.isdir(path):
|
||||
li = os.listdir(path)
|
||||
else:
|
||||
li = [path]
|
||||
items = [os.path.join(path, i) for i in li if not i.startswith('.')]
|
||||
items = clean(items)
|
||||
items = sorted(items)
|
||||
if not showfile: items = [i for i in items if os.path.isdir(i)]
|
||||
if not showfile:
|
||||
items = [i for i in items if os.path.isdir(i)]
|
||||
if depth == 1:
|
||||
return [mklink(path)] + [' '*4 + mklink(i) for i in items]
|
||||
else:
|
||||
|
@ -50,5 +58,6 @@ def tree(path='.',depth=2,showfile=False):
|
|||
ret = [' '*4 + li for ul in uls for li in ul]
|
||||
return [mklink(path)] + ret
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print('\n'.join(tree(PATH, DEPTH, FILE)))
|
||||
|
|
Loading…
Reference in New Issue
Block a user