[2021 Spring] CS61A 学习笔记 Homework 4: Trees, Data Abstraction

作业地址: https://inst.eecs.berkeley.edu/~cs61a/sp21/hw/hw04/

Abstraction

Q1: Weights

参考mobile和arm同一模板

def planet(size):
    """Construct a planet of some size."""
    assert size > 0
    "*** YOUR CODE HERE ***"
    return ['planet', size]


def size(w):
    """Select the size of a planet."""
    assert is_planet(w), 'must call size on a planet'
    "*** YOUR CODE HERE ***"
    return w[1]

Q2: Balanced

要求使用abstraction barrier,禁止使用索引。
考虑平衡性:

  1. 当m是planet时,本身是平衡的,直接返回True;
  2. 当m是mobile时,需要计算arm的扭矩torque,torque = arm下的weight*length,左右两边的torque相等即表示该mobile是平衡的;
  3. 另一个要求是每个mobile下的arm都平衡,递归即可。
def balanced(m):
    """Return whether m is balanced.

    >>> t, u, v = examples()
    >>> balanced(t)
    True
    >>> balanced(v)
    True
    >>> w = mobile(arm(3, t), arm(2, u))
    >>> balanced(w)
    False
    >>> balanced(mobile(arm(1, v), arm(1, w)))
    False
    >>> balanced(mobile(arm(1, w), arm(1, v)))
    False
    >>> from construct_check import check
    >>> # checking for abstraction barrier violations by banning indexing
    >>> check(HW_SOURCE_FILE, 'balanced', ['Index'])
    True
    """
    "*** YOUR CODE HERE ***"
    if is_planet(m):
        return True
    return total_weight(end(left(m))) * length(left(m)) == \
            total_weight(end(right(m))) * length(right(m)) and \
                balanced(end(left(m))) and balanced(end(right(m)))

Q3: Totals

  1. planet返回叶节点,即tree(total_weight(m))
  2. mobile返回带有枝干的树节点,枝为end(arm)的totals_tree,即tree(total_weight(m), [totals_tree(end(left(m))), totals_tree(end(right(m)))])
def totals_tree(m):
    """Return a tree representing the mobile with its total weight at the root.

    >>> t, u, v = examples()
    >>> print_tree(totals_tree(t))
    3
      2
      1
    >>> print_tree(totals_tree(u))
    6
      1
      5
        3
        2
    >>> print_tree(totals_tree(v))
    9
      3
        2
        1
      6
        1
        5
          3
          2
    >>> from construct_check import check
    >>> # checking for abstraction barrier violations by banning indexing
    >>> check(HW_SOURCE_FILE, 'totals_tree', ['Index'])
    True
    """
    "*** YOUR CODE HERE ***"
    if is_planet(m):
        return tree(total_weight(m))
    return tree(total_weight(m), [totals_tree(end(left(m))), totals_tree(end(right(m)))])

Trees

Q4: Replace Thor at Leaf

base:节点为叶节点且值为'thor'时替换为thors_replacement

def replace_thor_at_leaf(t, thors_replacement):
    """Returns a new tree where every leaf value equal to "thor" has
    been replaced with thors_replacement.

    >>> yggdrasil = tree('odin',
    ...                  [tree('balder',
    ...                        [tree('thor'),
    ...                         tree('freya')]),
    ...                   tree('frigg',
    ...                        [tree('thor')]),
    ...                   tree('thor',
    ...                        [tree('sif'),
    ...                         tree('thor')]),
    ...                   tree('thor')])
    >>> laerad = copy_tree(yggdrasil) # copy yggdrasil for testing purposes
    >>> print_tree(replace_thor_at_leaf(yggdrasil, 'freya'))
    odin
      balder
        freya
        freya
      frigg
        freya
      thor
        sif
        freya
      freya
    >>> laerad == yggdrasil # Make sure original tree is unmodified
    True
    """
    "*** YOUR CODE HERE ***"
    if is_leaf(t) and label(t) == 'thor':
        return tree(thors_replacement)
    return tree(label(t), [replace_thor_at_leaf(c, thors_replacement) for c in branches(t)])

Q5: Has Path

  1. label(t)与word[0]不相等时,返回False
  2. label(t)与word[0]相等,在len(word)等于1时,完全匹配,返回True
  3. for循环遍历branch,传入word[1:].
def has_path(t, word):
    """Return whether there is a path in a tree where the entries along the path
    spell out a particular word.

    >>> greetings = tree('h', [tree('i'),
    ...                        tree('e', [tree('l', [tree('l', [tree('o')])]),
    ...                                   tree('y')])])
    >>> print_tree(greetings)
    h
      i
      e
        l
          l
            o
        y
    >>> has_path(greetings, 'h')
    True
    >>> has_path(greetings, 'i')
    False
    >>> has_path(greetings, 'hi')
    True
    >>> has_path(greetings, 'hello')
    True
    >>> has_path(greetings, 'hey')
    True
    >>> has_path(greetings, 'bye')
    False
    >>> has_path(greetings, 'hint')
    False
    """
    assert len(word) > 0, 'no path for empty word.'
    "*** YOUR CODE HERE ***"
    if label(t) != word[0]:
        return False
    elif len(word) == 1:
        return True
    for b in branches(t):
        if has_path(b, word[1:]):
            return True
    return False

Q6: Preorder

前序遍历:

  1. 叶节点返回[label(t)]
  2. 对于每个非叶节点b,将preorder(b)累加到res
  3. 返回根节点+res
def preorder(t):
    """Return a list of the entries in this tree in the order that they
    would be visited by a preorder traversal (see problem description).

    >>> numbers = tree(1, [tree(2), tree(3, [tree(4), tree(5)]), tree(6, [tree(7)])])
    >>> preorder(numbers)
    [1, 2, 3, 4, 5, 6, 7]
    >>> preorder(tree(2, [tree(4, [tree(6)])]))
    [2, 4, 6]
    """
    "*** YOUR CODE HERE ***"
    if is_leaf(t):
        return [label(t)]
    res = []
    for b in branches(t):
        res += preorder(b)
    return [label(t)] + res
posted @ 2021-07-01 23:49  ikventure  阅读(3075)  评论(0编辑  收藏  举报