探索所有子序列

时间:2018-12-26 17:05:26

标签: python python-3.x recursion

我已经尝试了几天以解决此问题,但没有成功。

关于此问题:

给出序列“ 2 2 4 4”。

我们从序列中连续获取2个数字,例如:2 2,2 4,4 4。

如果2个数字的总和是可以被2整除的数字,我们将替换2个数字,并以2个数字的结果为例:(2 + 2 = 4,4/2 = 2),因此新序列为(2 4 4),但是在这里我应该找到所有可能的序列。 如果找不到除以2的偶数,则返回序列。

应有的样子

A picture of how should it be

红色矩形是我无法获得的序列:(

我的代码:

def recFunc(n):
    for i in range(len(n)):
        if i+1 <= len(n)-1: #control out of range
            if ((n[i] + n[i+1]) % 2 == 0):
                newnum = int((n[i] + n[i+1])/2)
                n[i:i+2] = [newnum]
                return recFunc(n)
            else:
                if i+1 == len(n)-1:
                    return [n]
                else:
                    continue
def main(s):
    s = s.split()
    integers = [int(x) for x in s]
    final = recFunc(integers)
    print(final)

main('2 2 4 4')

我在这里所做的是,将序列转换为整数,并将其发送给新函数。我应该递归地接收所有序列。

我对序列进行迭代,将第一个数字乘以n [i]和第二个n [i + 1](并控制我是否可以让第二个数字不超出范围)。

如果2个序列的长度相同,则最终结果应以大小序列的递增顺序排序,因此我们按序列的第一个数字排序。

最后我应该收到['3', '2 3', '3 4', '2 3 4']

3 个答案:

答案 0 :(得分:2)

以下是基于您的图的我的递归解决方案,该解决方案可以处理'30 20 10 30 6 6'而不会出现堆栈问题。数据转换,排序和冗余减少由main()例程处理。 sub_sequence()函数接受一个数组,并返回一个与您的逻辑图匹配的数组:

def sub_sequence(array):
    solutions = []

    length = len(array)
    changed = False

    if length > 1:
        for index in range(len(array) - 1):
            prefix, pair, postfix = array[:index], array[index:index + 2], array[index + 2:]

            total = sum(pair)

            if total % 2 == 0:
                solutions.extend(sub_sequence([*prefix, total // 2, *postfix]))
                changed = True

    if length < 2 or not changed:
        solutions.append(array)

    return solutions

def main(string):
    unsorted_redundant_sub_sequences = sub_sequence([int(number) for number in string.split()])
    unsorted_non_redundant_strings = set(" ".join(map(str, sequence)) for sequence in unsorted_redundant_sub_sequences)
    sorted_non_redundant_strings = sorted(unsorted_non_redundant_strings, key=lambda x: (len(x), x))
    print(sorted_non_redundant_strings)

main('30 20 10 30 6 6')

输出

> python3 test.py
['18', '19', '19 6', '25 6', '25 10', '25 14', '30 13', '30 15', '30 17', '30 13 6', '30 17 6', '30 15 12', '30 15 18']
> 

答案 1 :(得分:1)

我创建了一些函数来实现目标:

  1. least_check给出True / False序列是否为“最小”(例如'2 4'会返回False,而'3 4'将返回True
  2. find_leasts是递归函数,可将序列分解为问题所示树中的下一个级别(例如'2 2 4 4'将分解为'2 4 4',{{1 }}和'2 3 4'),直到达到所有“最少”
  3. '2 2 4'会创建一个从main函数中提取的所有“最少” yield的列表,并删除所有重复项(例如示例序列有find_leasts两次),并且返回唯一的“最少”列表

答案:

'3'

结果:

def least_check(n):
    check_list = [int(x) for x in n.split(' ')]
    for a, b in zip(check_list[:-1], check_list[1:]):
        if (a + b) % 2 == 0:
            return False
    return True

def find_leasts(n):
    if len(n.split(' ')) == 1:
        yield n
    for i in range(len(n.split(' '))-1):
        s = [int(x) for x in n.split(' ')]
        if (s[i] + s[i+1]) % 2 == 0:
            s[i] = int((s[i] + s[i+1]) / 2)
            s.pop(i+1)
        sub_n = ' '.join(str(j) for j in s)
        if least_check(sub_n):
            yield sub_n
        else:
            yield from find_leasts(sub_n)

def main(s):
    all_leasts = [x for x in find_leasts(s)]
    unique_leasts = list(set(all_leasts))
    return unique_leasts

seq = '2 2 4 4'
print(sorted(main(seq), key=len))

更新

上述解决方案有许多['3', '2 3', '3 4', '2 3 4'] split(),以避免递归函数修改列表引用(列表名称是指向其内存地址的指针-如果需要,请参见{{ 3}},而不是从当前范围以外的其他深度进行解释。

当查看在' '.join()序列上收到的错误并考虑通过this site进行最大递归操作时,sys.setrecursionlimit时,我重新评估了是否甚至需要递归-并确定不是。

以下是迭代解决方案中使用的函数:

  1. '30 20 10 30 6 6'-与原始答案相同
  2. least_check-提取列表并将其分解为树中一级的所有列表(例如break_down将分解为'2 2 4 4''2 4 4'和{ {1}})
  3. '2 3 4'-遍历可能最少的列表队列,直到'2 2 4'中的所有列表都是最小列表
  4. least_lister-执行所有least_listsmain操作,并在返回结果之前删除重复项

迭代解决方案:

split()

迭代结果:

' '.join()

列表参考示例

def least_check(check_list):
    for a, b in zip(check_list[:-1], check_list[1:]):
        if (a + b) % 2 == 0:
            return False
    return True

def break_down(s, ret):
    for i in range(len(s)-1):
        if (s[i] + s[i+1]) % 2 == 0:
            bd_list = s.copy()
            bd_list[i] = int((bd_list[i] + bd_list[i+1]) / 2)
            bd_list.pop(i+1)
            ret.append(bd_list)

def least_lister(n):
    least_lists = []
    if least_check(n):
        least_lists.append(n)
    else:
        i = 0
        break_down(n, least_lists)
        while i < len(least_lists):
            if least_check(least_lists[i]):
                i+=1
            else:
                break_down(least_lists[i], least_lists)
                least_lists.pop(i)
    return least_lists

def main(s):
    s_list = [int(x) for x in s.split(' ')]
    all_leasts = least_lister(s_list)
    unique_leasts = list(set([' '.join(str(j) for j in i) for i in all_leasts]))
    return unique_leasts

seq = '30 20 10 30 6 6'
print(sorted(main(seq), key=len))

列表参考示例输出:

['18', '19', '19 6', '25 6', '25 10', '25 14', '30 13', '30 15', '30 17', '30 13 6', '30 17 6', '30 15 12', '30 15 18']

答案 2 :(得分:0)

让我们逐步了解这个问题。

第一: 数组的第一个数字与第二个数字相加

将结果除以

使用新值创建新数组

甚至

然后在新的Arrey上递归调用

否则,将新的arrey放入静态数据结构中

第二: 首先,我们需要查看所有索引,

将所有内容放入索引I = 0到length-2的循环中

第三: 对静态数组进行处理,根据需要对其进行排序并打印结果。

我对python不太满意,但我希望此伪代码能对您有所帮助。