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错误。