mirror of
https://github.com/autistic-symposium/master-algorithms-py.git
synced 2025-04-29 20:26:07 -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)
|
||||
p = 0
|
||||
start = 0
|
||||
final = []
|
||||
while p < len(string1):
|
||||
if string1[p] == u"\u0020":
|
||||
reverser(string1,start,p-1)
|
||||
|
@ -4,28 +4,63 @@ __author__ = "Mari Wahl"
|
||||
__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)
|
||||
--> space complexity is O(n) for arrays
|
||||
--> not in place, good for large arrays
|
||||
>>> seq = [3, 5, 2, 6, 8, 1, 0, 3, 5, 6, 2]
|
||||
>>> merge_sort(seq) == sorted(seq)
|
||||
True
|
||||
>>> seq2 = [3, 3, 3, 3, 3, 3, 3, 3]
|
||||
>>> merge_sort(seq2) == sorted(seq2)
|
||||
True
|
||||
>>> seq3 = []
|
||||
>>> merge_sort(seq3) == sorted(seq3)
|
||||
True
|
||||
--> in general not in place, good for large arrays
|
||||
--> 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]
|
||||
'''
|
||||
|
||||
|
||||
|
||||
|
||||
"""
|
||||
The typical example...
|
||||
"""
|
||||
|
||||
def merge_sort(seq):
|
||||
if len(seq) <= 1: return seq
|
||||
if len(seq) < 2:
|
||||
return seq
|
||||
mid = len(seq)//2
|
||||
lft, rgt = seq[:mid], seq[mid:]
|
||||
if len(lft)>1: lft = merge_sort(lft)
|
||||
if len(rgt)>1: rgt = merge_sort(rgt)
|
||||
if len(lft)>1:
|
||||
lft = merge_sort(lft)
|
||||
if len(rgt)>1:
|
||||
rgt = merge_sort(rgt)
|
||||
|
||||
res = []
|
||||
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
|
||||
@ -50,17 +80,18 @@ def test_merge_sort():
|
||||
'''
|
||||
|
||||
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
|
||||
left, right = None, None # we could have declared the arrays here,
|
||||
# but this would allocate unecessary extra space
|
||||
if seq[:mid]: left = merge_sort(seq[:mid])
|
||||
if seq[mid:]: right = merge_sort(seq[mid:]) # notice that mid is included!
|
||||
|
||||
left = merge_sort(seq[:mid])
|
||||
right = merge_sort(seq[mid:]) # notice that mid is included!
|
||||
return merge(left, right) # merge iteratively
|
||||
|
||||
|
||||
|
||||
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 = []
|
||||
i, j = 0, 0
|
||||
while i < len(left) and j < len(right):
|
||||
@ -70,14 +101,14 @@ def merge(left, right):
|
||||
else:
|
||||
result.append(right[j])
|
||||
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:])
|
||||
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 '''
|
||||
def merge_2n(left, right):
|
||||
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__':
|
||||
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):
|
||||
if len(seq) < 2 : return seq
|
||||
mid = len(seq)//2
|
||||
|
Loading…
x
Reference in New Issue
Block a user