问题描述
我目前正在处理货架问题(众所周知,我希望吗?)。本质上,我得到了一个由块(元素)组成的架子(组)的场景,并且应该根据它们的大小重新排列它们。这是插入排序简介的一部分。
此问题的第一部分涉及我编写函数insert_animation(block_pos,shelf,high)
。此功能接收一堆不同大小的块,例如[Block size: 2,Block size: 6,Block size: 1,Block size: 4,Block size: 8,Block size: 3,Block size: 9]
。我得到了函数shelf.insert(position,block)
,该函数在给定位置插入一个块,而函数shelf.pop(position)
,在该位置删除一个元素。
对于这个问题,我应该首先从架子上弹出索引(整数)block_pos处的元素,将弹出的元素与0到high
范围内的每个元素进行比较,然后插入弹出的元素值等于或更大的元素之前。如果没有这样的值(即,弹出元素大于所有内容),则弹出元素将插入到high
的位置(即范围的最后一个位置)。
我想我了解逻辑,并且想出了这样的代码:
def insert_animate(block_pos,high):
if block_pos == 0:
return shelf
p = shelf.pop(block_pos)
for i in range(high):
if p.size <= shelf[i].size:
shelf.insert(i,p)
break
else:
shelf.insert(high,p)
return shelf
让我感到沮丧的是,似乎“ break”语句只是拒绝执行我所说的,并且越来越多的元素不断插入其中。
例如,让s = [Block size: 2,Block size: 9]
(这是一个需要教授给出的程序才能运行的代码,并且仅在Python上不能运行)。
假设我现在要print(insert_animate(3,s,3))
。我希望
[Block size: 2,Block size: 9]
弹出并插入大小为4的块,紧接大小为6的块。
但是有了上面的代码,我得到了
[Block size: 2,Block size: 9]
在我看来,问题在于break
不能正常工作,而for i in range(high)
循环只会继续运行,并会在满足条件时继续插入大小为4的块。
今天,我已经花了好几个小时来解决这个问题,但是想不出办法。这只是随后我所有问题的冰山一角,但是我认为这是问题的根源,因此,如果有人可以就此特定问题提供任何建议,我将不胜感激!
解决方法
TLDR:将for:...else:
与嵌套的if:
一起使用,而不是for:
与嵌套的if:...else:
。只有在循环中没有执行任何else:
的情况下,for
循环的break
子句才会触发–这对应于未找到有效位置,因此需要在末尾插入元素。 / p>
代码当前会为每个不小于此元素的元素插入p
,直到找到一个较小的元素:
def insert_animate(block_pos,shelf,high):
if block_pos == 0:
return shelf
p = shelf.pop(block_pos)
for i in range(high):
if p.size <= shelf[i].size:
shelf.insert(i,p)
break # stop once smaller element is found
else: # triggers *for each i* with p.size > shelf[i].size
shelf.insert(high,p) # insert until loop is stopped
return shelf
将其更改为仅在所有元素不小于时触发:
def insert_animate(block_pos,p)
break
else: # triggers *for all i* with p.size > shelf[i].size
shelf.insert(high,p) # insert at most once
return shelf