Python 解析一个";“订购”;列出并找到各自的总和和加数?
抱歉,如果以前有人问过这个问题,但我已经搜索了几天,没有找到与我的问题相关的帮助 我试图研究的是一种解析列表(类似于预算表)并将索引分配给父级或子级的方法。父项是其子项的总和,子项是该父项的加数(或没有父项的数字) 例如:Python 解析一个";“订购”;列出并找到各自的总和和加数?,python,algorithm,list,sum,stack,Python,Algorithm,List,Sum,Stack,抱歉,如果以前有人问过这个问题,但我已经搜索了几天,没有找到与我的问题相关的帮助 我试图研究的是一种解析列表(类似于预算表)并将索引分配给父级或子级的方法。父项是其子项的总和,子项是该父项的加数(或没有父项的数字) 例如:[1,2,3,6],其中6是1、2和3的父项 或者更复杂的例子:[1,2,3,6,1,4,3,8,14,3,2,3,8,1,4,3,8,16,30] 30是这个列表的“根”,因为30=14+16、14=6+8、6=1+2+3等等。这个列表总是有一定的顺序,也就是说,孩子们总是一
[1,2,3,6]
,其中6是1、2和3的父项
或者更复杂的例子:[1,2,3,6,1,4,3,8,14,3,2,3,8,1,4,3,8,16,30]
30是这个列表的“根”,因为30=14+16、14=6+8、6=1+2+3等等。这个列表总是有一定的顺序,也就是说,孩子们总是一起出现在他们的父母之前(当然,当父母是另一个父母的孩子时除外)。我试图找到最有效的方法,我的两个解决方案使用堆栈,但它们不是100%正确,因为上面的两个示例都失败了。以下是两者的伪代码:
解决方案尝试1
stack = []
for number in list
if stack.isEmpty()
stack.push(number)
elif stack.peek() > number
stack.push(number)
else
copy = stack
temp = []
current = number
while current > 0
popped = copy.pop()
temp.push(popped)
current -= popped
if current == 0
while temp
child = temp.pop()
child.parent = number
stack = copy
stack.push(number)
解决方案尝试2
stack = []
for number in list
stack.push(number)
while stack.size() > 1
child = stack.pop()
copy = stack
temp = []
if child > stack.peek()
while current > 0 and copy.size() > 0
popped = copy.pop()
temp.push(popped)
current -= popped
if current == 0
while temp
child = temp.pop()
child.parent = number
任何想法或想法都将不胜感激。这时我的头撞到了墙上
编辑
复杂示例解决方案
[1,2,3,6,1,4,3,8,14,3,2,3,8,1,4,3,8,16,30]
30
/ \
14 16
/ \ / \
6 8 8 8
/ | \ / | \ / | \ / | \
1 2 3 1 4 3 3 2 3 1 4 3
这是一个有趣的问题。下面是一个使用列表作为树的递归解决方案(根在索引0处,子在以下索引处):
get_tree
的逻辑如下:
- 在迭代数字列表时收集树列表
- 在
中的每个位置,您可以执行以下两项操作之一:nums
- 取树列表末尾的树的任何后缀(
trees[i://code>),并将它们作为子树放在一个新树下,当前编号为根
- 将当前编号作为新树添加到堆栈中
- 取树列表末尾的树的任何后缀(
- 当您到达列表的末尾并且堆栈上只有一棵树时,这就是结果
sorted()
函数和递归
示例(假设输入为非空):
印刷品:
[30, [[14, [[6, [1, 2, 3]], [8, [1, 4, 3]]]], [16, [[8, [3, 2, 3]], [8, [1, 4, 3]]]]]]
[3, [1, 2]]
[6, [1, 2, 3]]
[7, []]
为什么30是列表的根?你能编辑你的问题并发布一些示例输入和预期输出吗?30是“根”父级,因为它是所有其他父级的总和。请参见EDIT。您能为这个复杂的示例提供完整的解释吗?我看到1+2+3=6,但你如何将1,4,3,8,14分组…?你假设所有整数都是正整数吗?可能存在负整数/双精度的边缘情况,但大多数情况下,列表都是正整数。这样的序列是标准的吗,即,有没有唯一的解决方案?如果是,他们肯定有名字。@Vromfondel不确定我是否理解正确。序列是树的后序遍历。通常,多棵树可以生成相同的后序遍历序列。因此,解决方案是否唯一取决于施加的限制。在这种情况下,仅求和限制是不够的(请参见零示例)。但是,对于严格意义上的正数,它应该是,即使我没有正式证明:)
def _get_tree(lst):
new_children, cnt = [], 0
for idx, v in sorted(enumerate(lst[:-1]), key=lambda k: k[1], reverse=True):
cnt += v
new_children.append((idx, v))
if cnt == lst[-1]:
start, new_children = 0, sorted(new_children, key=lambda k: k[0])
for idx2, v2 in new_children:
if idx2 - start == 0:
yield lst[start]
else:
yield [v2, [*_get_tree(lst[start:idx2+1])]]
start = idx2 + 1
break
def get_tree(lst):
return list([lst[-1], [*_get_tree(lst)]])
print(get_tree([1,2,3,6,1,4,3,8,14,3,2,3,8,1,4,3,8,16,30]))
print(get_tree([1, 2, 3]))
print(get_tree([1, 2, 3, 6]))
print(get_tree([1, 2, 3, 7]))
[30, [[14, [[6, [1, 2, 3]], [8, [1, 4, 3]]]], [16, [[8, [3, 2, 3]], [8, [1, 4, 3]]]]]]
[3, [1, 2]]
[6, [1, 2, 3]]
[7, []]