mirror of
https://github.com/autistic-symposium/master-algorithms-py.git
synced 2025-04-30 04:36:08 -04:00
fix few details, qs
This commit is contained in:
parent
b50dc5d69d
commit
249434957b
Binary file not shown.
@ -43,7 +43,6 @@ def reversing_words_setence_logic(string1):
|
|||||||
reverser(string1)
|
reverser(string1)
|
||||||
p = 0
|
p = 0
|
||||||
start = 0
|
start = 0
|
||||||
final = []
|
|
||||||
while p < len(string1):
|
while p < len(string1):
|
||||||
if string1[p] == u"\u0020":
|
if string1[p] == u"\u0020":
|
||||||
reverser(string1,start,p-1)
|
reverser(string1,start,p-1)
|
||||||
|
@ -4,28 +4,63 @@ __author__ = "Mari Wahl"
|
|||||||
__email__ = "marina.w4hl@gmail.com"
|
__email__ = "marina.w4hl@gmail.com"
|
||||||
|
|
||||||
|
|
||||||
''' Some examples of how to implement Merge Sort in Python
|
|
||||||
|
''' Some examples of how to implement Merge Sort in Python.
|
||||||
--> RUNTIME: WORST/BEST/AVERAGE Is O(nlogn)
|
--> RUNTIME: WORST/BEST/AVERAGE Is O(nlogn)
|
||||||
--> space complexity is O(n) for arrays
|
--> space complexity is O(n) for arrays
|
||||||
--> not in place, good for large arrays
|
--> in general not in place, good for large arrays
|
||||||
>>> seq = [3, 5, 2, 6, 8, 1, 0, 3, 5, 6, 2]
|
--> In the case of two arrays: we can merge two arrays using the merge function from the merge sort
|
||||||
>>> merge_sort(seq) == sorted(seq)
|
--> we can do this for files too, merging each two
|
||||||
True
|
|
||||||
>>> seq2 = [3, 3, 3, 3, 3, 3, 3, 3]
|
1) If we can modify the arrays (pop) we can use:
|
||||||
>>> merge_sort(seq2) == sorted(seq2)
|
def merge(left, right):
|
||||||
True
|
if not left or not right: return left or right # nothing to be merged
|
||||||
>>> seq3 = []
|
result = []
|
||||||
>>> merge_sort(seq3) == sorted(seq3)
|
while left and right:
|
||||||
True
|
if left[-1] >= right[-1]:
|
||||||
|
result.append(left.pop())
|
||||||
|
else:
|
||||||
|
result.append(right.pop())
|
||||||
|
result.reverse()
|
||||||
|
return (left or right) + result
|
||||||
|
|
||||||
|
|
||||||
|
2) If we can't modify or we want to in place, we need two pointers:
|
||||||
|
>>> l1 = [1, 2, 3, 4, 5, 6, 7]
|
||||||
|
>>> l2 = [2, 4, 5, 8]
|
||||||
|
>>> merge(l1, l2)
|
||||||
|
[1, 2, 2, 3, 4, 4, 5, 5, 6, 7, 8]
|
||||||
|
|
||||||
|
|
||||||
|
3) For example, in the case we have a big array filled 0s in the end, and another array with the size of the number of 0s:
|
||||||
|
>>> l1 = [1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0]
|
||||||
|
>>> l2 = [2, 4, 5, 8]
|
||||||
|
>>> merge_two_arrays_inplace(l1, l2)
|
||||||
|
[1, 2, 2, 3, 4, 4, 5, 5, 6, 7, 8]
|
||||||
|
|
||||||
|
|
||||||
|
4) If we want to merge sorted files (and we have plenty of RAM to load all files):
|
||||||
|
>>> list_files = ['1.dat', '2.dat', '3.dat']
|
||||||
|
>>> merge_files(list_files)
|
||||||
|
[1, 1, 2, 3, 3, 3, 4, 5, 5, 5, 6, 7, 8]
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
|
The typical example...
|
||||||
|
"""
|
||||||
|
|
||||||
def merge_sort(seq):
|
def merge_sort(seq):
|
||||||
if len(seq) <= 1: return seq
|
if len(seq) < 2:
|
||||||
|
return seq
|
||||||
mid = len(seq)//2
|
mid = len(seq)//2
|
||||||
lft, rgt = seq[:mid], seq[mid:]
|
lft, rgt = seq[:mid], seq[mid:]
|
||||||
if len(lft)>1: lft = merge_sort(lft)
|
if len(lft)>1:
|
||||||
if len(rgt)>1: rgt = merge_sort(rgt)
|
lft = merge_sort(lft)
|
||||||
|
if len(rgt)>1:
|
||||||
|
rgt = merge_sort(rgt)
|
||||||
|
|
||||||
res = []
|
res = []
|
||||||
while lft and rgt:
|
while lft and rgt:
|
||||||
@ -38,11 +73,6 @@ def merge_sort(seq):
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
def test_merge_sort():
|
|
||||||
seq = [3, 5, 2, 6, 8, 1, 0, 3, 5, 6, 2]
|
|
||||||
assert(merge_sort(seq) == sorted(seq))
|
|
||||||
print('Tests passed!')
|
|
||||||
|
|
||||||
|
|
||||||
'''
|
'''
|
||||||
We could also divide this sort into two parts, separating
|
We could also divide this sort into two parts, separating
|
||||||
@ -50,17 +80,18 @@ def test_merge_sort():
|
|||||||
'''
|
'''
|
||||||
|
|
||||||
def merge_sort_sep(seq):
|
def merge_sort_sep(seq):
|
||||||
if len(seq) < 2 : return seq # base case
|
if len(seq) < 2 :
|
||||||
|
return seq # base case
|
||||||
mid = len(seq)//2
|
mid = len(seq)//2
|
||||||
left, right = None, None # we could have declared the arrays here,
|
left = merge_sort(seq[:mid])
|
||||||
# but this would allocate unecessary extra space
|
right = merge_sort(seq[mid:]) # notice that mid is included!
|
||||||
if seq[:mid]: left = merge_sort(seq[:mid])
|
|
||||||
if seq[mid:]: right = merge_sort(seq[mid:]) # notice that mid is included!
|
|
||||||
|
|
||||||
return merge(left, right) # merge iteratively
|
return merge(left, right) # merge iteratively
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def merge(left, right):
|
def merge(left, right):
|
||||||
if not left or not right: return left or right # nothing to be merged
|
if not left or not right:
|
||||||
|
return left or right # nothing to be merged
|
||||||
result = []
|
result = []
|
||||||
i, j = 0, 0
|
i, j = 0, 0
|
||||||
while i < len(left) and j < len(right):
|
while i < len(left) and j < len(right):
|
||||||
@ -70,14 +101,14 @@ def merge(left, right):
|
|||||||
else:
|
else:
|
||||||
result.append(right[j])
|
result.append(right[j])
|
||||||
j += 1
|
j += 1
|
||||||
if left[i:] : result.extend(left[i:]) # REMEMBER TO TO ENXTEND NOT APPEND
|
if left[i:] : result.extend(left[i:]) # REMEMBER TO EXTEND, NOT APPEND
|
||||||
if right[j:] : result.extend(right[j:])
|
if right[j:] : result.extend(right[j:])
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
''' The two following merge functions are O(2n)=O(n) and O(n) respectively. They
|
''' The following merge functions is O(2n) and
|
||||||
illustrate many features in Python that '''
|
illustrate many features in Python that '''
|
||||||
def merge_2n(left, right):
|
def merge_2n(left, right):
|
||||||
if not left or not right: return left or right # nothing to be merged
|
if not left or not right: return left or right # nothing to be merged
|
||||||
@ -92,9 +123,52 @@ def merge_2n(left, right):
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
''' Merge two arrays in place '''
|
||||||
|
def merge_two_arrays_inplace(l1, l2):
|
||||||
|
if not l1 or not l2: return l1 or l2 # nothing to be merged
|
||||||
|
p2 = len(l2) - 1
|
||||||
|
p1 = len(l1) - len(l2) - 1
|
||||||
|
p12 = len(l1) - 1
|
||||||
|
while p2 >= 0 and p1 >= 0:
|
||||||
|
item_to_be_merged = l2[p2]
|
||||||
|
item_bigger_array = l1[p1]
|
||||||
|
if item_to_be_merged < item_bigger_array:
|
||||||
|
l1[p12] = item_bigger_array
|
||||||
|
p1 -= 1
|
||||||
|
else:
|
||||||
|
l1[p12] = item_to_be_merged
|
||||||
|
p2 -= 1
|
||||||
|
p12 -= 1
|
||||||
|
return l1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
''' Merge sort for files '''
|
||||||
|
def merge_files(list_files):
|
||||||
|
result = []
|
||||||
|
final = []
|
||||||
|
for filename in list_files:
|
||||||
|
aux = []
|
||||||
|
with open(filename, 'r') as file:
|
||||||
|
for line in file:
|
||||||
|
aux.append(int(line))
|
||||||
|
result.append(aux)
|
||||||
|
final.extend(result.pop())
|
||||||
|
for l in result:
|
||||||
|
final = merge(l, final)
|
||||||
|
return final
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def test_merge_sort():
|
||||||
|
seq = [3, 5, 2, 6, 8, 1, 0, 3, 5, 6, 2]
|
||||||
|
seq_sorted = sorted(seq)
|
||||||
|
assert(merge_sort(seq) == seq_sorted)
|
||||||
|
assert(merge_sort_sep(seq) == seq_sorted)
|
||||||
|
print('Tests passed!')
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
test_merge_sort()
|
test_merge_sort()
|
||||||
|
@ -1,96 +0,0 @@
|
|||||||
#!/usr/bin/python
|
|
||||||
|
|
||||||
__author__ = "Mari Wahl"
|
|
||||||
__email__ = "marina.w4hl@gmail.com"
|
|
||||||
|
|
||||||
''' --> In the case of two arrays: we can merge two arrays using the merge function from the merge sort
|
|
||||||
--> we can do this for files too, merging each two
|
|
||||||
|
|
||||||
1) If we can modify the arrays (pop) we can use:
|
|
||||||
def merge(left, right):
|
|
||||||
if not left or not right: return left or right # nothing to be merged
|
|
||||||
result = []
|
|
||||||
while left and right:
|
|
||||||
if left[-1] >= right[-1]:
|
|
||||||
result.append(left.pop())
|
|
||||||
else:
|
|
||||||
result.append(right.pop())
|
|
||||||
result.reverse()
|
|
||||||
return (left or right) + result
|
|
||||||
|
|
||||||
|
|
||||||
2) If we can't modify or we want to in place, we need two pointers:
|
|
||||||
>>> l1 = [1, 2, 3, 4, 5, 6, 7]
|
|
||||||
>>> l2 = [2, 4, 5, 8]
|
|
||||||
>>> merge(l1, l2)
|
|
||||||
[1, 2, 2, 3, 4, 4, 5, 5, 6, 7, 8]
|
|
||||||
|
|
||||||
|
|
||||||
3) For example, in the case we have a big array filled 0s in the end, and another array with the size of the number of 0s:
|
|
||||||
>>> l1 = [1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0]
|
|
||||||
>>> l2 = [2, 4, 5, 8]
|
|
||||||
>>> merge_two_arrays_inplace(l1, l2)
|
|
||||||
[1, 2, 2, 3, 4, 4, 5, 5, 6, 7, 8]
|
|
||||||
|
|
||||||
|
|
||||||
4) If we want to merge sorted files (and we have plenty of RAM to load all files):
|
|
||||||
>>> list_files = ['1.dat', '2.dat', '3.dat']
|
|
||||||
>>> merge_files(list_files)
|
|
||||||
[1, 1, 2, 3, 3, 3, 4, 5, 5, 5, 6, 7, 8]
|
|
||||||
'''
|
|
||||||
|
|
||||||
def merge(left, right):
|
|
||||||
if not left or not right: return left or right # nothing to be merged
|
|
||||||
result = []
|
|
||||||
i, j = 0, 0
|
|
||||||
while i < len(left) and j < len(right):
|
|
||||||
if left[i] <= right[j]:
|
|
||||||
result.append(left[i])
|
|
||||||
i += 1
|
|
||||||
else:
|
|
||||||
result.append(right[j])
|
|
||||||
j += 1
|
|
||||||
if left[i:] : result.extend(left[i:]) # REMEMBER TO TO ENXTEND NOT APPEND
|
|
||||||
if right[j:] : result.extend(right[j:])
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def merge_two_arrays_inplace(l1, l2):
|
|
||||||
if not l1 or not l2: return l1 or l2 # nothing to be merged
|
|
||||||
p2 = len(l2) - 1
|
|
||||||
p1 = len(l1) - len(l2) - 1
|
|
||||||
p12 = len(l1) - 1
|
|
||||||
while p2 >= 0 and p1 >= 0:
|
|
||||||
item_to_be_merged = l2[p2]
|
|
||||||
item_bigger_array = l1[p1]
|
|
||||||
if item_to_be_merged < item_bigger_array:
|
|
||||||
l1[p12] = item_bigger_array
|
|
||||||
p1 -= 1
|
|
||||||
else:
|
|
||||||
l1[p12] = item_to_be_merged
|
|
||||||
p2 -= 1
|
|
||||||
p12 -= 1
|
|
||||||
return l1
|
|
||||||
|
|
||||||
|
|
||||||
def merge_files(list_files):
|
|
||||||
result = []
|
|
||||||
final = []
|
|
||||||
for filename in list_files:
|
|
||||||
aux = []
|
|
||||||
with open(filename, 'r') as file:
|
|
||||||
for line in file:
|
|
||||||
aux.append(int(line))
|
|
||||||
result.append(aux)
|
|
||||||
final.extend(result.pop())
|
|
||||||
for l in result:
|
|
||||||
final = merge(l, final)
|
|
||||||
return final
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
import doctest
|
|
||||||
doctest.testmod()
|
|
||||||
|
|
||||||
|
|
@ -25,16 +25,7 @@ __email__ = "marina.w4hl@gmail.com"
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
def quick_sort(seq):
|
|
||||||
if len(seq) < 2: return seq
|
|
||||||
pivot = sorted(seq[0], seq[len(seq)//2], seq[-1])[1]
|
|
||||||
print(pivot)
|
|
||||||
left = quick_sort([x for x in seq[1:] if x < pivot])
|
|
||||||
right = quick_sort([x for x in seq[1:] if x >= pivot])
|
|
||||||
return left + [pivot] + right
|
|
||||||
|
|
||||||
|
|
||||||
''' slightly different in the way we get the pivot'''
|
|
||||||
def quick_sort(seq):
|
def quick_sort(seq):
|
||||||
if len(seq) < 2 : return seq
|
if len(seq) < 2 : return seq
|
||||||
mid = len(seq)//2
|
mid = len(seq)//2
|
||||||
|
Loading…
x
Reference in New Issue
Block a user