红魔咖啡馆

头发越掉越多,头发越掉越少

0%

【CS61A】CS61A——Lab4

Dictionaries 部分跳过

Divide

传入一组商数与一组除数,返回字典,键为每个商数,值为表示每个商数能整除的除数的列表

1
2
3
4
5
6
7
8
9
10
def divide(quotients, divisors):
    """Return a dictonary in which each quotient q is a key for the list of
    divisors that it divides evenly.

    >>> divide([3, 4, 5], [8, 9, 10, 11, 12])
    {3: [9, 12], 4: [8, 12], 5: [10]}
    >>> divide(range(1, 5), range(20, 25))
    {1: [20, 21, 22, 23, 24], 2: [20, 22, 24], 3: [21, 24], 4: [20, 24]}
    """
    return {i: [x for x in divisors if x%i==0] for i in quotients}

注意用表达式建立列表与字典的方法

Buying Fruit

实现buy函数,通过给定的水果与价格,用恰好为传入的total_amount的价格购买指定的水果(每种指定水果至少买一次) 用display函数输出所有结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
def buy(required_fruits, prices, total_amount):
    """Print ways to buy some of each fruit so that the sum of prices is amount.

    >>> prices = {'oranges': 4, 'apples': 3, 'bananas': 2, 'kiwis': 9}
    >>> buy(['apples', 'oranges', 'bananas'], prices, 12)
    [2 apples][1 orange][1 banana]
    >>> buy(['apples', 'oranges', 'bananas'], prices, 16)
    [2 apples][1 orange][3 bananas]
    [2 apples][2 oranges][1 banana]
    >>> buy(['apples', 'kiwis'], prices, 36)
    [3 apples][3 kiwis]
    [6 apples][2 kiwis]
    [9 apples][1 kiwi]
    """
    def add(fruits, amount, cart):
        if fruits == [] and amount == 0:
            print(cart)
        elif fruits and amount > 0:
            fruit = fruits[0]
            price = prices[fruit]
            for k in range(1,amount//price+1):
                add(fruits[1:], amount-k*price, cart+display(fruit,k))
    add(required_fruits, total_amount, '')

def display(fruit, count):
    """Display a count of a fruit in square brackets.

    >>> display('apples', 3)
    '[3 apples]'
    >>> display('apples', 1)
    '[1 apple]'
    """
    assert count >= 1 and fruit[-1] == 's'
    if count == 1:
        fruit = fruit[:-1]  # get rid of the plural s
    return '[' + str(count) + ' ' + fruit + ']'

返回条件是fruits为空或钱被花光,且递归时每次都取fruits的首个元素 可以推断递归时对fruits数组进行了切片,每次往后切一个元素 for循环遍历选择每个水果的个数,从至少选一个到最多能选的个数\(\frac{amount}{price}+1\) 递归时传入总价格减去已经使用的价格数的不同情况,并使用display函数进行字符串拼接来显示

Cities ADT

以下问题基于建立的该ADT 一个城市由以下参数描述:名称、经度、维度 包括一个构造函数 - make_city(name, lat, lon):建立一个城市对象,存储其名称、经度、维度 以下选择器 - get_name(city):获取城市名称 - get_lat(city):获取城市经度 - get_lon(city):获取城市维度 该抽象数据类型已经在文件中实现,你不需要知道是怎么实现的

Distance

计算并返回两城市的距离

1
2
3
4
5
6
7
8
9
10
11
12
13
from math import sqrt
def distance(city_a, city_b):
    """
    >>> city_a = make_city('city_a', 0, 1)
    >>> city_b = make_city('city_b', 0, 2)
    >>> distance(city_a, city_b)
    1.0
    >>> city_c = make_city('city_c', 6.5, 12)
    >>> city_d = make_city('city_d', 2.5, 15)
    >>> distance(city_c, city_d)
    5.0
    """
    return sqrt(abs(get_lat(city_a)-get_lat(city_b))**2+abs(get_lon(city_a)-get_lon(city_b))**2)

Closer City

比较两个城市离给定经纬度的远近,返回更近的那个城市

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
def closer_city(lat, lon, city_a, city_b):
    """
    Returns the name of either city_a or city_b, whichever is closest to
    coordinate (lat, lon). If the two cities are the same distance away
    from the coordinate, consider city_b to be the closer city.

    >>> berkeley = make_city('Berkeley', 37.87, 112.26)
    >>> stanford = make_city('Stanford', 34.05, 118.25)
    >>> closer_city(38.33, 121.44, berkeley, stanford)
    'Stanford'
    >>> bucharest = make_city('Bucharest', 44.43, 26.10)
    >>> vienna = make_city('Vienna', 48.20, 16.37)
    >>> closer_city(41.29, 174.78, bucharest, vienna)
    'Bucharest'
    """
    fake_city = make_city('fake', lat, lon)
    if distance(fake_city,city_a)<distance(fake_city,city_b):
        return get_name(city_a)
    else:
        return get_name(city_b)

可以将指定的经纬度看作第三个城市并构造这么一个对象 通过上面已经写完的distance函数计算两城市与第三个城市的距离并比较,输出更近的 若相同输出city_b