美文网首页
COMP9021 Principles of Programmi

COMP9021 Principles of Programmi

作者: Sisyphus235 | 来源:发表于2017-10-09 15:58 被阅读0次

Q1.

输入一串数字和一个目标值,求解不重复的使用这串数字中的数能够有多少种得到目标值的方法。
如使用12234求解目标值5,则:
1+2+2 = 5;
2+3 = 5;
2(另一个2)+3 = 5;
1+4 = 5
总共有4种方式。
思路:按顺序排查输入的这串数字,每一个数字都有两种情况:使用其形成目标数字,不使用其形成目标数字。使用recursion可以容易求解:

def solve(input_number, target_sum):
    if input_number == 0:
    #input_number为0就是判断到了这串数字的最后一个,所以属于base condition
        if target_sum == 0:
            return 1
        #如果target_sum等于0,说明之前选择的路径能够得到目标值,所以形成一个解,返回数字1代表一个解
        return 0
    if target_sum < 0:
        return 0
    #还会出现一些路径值求和大于了目标值,这样的情况不是解,不用继续向下展开,返回数字0代表无解
    return solve(input_number // 10, target_sum) + solve(input_number // 10, target_sum - input_number % 10)
    #对于每一位数字都有两种基本情况,使用/不使用这个数字作为求目标值的一部分

Q2.

同样的道理,把上题中求和得到目标值替换为求积得到目标值:

def solve(input_number, target_product):
    if input_number == 0:
        if target_product == 1:
            return 1
        return 0
    if target_product % (input_number % 10) == 0:
        return solve(input_number // 10, target_product) + solve(input_number // 10, target_product // (input_number % 10))
    else:
        return solve(input_number // 10, target_product)
    #与求和不同,任何数字都可以选择使用/不使用它来求和;但是乘积要先判断能不能整除,如果不能整除就一定不能使用

Q3.

在Q1的基础上继续变形,把返回具体的解法数量,换成由哪些解组成的。

def solve(input_number, target_sum):
    if input_number == 0:
        if target_sum == 0:
            return [[]]
        #如果有解,则返回一个嵌套的list结构,在内层可以生成之前路径使用的数字
        return []
        #如果无解,则返回一个不嵌套的list,无法在内层list生成解
    if target_sum < 0:
        return []
    return solve(input_number // 10, target_sum) + \
    [[input_number % 10] + sol for sol in solve(input_number // 10, target_sum - input_number % 10)]
    #这条语句不容易理解,核心是两个加号,这两个加号的共同点为二者都是list的连接符;
    #不同点是,第一个加号是不同解之间的list连接,第二个加号是形成解过程的list连接
    #换句话说,第一个加号连接的是外层的list element,第二个加号连接的内层的list element

print(solve(12345, 5))
>>>
[[2, 2, 1], [3, 2], [3, 2], [4, 1]]

Q4.

在Q3的基础上,去除重复的解。

def solve_without_duplication(input_number, target_sum):
    solutions = []
    for sol in solve(input_number, target_sum):
        sorted_sol = sorted(sol)
        if sorted_sol not in solutions:
            solutions.append(sorted_sol)
    return solutions

这段程序的操作比较简单,没有注释。

Q5.

继续在Q1的基础上变形,输入一串字母,找到其中增长的字母串的最大长度,允许不连续。比如'aceh',它的最大增长长度就是4;'caeh',它的最大增长长度就是3(aeh)。

def longest_increasing_sequence(w):
    for target_length in range(len(w), 0, -1):
        n = nb_of_sol(w, target_length, 0, chr(ord('a') - 1))
        if n:
            return target_length
    #因为要找最大程度,所以逆序去找,最大可能是word的长度,最短是1,这就有了上面的for循环
    #使用nb_of_sol根据输入的word,指定的长度,index和最后一个character寻找符合要求的解,有解救返回这个targe_length值
    #使用比ord('a')小1作为最后一个字母的初始值,保证任意一个字母都可以作为第一个开头字母使用

def nb_of_sol(w, desired_length, index, last_char):
    if desigred_length == 0:
        return 1
    if index >= len(w):
        return 0
    if w[index] > last_char:
        return nb_of_sol(w, desired_length - 1, index + 1, w[index]) +\
        nb_of_sol(w, desired_length, index + 1, last_char)
        #也是分成是否使用该字母构建目标值,不管是否使用index都要加1,和之前输入数字串要//10是一个道理
        #如果使用这个字母,则length要减1,同时最后的字母变成当前最后一个字母,方便判断后续字母是否比这个大
    else: 
        return nb_of_sol(w, desired_length, index + 1, last_char)

相关文章

网友评论

      本文标题:COMP9021 Principles of Programmi

      本文链接:https://www.haomeiwen.com/subject/ptkpyxtx.html