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

6 篇文章 0 订阅
5 篇文章 0 订阅

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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值