Principles of Computing (Part 2) week 2 -- Recursion

来源:互联网 发布:xtream path1.6 mac 编辑:程序博客网 时间:2024/06/07 12:11

1. Recursion

a funny game “Cat in the Hat
Cat in the Hat
http://www.codeskulptor.org/#poc_cat_in_the_hat.py

example for recursion

    #sum_up_to(n):    #   base case: 1 when n = 1    #   recursive case: n + sum_up_to(n-1) when n > 1    def sum_up_to(n):        # base case        if n == 1:            return 1        # recursive case        else:            return n + sum_up_to(n-1)    def is_palindrome(word):        if len(word) < 2:        # base case            return True        else:        # recursive case            if word[0] != word[-1]:                return False            else:                return is_palindrome(word[1:-1])    def gen_all_permutations(outcomes):        answer_set = set()        if len(outcomes) == 1:            perm = list(outcomes)            answer_set.add(tuple(perm))            return answer_set        rest_permutations = list(gen_all_permutations(outcomes[1 :]))        for perm in rest_permutations:            for idx in range(len(perm) + 1):                temp_list = list(perm)                temp_list.insert(idx, outcomes[0])                answer_set.add(tuple(temp_list))        return answer_set

Binary Search codes:
http://www.codeskulptor.org/#poc_binary_search.py

Linear Search: search the element by scanning the list

    # Search element in a list      # for i = 0 to n -1    #    if L[i] == K    #        return True    # return False

Binary Search: compare the element with the middle number in the list to choose upper list or lower list for next search (the list is sorted)

        def binary_search(sort_list, element):            if len(sort_list) == 1:                # base case                return sort_list[0] == element             mid = len(sort_list) / 2            if sort_list[mid] > element:                return binary_search(sort_list[: mid], element)            else:                return binary_search(sort_list[mid :], element)

3. Recurrences

Solutions to common recurrences

When building recursive programs, knowing the closed-form solutions to common recurrences is helpful since this knowledge can guide you towards building efficient programs. Below, we list various common recurrences and their approximate solutions.
In all cases, we assume that  f(1)=1.

  •  f(n)=f(n1)+1f(n)=n
  •  f(n)=f(n1)+nf(n)=12n(n+1)
  •  f(n)=2f(n1)f(n)=2n1
  •  f(n)=n f(n1)f(n)=n!
  •  f(n)=f(n2)+1 f(n)log2(n)+1
  •  f(n)=f(n2)+n f(n)2n1
  •  f(n)=2f(n2) f(n)n
  •  f(n)=2f(n2)+1f(n)2n1
  •  f(n)=2f(n2)+nf(n)n(log2(n)+1)

This recursive Python function that computes the Fibonacci numbers is not efficient

    def fib(num):        if num == 0:            return 0        elif num == 1:            return 1        else:            return fib(num - 1) + fib(num - 2)

One technique for avoiding this issue is memoization , a technique in which the values computed by calls to fib are stored in an auxiliary dictionary for later use.

    def memoized_fib(num, memo_dict):        if num in memo_dict:            return memo_dict[num]        else:            sum1 = memoized_fib(num - 1, memo_dict)            sum2 = memoized_fib(num - 2, memo_dict)            memo_dict[num] = sum1 + sum2            return sum1 + sum2

4. Reading Files

    # Reading files from the network    import urllib2    import codeskulptor    FILENAME = "examples_files_dracula.txt"    # http://codeskulptor-examples.commondatastorage.googleapis.com/examples_files_dracula.txt    url = codeskulptor.file2url(FILENAME)    netfile = urllib2.urlopen(url)    # read() only works once    data = netfile.read()    print data    print type(data)    # readlines() only works once    for line in netfile.readlines():        print line        #print line[:-1]

5. Word Wrangler

1. *merge sorted list & 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.        """           merged_list = []        # duplicate the input lists        temp_list1 = list(list1)        temp_list2 = list(list2)        while len(temp_list1) and len(temp_list2):            if temp_list1[0] < temp_list2[0]:                merged_list.append(temp_list1.pop(0))            else:                merged_list.append(temp_list2.pop(0))        if len(temp_list1) == 0:            merged_list.extend(temp_list2)        elif len(temp_list2) == 0:            merged_list.extend(temp_list1)        return merged_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.        """        if len(list1) <= 1:            # base case            sort_list = list(list1)            return sort_list        else:            # recursive case            mid = len(list1) / 2            down_list = merge_sort(list1[ :mid])            up_list   = merge_sort(list1[mid :])            return merge(down_list, up_list)  

2. *gen_all_strings*

1. Split the input word into two parts: the first character     (first) and the remaining part (rest).2. Use gen_all_strings to generate all appropriate strings     for rest. Call this list rest_strings.3. For each string in rest_strings, generate new strings by     inserting the initial character, first, in all possible     positions within the string.4. Return a list containing the strings in rest_strings     as well as the new strings generated in step 3.
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.    """    all_strings = []    if len(word) == 0:        # base case        all_strings.append("")    else:        # recursive case        first = word[0]        rest  = word[1 :]        rest_strings = (gen_all_strings(rest))        all_strings.extend(rest_strings)        for string in rest_strings:            if len(string) == 0:                all_strings.append(first)            else:                for idx in range(len(string) + 1):                    all_strings.append("".join([string[:idx], first, string[idx:]]))    return all_strings

3. *Word Wrangler*
http://www.codeskulptor.org/#user39_gMEWuD77jcQzxUH_0.py

    """    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.        """        unique_list = []        for element in list1:            if len(unique_list) == 0 or unique_list[-1] != element:                unique_list.append(element)        return unique_list    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.        """        intersect_list = []        # duplicate the input lists        temp_list1 = list(list1)        temp_list2 = list(list2)        while len(temp_list1) and len(temp_list2):            if temp_list1[0] < temp_list2[0]:                temp_list1.pop(0)            elif temp_list1[0] > temp_list2[0]:                temp_list2.pop(0)            else:                intersect_list.append(temp_list1.pop(0))                intersect_list.append(temp_list2.pop(0))        return remove_duplicates(intersect_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.        """           merged_list = []        # duplicate the input lists        temp_list1 = list(list1)        temp_list2 = list(list2)        while len(temp_list1) and len(temp_list2):            if temp_list1[0] < temp_list2[0]:                merged_list.append(temp_list1.pop(0))            else:                merged_list.append(temp_list2.pop(0))        if len(temp_list1) == 0:            merged_list.extend(temp_list2)        elif len(temp_list2) == 0:            merged_list.extend(temp_list1)        return merged_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.        """        if len(list1) <= 1:            # base case            sort_list = list(list1)            return sort_list        else:            # recursive case            mid = len(list1) / 2            down_list = merge_sort(list1[ :mid])            up_list   = merge_sort(list1[mid :])            return merge(down_list, up_list)    # 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.        """        all_strings = []        if len(word) == 0:            # base case            all_strings.append("")        else:            # recursive case            first = word[0]            rest  = word[1 :]            rest_strings = (gen_all_strings(rest))            all_strings.extend(rest_strings)            for string in rest_strings:                if len(string) == 0:                    all_strings.append(first)                else:                    for idx in range(len(string) + 1):                        all_strings.append("".join([string[:idx], first, string[idx:]]))        return all_strings    # Function to load words from a file    def load_words(filename):        """        Load word list from the file named filename.        Returns a list of strings.        """        url = codeskulptor.file2url(filename)        netfile = urllib2.urlopen(url)        lines = []        for line in netfile.readlines():              lines.append(line[:-1])          return lines     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()
0 0
原创粉丝点击