fix few details, qs

This commit is contained in:
Mari Wahl 2014-08-26 10:18:50 -04:00
parent b50dc5d69d
commit 249434957b
5 changed files with 102 additions and 134 deletions

Binary file not shown.

View File

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

View File

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

View File

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

View File

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