Python 探索所有子序列

Python 探索所有子序列,python,python-3.x,recursion,Python,Python 3.x,Recursion,我已经试了几天来解决这个问题,但没有成功 关于此问题: 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 le

我已经试了几天来解决这个问题,但没有成功

关于此问题:

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']
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']
[0, 1, 2]
[0, 1, 2]
给定一个序列'2 4 4'

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

如果这两个数的和是一个可被2整除的数,我们替换这两个数,并把这两个数的结果放在例子中:(2+2=4,4/2=2),所以新的序列是(244),但这里我应该找到所有可能的序列。 如果找不到可除以2的偶数,则返回序列

它应该是什么样子的图片

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

我的代码:

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')
def recFunc(n):
对于范围内的i(len(n)):

如果i+1让我们一步一步地看这个问题

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

将结果除以二

使用新值创建一个新数组

如果是偶数

然后在新的arrey上调用recursive

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

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

将所有内容放在一个循环中,从索引I=0到长度-2

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


我不擅长python,但我希望这段伪代码能对您有所帮助。

我创建了几个函数来实现这一目标:

  • least\u检查
    给出一个
    True
    /
    False
    序列是否为“least”(例如
    '24'
    将返回
    False
    ,而
    '34'
    将返回
    True
  • find_leasts
    这是一个递归函数,它将序列分解到问题所示树中的下一级(例如
    '2 2 2 4'
    将分解为
    '2 4'
    '2 3 4'
    '2 2 4'
    ),直到它到达所有的“leasts”
  • main
    find_leats
    函数创建所有“leats”
    yield
    ed的列表,并删除任何重复项(例如,示例序列有两次
    '3'
    ),并返回唯一“leats”列表
  • 回答:

    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']
    
    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']
    
    [0, 1, 2]
    [0, 1, 2]
    
    结果:

    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']
    
    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']
    
    [0, 1, 2]
    [0, 1, 2]
    
    更新:

    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']
    
    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']
    
    [0, 1, 2]
    [0, 1, 2]
    
    上述解决方案有许多
    split()
    s和
    '.join()
    s,以避免递归函数从当前范围以外的深度修改列表引用(列表名称是指向其内存地址的指针-如果需要,请参阅以获取进一步解释)

    当查看在
    '30 20 10 30 6'
    序列上收到的错误,并考虑到通过is使用最大递归时,我重新评估了递归是否必要,并确定它不是

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

  • 最少检查
    -与原始答案相同
  • break\u down
    -获取一个列表,并将其分解为树中一级的所有列表(例如
    '2 2 2 4'
    将分解为
    '2 4'
    '2 3 4'
    '2 2 4'
  • least_-lister
    -迭代潜在最小列表的队列,直到
    least_-lister
    中的所有列表都是最小列表
  • main
    -执行所有
    split()
    '.join()
    操作,并在返回结果之前删除重复项
  • 迭代解:

    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']
    
    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']
    
    [0, 1, 2]
    [0, 1, 2]
    
    列表参考示例

    def add_to_list(n):
        n.append(len(n))
        print(n)
    
    a = [0, 1]
    
    add_to_list(a)
    print(a)
    
    列出参考示例输出:

    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']
    
    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']
    
    [0, 1, 2]
    [0, 1, 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')
    

    非常感谢您的回复,它通过函数收益率在内存中节省了空间,但是字符串和int之间有很多转换,所以如果我放一个longer字符串“seq='302010066'”它转到RecursionError:在获取object@LordNord我的回复太长,无法发表评论,请查看我的回复的更新。感谢您的回复,即使回复太长,您的代码也工作得很完美,问题是当我尝试使用retu时,我应该递归地解决它rn而不是yield,我不知道为什么,但它只解树的左侧(如图所示,我的意思是这棵树),即使我递归地解,它也不会去红色矩形(如图所示),你有什么解决方案吗?@LordNord你的递归只在左边出现的原因是列表名引用了一个内存地址。我在回答中添加的列表引用示例说明了这一点。深入解释了原因,并探讨了可能的解决方法。问题是,即使实现一个,就像我在原始答案中所做的那样,您将得到与我在执行
    '302010306'
    序列时相同的maxrecursion错误。