本节相对比较简单,以最基础的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()