本节相对比较简单,以最基础的recursion介绍为主。
1 recursion programs
http://www.codeskulptor.org/#examples_recursion.py
2 recurrence relations
factorial(8) = 8 * factorial(7)
= 8 * (7 * factorial(6))
= 8 * (7 * (6 * factorial(5)))
= 8 * (7 * (6 * (5 * factorial(4))))
= 8 * (7 * (6 * (5 * (4 * factorial(3)))))
= 8 * (7 * (6 * (5 * (4 * (3 * factorial(2))))))
= 8 * (7 * (6 * (5 * (4 * (3 * (2 * factorial(1)))))))
= 8 * (7 * (6 * (5 * (4 * (3 * (2 * (1 * factorial(0))))))))
= 8 * (7 * (6 * (5 * (4 * (3 * (2 * (1 * 1)))))))
= 8 * (7 * (6 * (5 * (4 * (3 * (2 * 1))))))
= 8 * (7 * (6 * (5 * (4 * (3 * 2)))))
= 8 * (7 * (6 * (5 * (4 * 6))))
= 8 * (7 * (6 * (5 * 24)))
= 8 * (7 * (6 * 120))
= 8 * (7 * 720)
= 8 * 5040
= 40320
https://class.coursera.org/principlescomputing-001/wiki/view?page=recurrences
http://www.codeskulptor.org/#poc_recurrence_examples.py
Master Theorem http://en.wikipedia.org/wiki/Master_theorem
detect closed form of a recurrence using plotting http://www.codeskulptor.org/#poc_recurrence_plot.py
cat in the hat demo http://www.codeskulptor.org/#poc_cat_in_the_hat.py
3 binary search
http://www.codeskulptor.org/#poc_binary_search.py
4 how to read files in codeskulptor
http://www.codeskulptor.org/#examples_files.py
http://www.codeskulptor.org/#user36_qnLrB3TwNh_0.py
5 mini-project Word Wrangler
需要注意的地方有2处,容易出bug.
1 函数def gen_all_strings(word)返回word的所有字母构成的集合的所有子集。只用递归时,basecase是
if len(word) == 0:
return [""] #easy to bug: return []
注意返回的不是[]是[""]
2 在写merge_sort()时,把输入数组分成两部分分别进行sort之后再合并,如何分着两部分,如何确定下标的起止,也是容易出bug的地方。
mid = (len(list1)-1)//correct
list2 = merge_sort(list1[:mid+1])
list3 = merge_sort(list1[mid+1:])
list4 = merge(list2,list3)
mid = (len(list1)-1)// wrong
list2 = merge_sort(list1[:mid])
list3 = merge_sort(list1[mid:])
list4 = merge(list2,list3)
用list = [a,b]这个长度为2的输入来考虑就很容易看出来,按照错误写法,list2=[],list3=[a,b],将永远死循环。
我的作业
"""
Student code for Word Wrangler game
"""
import urllib2
import codeskulptor
import poc_wrangler_provided as provided
WORDFILE = "assets_scrabble_words3.txt"
# Functions to manipulate ordered word lists
def remove_duplicates(list1):
"""
Eliminate duplicates in a sorted list.
Returns a new sorted list with the same elements in list1, but
with no duplicates.
This function can be iterative.
"""
list2 = list(list1)
if len(list2) <= 1:
return list2;
idx_i = 0;
idx_j = 1;
while idx_i < len(list2) and idx_j < len(list2):
if list2[idx_i] != list2[idx_j]:
list2[idx_i+1] = list2[idx_j]
idx_i += 1
idx_j += 1
else:
idx_j += 1
return list2[0:idx_i+1]
def intersect(list1, list2):
"""
Compute the intersection of two sorted lists.
Returns a new sorted list containing only elements that are in
both list1 and list2.
This function can be iterative.
"""
idx_i = 0;
idx_j = 0;
res_list = [];
while idx_i < len(list1) and idx_j < len(list2):
if list1[idx_i]==list2[idx_j]:
res_list.append(list1[idx_i])
idx_i += 1;
idx_j += 1;
elif list1[idx_i]<list2[idx_j]:
idx_i += 1
else:
idx_j += 1
return res_list;
# Functions to perform merge sort
def merge(list1, list2):
"""
Merge two sorted lists.
Returns a new sorted list containing all of the elements that
are in either list1 and list2.
This function can be iterative.
"""
res_list = []
idx_i = 0;
idx_j = 0;
res_list = [];
while idx_i < len(list1) and idx_j < len(list2):
if list1[idx_i] <= list2[idx_j]:
res_list.append(list1[idx_i])
idx_i += 1
else:
res_list.append(list2[idx_j])
idx_j += 1
while idx_i < len(list1):
res_list.append(list1[idx_i])
idx_i += 1
while idx_j < len(list2):
res_list.append(list2[idx_j])
idx_j += 1
return res_list;
def merge_sort(list1):
"""
Sort the elements of list1.
Return a new sorted list with the same elements as list1.
This function should be recursive.
"""
list4 = []
if len(list1) <= 1:
return list1
mid = (len(list1)-1)//2
list2 = merge_sort(list1[:mid+1])
#mid = (len(list1)-1)//2 and here is
#merge_sort(list1[:mid]) then there is an infinite loop,
#imagine the case where list1=[3,4], list1[:0] and
#list1[0:]. It will start an infinite loop.
list3 = merge_sort(list1[mid+1:])
list4 = merge(list2,list3)
return list4
# Function to generate all strings for the word wrangler game
def gen_all_strings(word):
"""
Generate all strings that can be composed from the letters in word
in any order.
Returns a list of all strings that can be formed from the letters
in word.
This function should be recursive.
"""
if len(word) == 0:
return [""] #easy to bug: return []
first_letter = word[0:1]
rest_result = gen_all_strings(word[1:])
rest_result_copy = list(rest_result)
for each in rest_result_copy:
for index in range(len(each)):
new_word = each[:index] + first_letter + each[index:]
rest_result.append(new_word)
rest_result.append(each + first_letter)
return rest_result
# Function to load words from a file
def load_words(filename):
"""
Load word list from the file named filename.
Returns a list of strings.
"""
res = []
url = codeskulptor.file2url(filename)
netfile = urllib2.urlopen(url)
for line in netfile.readlines():
res.append(line[:-1])
return res
def run():
"""
Run game.
"""
words = load_words(WORDFILE)
wrangler = provided.WordWrangler(words, remove_duplicates,
intersect, merge_sort,
gen_all_strings)
provided.run_game(wrangler)
# Uncomment when you are ready to try the game
#run()