编程珠玑第三章总结

本文介绍了几种算法挑战的解决方案,包括使用数组解决特定问题、通过字符编码绘制字母图形以及日期间隔的快速计算方法。同时展示了如何利用日期编号简化日期计算过程,并提供了具体的实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第二题:直接用两个数组就解决了。

def const_recursion(k,a,c,m):
    def get(n):
        if n <= len(a):return a[n-1]
        next = 0
        kase = 0
        for i in range(n-k-1,n-1): 
            next += a[i]*c[kase]
            kase += 1
        next += c[kase]#c_k+1
        a.append(next)
        return next
    for i in range(m):
        print(get(i+1))

第三题:此题可以采用编码方式进行绘制,由于十分繁琐,只画了几个字母的情况。

const_code = {'A':'1 2 b 1 * 2 b/1 1 b 3 * 1 b/1 1 * 3 b 1 *',\
'I':'1 9 */3 3 b 3 * 3 b/1 9 *',\
'D':'1 1 * 5 b/1 1 * 3 b 1 * 1 b/1 1 * 4 b 1 */1 1 * 3 b 1 * 1 b/1 1 * 5 b'}
const_code['B'] = const_code['D']+'/'+const_code['D']
def get(char):
    if char == 'b':return ' '
    return char
def decode_line(line_code):
    line_code = line_code.split(' ')
    length = len(line_code)
    index = 0
    while index <= length-1:
        cols = int(line_code[index])
        char = line_code[index+1]
        index += 2
        print(get(char)*cols,end ='')
    print('')
def de_code(code):
    lines = code.split('/')
    for line in lines:
        rows = int(line[0])#获取要连续执行的行数
        for row in range(rows):
            decode_line(line[2:])

def output():
    for each in const_code:
        de_code(const_code[each])
        print('='*10)
output()

这里写图片描述

画的不是很像…

第四题:这道题目有一点小技巧,我自己的思路不是很好,不利于拓展性.

思路1:直接模拟就好,相对繁琐,需要从第一个日期开始,分几个阶段模拟,代码就不给出了。
思路2:对每一个日期在各自的年份进行编号,然后相减,并且加上差的年份*365 or 366即可。这个思路是很巧妙的,当然你想到了也就不难,没想到就和我一样采用模拟的办法确实要繁琐一些,但是算法复杂度是一样的。编号的好处在于对其他一些需要利用日期的需求都可以借助编号来解决!另外,这里有一个小细节很容易错,在计算编号的时候,需要要注意每过一个月都要加上整个月的天数而不是月末减月初!
Excited!
from collections import namedtuple
date = namedtuple('date',['year','month','day'])
const_month = [None,31,28,31,30,31,30,31,31,30,31,30,31]
base_date = date(2016,6,6)#周1
weekdays = ['一','二','三','四','五','六','七']

def is_special(year):
    if not year%100:
        return not year%400
    else:return not year%4

def get_endof_month(year,month):
    if month != 2:return const_month[int(month)]#不是2月
    elif is_special(year):return 29#是润年的2月
    return 28#普通2月

def get_own_index(date):
    first_index = 0
    for first_month in range(1,date.month):
        month_end = get_endof_month(date.year,first_month)
        first_index += month_end
    first_index += (date.day -1)
    return first_index

def fast_offset(date1,date2):
    gap = 0
    for year in range(date1.year,date2.year):
        gap += 366 if is_special(year) else 365
    #计算两个日期在各自年份的编号
    first_index = get_own_index(date1)
    second_index = get_own_index(date2)
    gap += (second_index - first_index)
    return gap

def get_weekday(date):
    offset = fast_offset(base_date,date)%7
    return '周'+weekdays[offset]

def generate_calender(year,month):
    first_date = date(year,month,1)
    end_date = date(year,month,get_endof_month(year,month))
    prefix = str(year)+'.'+str(month)+'.'
    for i in range(7):
        print('   周'+weekdays[i],end = '   ')
    print('')
    offset =  fast_offset(base_date,first_date)%7
    print((offset*10)*' '+'    ',end='')
    count = 0
    for each in range(end_date.day-first_date.day+1):
        curr_date = date(year,month,1+each)
        print(str(1+each),end=' '* (8 if (1+each)>9 else 9))
        if not (offset+each+1)%7:print('\n    ',end='')

generate_calender(2016,6)

注意一点,对齐格式还是有点麻烦

这里写图片描述

习题8:注意补充完不足的字节就好。

const_cache = {0:'',1:'35',2:'01245',3:'01246',4:'1346',5:'01236',6:'012356',7:'246',8:'0123456',9:'012346'}
def process_one_digit(num):
    data = ['0' for i in range(8)]
    rule = const_cache[num]
    for each in rule:
        each = int(each)
        data[each] = '1'
    return ''.join(data)
def complete(x):
    x = str(x)
    x += '0'*(5-len(x))+x
    return x
def process_input(bit_16_num):
    x = int(bit_16_num,base = 2)
    x = complete(x)
    output = ''
    for each in x:
        output += process_one_digit(int(each))
    return output
print(process_input('11111'))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值