Berkeley cs61a dis1的完成和思考

Discussion1主要是围绕control语句(while和if)、environment diagrams进行一些问题的小组讨论和思考。

While and If

Q1: Race

传统的龟兔赛跑问题。设定兔子先按y feet/分的速度跑5分钟,然后再休息5分钟。乌龟一直按照x feet/分的速度跑。问多久后两者第一次相遇。

def race(x, y):
    """The tortoise always walks x feet per minute, while the hare repeatedly
    runs y feet per minute for 5 minutes, then rests for 5 minutes. Return how
    many minutes pass until the tortoise first catches up to the hare.

    >>> race(5, 7)  # After 7 minutes, both have gone 35 steps
    7
    >>> race(2, 4) # After 10 minutes, both have gone 20 steps
    10
    """
    assert y > x and y <= 2 * x, 'the hare must be fast but not too fast'
    tortoise, hare, minutes = 0, 0, 0
    while minutes == 0 or tortoise - hare:
        tortoise += x
        if minutes % 10 < 5:
            hare += y
        minutes += 1
    return minutes

题目给的代码是有问题的。让我们讨论x和y怎样取值的时候,输出的结果是 wrong value 或runs forever的。在分析后发现,此处的minutes只取整数,忽略了小数的情况。当x=2,y=3时,第一次相遇的时间应该是7.5min,但是程序的结果是15min,return wrong value。

思考一个程序runs forever意味着什么。意味着得到的minutes有无数个。此处代码的逻辑是将“第一次追赶上”理解成了“相遇”,即tortoise - hare==0时打断循环。没有了“第一次”这个限定,在一定的x和y输入时就会有无数个结果。我们发现x=4,y=5时程序runs forever。

⚠️注意

  • 0 is a false value and all other numbers are true values.也就是说bool(负数)的结果也是True。

Q2: Fizzbuzz

首先要理解什么是Fizz buzz game。“Fizz buzz is a group word game for children to teach them about division”。游戏者轮流递增计数,用 “fizz ”代替任何能被 3 整除的数字,用 “buzz ”代替任何能被 5 整除的数字,用 “fizzbuzz ”代替任何能被 3 和 5 整除的数字。例子如下:

1, 2, Fizz, 4, Buzz, Fizz, 7, 8, Fizz, Buzz, 11, Fizz, 13, 14, Fizz Buzz, 16, 17, Fizz, 19, Buzz, Fizz, 22, 23, Fizz, Buzz, 26, Fizz, 28, 29, Fizz Buzz, 31, 32, Fizz, 34, Buzz, Fizz, ...

def fizzbuzz(n):
    """
    >>> result = fizzbuzz(16)
    1
    2
    fizz
    4
    buzz
    fizz
    7
    8
    fizz
    buzz
    11
    fizz
    13
    14
    fizzbuzz
    16
    >>> print(result)意味着没有return只有print
    None
    """
    "*** YOUR CODE HERE ***"
    m = 1
    while m <= n:
        if m % 3 ==0 and m % 5==0:
            print('fizzbuzz')
        elif m % 3== 0 and m % 5 != 0:
            print("fizz")
        elif m % 3!= 0 and m % 5 == 0:
            print('buzz')
        else:
            print(m)
        m = m + 1

总结:用if-elif-else成套可以用条件处理多种情况。非常清晰明了。其中result是None意味着函数没有return只有print。

Problem Solving

这个部分让我持续思考写代码的整个过程。如何将脑中的逻辑传递给计算机呢?数学是其中一个重要的桥梁。我很赞同此处伯克利老师写的解决过程。

A useful approach to implementing a function is to:

  1. Pick an example input and corresponding output.  选择一个简单案例
  2. Describe a process (in English) that computes the output from the input using simple steps. 描述大致的过程
  3. Figure out what additional names you'll need to carry out this process. 细化过程,看过程中哪些数需要存储,引入新name
  4. Implement the process in code using those additional names.明确name在过程中的作用 
  5. Determine whether the implementation really works on your original example. 用案例结果证实
  6. Determine whether the implementation really works on other examples. (If not, you might need to revise step 2.) 再用一个例子论证

Q3: Is Prime?

def is_prime(n):
    """
    >>> is_prime(10)
    False
    >>> is_prime(7)
    True
    >>> is_prime(1) # one is not a prime number!!
    False
    """
    "*** YOUR CODE HERE ***"#只有两个因子:1和他自己
    i = 1
    sum=0
    while i <= n:
        if n % i ==0:
            sum=sum+1
        else:
            sum=sum+0
        i=i+1
    if sum ==2:
        return True
    else:
        return False

以此题为例。任务:判断这个数是否是质数。可以转化为判断这个数是否只有1和其本身两个因子的数学问题。那么这一过程在程序中具体如何实现呢?对于一个数n,从1到n全部遍历一遍,然后计算n%i 为0的个数是否为2。如果是,则为质数;否则便不是。因为要遍历所以想着要用while。因为要用n%i==0来判断所以要有个数i表示从1到n的遍历。因为要看个数是否为2,所以需要有个name来计数,就是sum。新变量的选择与具体的实现细节分不开。在之前的编程中我可能更看重逻辑,对于name的选择并没有很重视。现在我的一个想法就是要重视对新变量的引入。要在解题的过程中有意识地思考哪些步骤中需要存什么数,这些数是全局的还是局部的,他是为了什么而存在的。

Q4: Unique Digits

def unique_digits(n):
    """Return the number of unique digits in positive integer n.

    >>> unique_digits(8675309) # All are unique
    7
    >>> unique_digits(13173131) # 1, 3, and 7
    3
    >>> unique_digits(101) # 0 and 1
    2
    """
    "*** YOUR CODE HERE ***"
    sum = 0  
    b = -1
    while n > 0 : #问题:怎么记录上一个位数的数? 222
      a = n % 10 #2 2 2
      n = (n - a)//10#22 2 0 
      if b != a: 
         sum = sum +1# 1
         b = a #2
    return  sum 


def has_digit(n, k):#199
    """Returns whether k is a digit in n.

    >>> has_digit(10, 1)
    True
    >>> has_digit(12, 7)
    False
    """
    assert k >= 0 and k < 10
    "*** YOUR CODE HERE ***"
    while n > 0 : 
      a = n % 10#个位数 9 9 1
      n = (n - a)//10#19 1 0
      if a == k:
          return True
    return False

    

解决问题的本质就是获得每一位的位数。要达到这个目的,需要先获得该数的个位数,再将小数点左移一位,再获得该数的个位数,以此类推。

Q5和Q6此处省略。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值