Principle of Computing (Python)学习笔记(6) Recursion + Word Wrangler

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

你可能感兴趣的:(python)