终止货架问题中的循环
Terminating the loop in the shelf problem
我目前正在处理货架问题(我希望这是相当有名的?)。本质上,我得到了一个架子(集合)块(元素)的场景,我应该根据它们的大小重新排列它们。这是插入排序简介的一部分。
这个问题的第一部分涉及我编写一个函数 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, 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
else:
shelf.insert(high, p)
return shelf
令我沮丧的是,“break”语句似乎只是拒绝按我说的去做,而且越来越多的元素不断被插入。
比如让s = [Block size: 2, Block size: 6, Block size: 1, Block size: 4, Block size: 8, Block size: 3, Block size: 9]
(这是需要教授给运行的程序的代码,单独在Python上是行不通的)
假设现在我想要print(insert_animate(3, s, 3))
。我希望
[Block size: 2, Block size: 4, Block size: 6, Block size: 1, Block size: 8, Block size: 3, Block size: 9]
其中大小为 4 的块被弹出并插入到大小为 6 的块之前。我希望合理吗?
但是使用上面的代码,我得到
[Block size: 2, Block size: 4, Block size: 6, Block size: 1, Block size: 4, Block size: 8, Block size: 3, Block size: 9]
在我看来,问题是 break
无法正常工作,而 for i in range(high)
循环简单地保持 运行ning 并在满足条件时不断插入大小为 4 的块。
今天我已经为此绞尽脑汁好几个小时了,但想不出解决办法。这只是我后来所有问题的冰山一角,但我认为这是问题的根源,所以如果有人能就这件事提供任何建议,我将不胜感激!!!
TLDR:使用 for:...else:
和嵌套 if:
,而不是 for:
和嵌套 if:...else:
。 for
循环的 else:
子句只有在循环中没有执行 break
时才会触发——这对应于没有找到有效位置,因此需要在末尾插入元素。
当前代码为每个不小于的元素插入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, 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
else: # triggers *for all i* with p.size > shelf[i].size
shelf.insert(high, p) # insert at most once
return shelf
我目前正在处理货架问题(我希望这是相当有名的?)。本质上,我得到了一个架子(集合)块(元素)的场景,我应该根据它们的大小重新排列它们。这是插入排序简介的一部分。
这个问题的第一部分涉及我编写一个函数 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, 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
else:
shelf.insert(high, p)
return shelf
令我沮丧的是,“break”语句似乎只是拒绝按我说的去做,而且越来越多的元素不断被插入。
比如让s = [Block size: 2, Block size: 6, Block size: 1, Block size: 4, Block size: 8, Block size: 3, Block size: 9]
(这是需要教授给运行的程序的代码,单独在Python上是行不通的)
假设现在我想要print(insert_animate(3, s, 3))
。我希望
[Block size: 2, Block size: 4, Block size: 6, Block size: 1, Block size: 8, Block size: 3, Block size: 9]
其中大小为 4 的块被弹出并插入到大小为 6 的块之前。我希望合理吗?
但是使用上面的代码,我得到
[Block size: 2, Block size: 4, Block size: 6, Block size: 1, Block size: 4, Block size: 8, Block size: 3, Block size: 9]
在我看来,问题是 break
无法正常工作,而 for i in range(high)
循环简单地保持 运行ning 并在满足条件时不断插入大小为 4 的块。
今天我已经为此绞尽脑汁好几个小时了,但想不出解决办法。这只是我后来所有问题的冰山一角,但我认为这是问题的根源,所以如果有人能就这件事提供任何建议,我将不胜感激!!!
TLDR:使用 for:...else:
和嵌套 if:
,而不是 for:
和嵌套 if:...else:
。 for
循环的 else:
子句只有在循环中没有执行 break
时才会触发——这对应于没有找到有效位置,因此需要在末尾插入元素。
当前代码为每个不小于的元素插入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, 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
else: # triggers *for all i* with p.size > shelf[i].size
shelf.insert(high, p) # insert at most once
return shelf