zoukankan      html  css  js  c++  java
  • 【个人笔记】编程的乐趣(用python解算法谜题)——谜题1,2

    谜题 1 保持一致

    s = 'Alice'
    #不能修改字符串s[0] = 'B'



    # print默认末尾换行
    # end = '' 末尾不换行,加空格
    print(s, end=' ')

      

    Python中的列表(list)可理解为元素的序列或数组 

    L = [1, 2, 'A', [3,4] ]

    元组与列表类似但不可修改

    T1 = (1, 2, 'A', [3, 4] )

    T2= (1, 2, 'A', (3, 4) )

    T1[3]不可修改,T1[3][0]可修改

    T2[3][0]不可修改

    习题

    cap1 = ['F', 'F', 'B', 'B', 'B', 'F', 'B', 'B', 'B', 'F', 'F', 'B', 'F']
    cap2 = ['F', 'F', 'B', 'B', 'B', 'F', 'B', 'B', 'B', 'F', 'F', 'F', 'F']
    cap3 = ['F', 'F', 'B', 'H', 'B', 'F', 'B', 'B', 'B', 'F', 'H', 'F', 'F']

    习题 1.修改代码使命令听起来更自然一些。

    增加判断语句,输出时先判断区间大小是否为1

    def pleaseConform(caps):
        start = forward = backward = 0
        intervals = []
        #caps += ['end']
        for i in range(1, len(caps)):
            if caps[start] != caps[i] or i == len(caps) - 1:
                intervals.append((start, i - 1, caps[start]))
                if caps[start] == 'F':
                    forward += 1
                else:
                    backward += 1
                start = i
    
        if forward < backward:
            flip = 'F'
        else:
            flip = 'B'
        for t in intervals:
            if t[2] == flip:
                if t[0] == t[1]:
                    print('People in positions', t[0], 'flip your caps!')
                else:
                    print('People in positions', t[0], 'through', t[1], 'flip your caps!')
    

     

    习题2.修改pleaseConformOnepass,如习题1那样打印更自然一些的命令,并确保程序再输入是空列表时不会崩溃。
      提示:你需要记住区间的起始位置(而不是在第6行打印)。

    记录开始位置,输出时先判断区间大小是否为1

    def pleaseConformOnepass(caps):
        if caps != []:
            caps = caps + [caps[0]]
            for i in range(1, len(caps)):
                if caps[i] != caps[i - 1]:
                    if caps[i] != caps[0]:
                        start = i
                    else:
                        if start == i-1:
                            print('People in positions', i-1, 'flip your caps!')
                        else:
                            print('People in positions', start, ' through', i - 1, 'flip your caps!')
    
    
    pleaseConformOnepass(cap2)
    

    习题3.

    假设在队伍中存在没戴帽子的人。我们用字符’H’代表他们。例如,有这样一组数据:
      caps3 = [‘F’, ‘F’, ‘B’, ‘H’, ‘B’, ‘F’, ‘B’, ‘B’, ‘B’, ‘F’, ‘H’, ‘F’, ‘F’ ]
      我们不想指示没戴帽子的人去转动不存在的帽子,这令人困惑,可能会导致有人试图从队伍前面的人那里偷帽子。因此我们希望跳过所有’H’位置。修改pleaseConform,使它生成正确并且最小数量的命令集合。对于上面的例子,它应当生成:
      People in positions 2 flip your caps!
      People in positions 4 flip your caps!
      People in positions 6 through 8 flip your caps!

    增加对不戴帽子 'H' 的判断

    def pleaseConform(caps):
        start = forward = backward = 0
        intervals = []
        #caps += ['end']
        for i in range(1, len(caps)):
            if caps[start] != caps[i] or i == len(caps) - 1:
                if caps[start] != 'H':
                    intervals.append((start, i - 1, caps[start]))
                    if caps[start] == 'F':
                        forward += 1
                    else:
                        backward += 1
                start = i
    
        if forward < backward:
            flip = 'F'
        else:
            flip = 'B'
        for t in intervals:
            if t[2] == flip:
                if t[0] == t[1]:
                    print('People in positions', t[0], 'flip your caps!')
                else:
                    print('People in positions', t[0], 'through', t[1], 'flip your caps!')
    
    
    pleaseConform(cap3)
    

     习题4 写一段程序实现简单的游程编码,将给定字符串(如BWWWWWBWWWW)转换为较短的字符串(1B5W1B4W),并且执行游程解码,将压缩过的字符串转换回原始字符串。你只能通过一次字符串遍历来执行压缩和解压缩过程。

      str函数能将数字转换成字符串,例如str(12) = ‘12’。它在编码步骤汇总会很有用。
      int函数能将字符串转换成数字,例如:int(‘12’) = 12。对于任意字符串s,如果s[i]是字母字符,则s[i].isalpha()将返回True,否则返回False。如果s中所有的字符都是字母字符,则s.isalpha()返回True,否则返回False。函数int和isalpha在解码步骤中会很有用。

    s = "BWWWWWBWWWWQ"
    
    
    def encode(string):
        string += ' '
        time = idx = 1
        res = ''
        while idx < len(string):
            if string[idx] != string[idx - 1]:
                res += str(time)
                res += string[idx - 1]
                time = 1
            else:
                time += 1
            idx += 1
        print(res)
        return res
    
    
    def decode(string):
        time = 0
        res = ''
        for c in string:
            if '0' <= c <= '9':
                time = time * 10 + int(c)
            else:
                for i in range(time):
                    res += c
                time = 0
        print(res)
        return res
    
    
    decode(encode(s))
    

      

    谜题 2 参加派对的最佳时间

    #选择排序
    def sortList(tlist):
        for ind in range(len(tlist) - 1):
            iSm = ind
            for i in range(ind, len(tlist)):
                if tlist[iSm][0] > tlist[i][0]:
                    iSm = i
            tlist[ind], tlist[iSm] = tlist[iSm], tlist[ind]
    

    习题1

    在计算名人参加派对最多的时间时,增加对时间是否满足[ystart, yend]范围的判断

    sched2 = [(6.0, 8.0), (6.5, 12.0), (6.5, 7.0), (7.0, 8.0), (7.5, 10.0), (8.0, 9.0),
              (8.0, 10.0), (9.0, 12.0), (9.5, 10.0), (10.0, 11.0), (10.0, 12.0), (11.0, 12.0)]
    
    
    def bestTimeToPartySmart(schedule, ystart, yend):
        times = []
        for c in schedule:
            times.append((c[0], 'start'))
            times.append((c[1], 'end'))
    
    
        sortlist(times)
        maxcount, time = chooseTime(times, ystart, yend)
        print(maxcount, time)
    
    # 选择排序
    def sortlist(tlist):
        for ind in range(len(tlist) - 1):
            iSm = ind
            for i in range(ind, len(tlist)):
                if tlist[iSm][0] > tlist[i][0]:
                    iSm = i
            tlist[ind], tlist[iSm] = tlist[iSm], tlist[ind]
    
        return
    
    
    def chooseTime(times,  ystart, yend):
        rcount = 0
        maxcount = 0
        time = 0
    
        # Range through the times computing a running count of celebrities
        for t in times:
            if t[1] == 'start':
                rcount = rcount + 1
            elif t[1] == 'end':
                rcount = rcount - 1
            if rcount > maxcount and ystart < t[0] < yend:
                maxcount = rcount
                time = t[0]
    
        return maxcount, time
    
    
    ##bestTimeToPartySmart(sched)
    ystart = 8
    yend = 10
    bestTimeToPartySmart(sched2, ystart, yend)
    

    习题2

    有另一种方法, 可以不依赖时间精度来计算参加派对的最佳时间。我们依次选择每位名人的时间区间,并确定有多少其他名人的时间区间包含所选名人的开始时间。我们选择出某位名人,使他的开始时间被最大数量的其他名人时间区间所包含,并将他的开始时间作为参加派对的时间。编写代码实现该算法,并验证它的结果与基于排序算法的结果是否相同。

    计算每一位名人在开始时间时,有多少其它名人在场

    def fun2(time):
        max_count = count = 0
        best_time = 0;
        for t in time:
            for t0 in time:
                if t0[0] <=t[0] < t0[1] :
                    count += 1
            if max_count < count:
                max_count = count
                best_time = t[0]
        return best_time, max_count
    

      

     习题3

    假设每位名人都有一个权重,取决于你对这位名人的喜爱程度。可以在时间表中将其表示为一个三元组,如(6.0, 8.0, 3)。开始时间是6.0,结束时间是8.0,权重是3。修改代码,找出最大化名人总权重的时间。例如…下面是一个更复杂的例子:
      sched3 = [(6.0, 8.0, 2), (6.5, 12.0, 1), (6.5, 7.0, 2), (7.0, 8.0, 2), (7.5, 10.0, 3), (8.0, 9.0, 2), (8.0, 10.0, 1), (9.0, 12.0, 2), (9.5, 10.0, 4), (10.0, 11.0, 2), (10.0, 12.0, 3), (11.0, 12.0, 7)]
      根据名人的日程安排,你想要在11点参加派对,此时参加派对名人权重之和是13,为最大值。

    对2.2的算法进行修改:

    在排序时间前,即bestTimeToPartySmart函数中,对每一个开始时间和结束时间都记录上该名人的权重值

    在最终选择时间时,即chooseTime函数中,“start” 时刻将增加此名人对应的权重,“end” 时刻减少权重

    sched3 = [(6.0, 8.0, 2), (6.5, 12.0, 1), (6.5, 7.0, 2), (7.0, 8.0, 2), (7.5, 10.0, 3), (8.0, 9.0, 2),
              (8.0, 10.0, 1), (9.0, 12.0, 2), (9.5, 10.0, 4), (10.0, 11.0, 2), (10.0, 12.0, 3), (11.0, 12.0, 7)]
    
    def bestTimeToPartySmart(schedule):
        times = []
        for c in schedule:
            times.append((c[0], 'start', c[2]))
            times.append((c[1], 'end', c[2]))
    
    
        sortlist(times)
        maxcount, time = chooseTime(times)
        return maxcount, time
    
    # 选择排序
    def sortlist(tlist):
        for ind in range(len(tlist) - 1):
            iSm = ind
            for i in range(ind, len(tlist)):
                if tlist[iSm][0] > tlist[i][0]:
                    iSm = i
            tlist[ind], tlist[iSm] = tlist[iSm], tlist[ind]
    
        return
    
    
    def chooseTime(times):
        rcount = 0
        maxcount = 0
        time = 0
    
        # Range through the times computing a running count of celebrities
        for t in times:
            if t[1] == 'start':
                rcount = rcount + t[2]
            elif t[1] == 'end':
                rcount = rcount - t[2]
            if rcount > maxcount:
                maxcount = rcount
                time = t[0]
    
        return maxcount, time
    
    
    maxcount, time = bestTimeToPartySmart(sched3)
    print('The best time to go is', time, 'with pow', maxcount)
    

      

     参考资料:

    编程的乐趣用Python解算法谜题 —— 斯里尼·德瓦达斯

    编程的乐趣:用Python解算法谜题 课后习题答案 —— CSDN博主「咬不动的椰果」:https://blog.csdn.net/qgazq/article/details/102711260

  • 相关阅读:
    代码块
    hp g6 2328tx 加装ssd 机械硬盘安装到光驱位置 问题小结
    thinking java
    命令设计模式
    内部类
    模板方法模式
    UIAlertController
    一个基于qml的网络封装库
    qml package 的使用
    一个QMLListView的例子--
  • 原文地址:https://www.cnblogs.com/leftstan/p/14464424.html
Copyright © 2011-2022 走看看