[英]Variation on Bubble Sort infinite loop error
在一個特定的棋盤游戲中,只有一行,它包含 N 個空格,從左到右編號為 0 到 N - 1。 還有 N 個彈珠,編號從 0 到 N - 1,最初以任意順序放置。 之后,有兩個可用的動作,一次只能做一個:
目標是按順序排列彈珠,每個彈珠 i 在 position i 中。
我編寫的代碼適用於發布在問題上的示例(1 3 0 2),但是當我將額外的數字 4 隨機添加到列表中時,while 循環永遠不會終止。 查看排序后的序列,它似乎在重復循環多個相同的序列。 我不確定為什么它適用於一個系列但不適用於下一個系列。
獎勵,我似乎無法弄清楚如何將 output 打印為用空格分隔的數字與用括號和逗號分隔的列表。 問題要求我們將 output 打印為以空格分隔的數字。 對此的任何幫助將不勝感激。
class MarblesBoard:
"""creates a marble board with number marbles in specific spots"""
def __init__(self, marble_sequence):
self.board = [x for x in marble_sequence]
def __str__(self):
return str(self.board)
def __repr__(self):
return "%r " % (self.board)
def switch(self):
"""switch the marbles in position 0 and 1"""
self.board[0], self.board[1] = self.board[1], self.board[0]
return self.board
def rotate(self):
"""Move the marble in position 0 to position N - 1, and move all other marbles one space to the left (one index lower)"""
copy_board = self.board.copy()
copy_board[len(self.board)-1] = self.board[0]
for x in range(1, len(self.board)):
copy_board[x - 1] = self.board[x]
self.board = copy_board
return self.board
def is_sorted(self):
return self.board == sorted(self.board):
class Solver:
"""solves the marble sorting game when given a marble board as input"""
def __init__(self, MarblesBoard):
self.steps = 0
self.board = MarblesBoard.board
return
def solve(self):
n = len(self.board)
# print("n = ", n)
print(self.board)
while MarblesBoard.is_sorted(self) == False:
if self.board[0] > self.board[1]:
MarblesBoard.rotate(self)
print(self.board)
self.steps += 1
else:
MarblesBoard.switch(self)
print(self.board)
self.steps += 1
print("total steps: ", self.steps)
關於 output,代碼在此處適用於示例 output:
board2 = MarblesBoard((1,3,0,2))
solver = Solver(board2)
solver.solve()
[1, 3, 0, 2]
[3, 1, 0, 2]
[1, 0, 2, 3]
[0, 2, 3, 1]
[2, 0, 3, 1]
[0, 3, 1, 2]
[3, 0, 1, 2]
[0, 1, 2, 3]
total steps: 7
但是,如果我在起始板上添加 4:
board2 = MarblesBoard((1,3,0,2,4))
solver = Solver(board2)
solver.solve()
[1, 3, 0, 2, 4]
[3, 1, 0, 2, 4]
[1, 0, 2, 4, 3]
[0, 2, 4, 3, 1]
[2, 0, 4, 3, 1]
[0, 4, 3, 1, 2]
[4, 0, 3, 1, 2]
[0, 3, 1, 2, 4]
[3, 0, 1, 2, 4]
[0, 1, 2, 4, 3]
[1, 0, 2, 4, 3]
[0, 2, 4, 3, 1]
[2, 0, 4, 3, 1]
[0, 4, 3, 1, 2]
[4, 0, 3, 1, 2]
[0, 3, 1, 2, 4]
[3, 0, 1, 2, 4]
請注意,3 0 1 2 4 作為第二次迭代和最后列出的迭代重復。 由於 while 循環的結構,由於發生相同的序列,因此執行相同的步驟並且循環無限繼續。
那么,冒泡排序究竟是如何變化的呢? 大多數排序都有一種方法將已排序和未排序的數據保存在不同的區域中,以便清楚已經排序的數據。 這種似乎並沒有做到這一點。
看起來切換發生的唯一標准是board[0] > board[1]
。 真的只有這些嗎?
我對代碼的建議如下:
class MarblesBoard:
def __init__(self, marble_sequence):
self.board = [x for x in marble_sequence]
是不是有點多余? 為什么不:
class MarblesBoard:
def __init__(self, marble_sequence):
self.board = marble_sequence
我似乎無法弄清楚如何將 output 打印為用空格分隔的數字
這將我帶到您對__str__
的實施:
def __str__(self):
return str(self.board)
那不行。 看看我嘗試在 shell 中執行類似操作時返回的字符串:
>>> str([1, 2, 3])
'[1, 2, 3]'
>>>
你最好使用str.join
:
def __str__(self):
return " ".join(map(str, self.board))
您的switch
方法看起來不錯,除了您不需要從中返回任何內容。 只需交換元素,這就是您需要做的一切。
如果我正確理解了rotate
方法,它可以簡化:
def rotate(self):
self.board.append(self.board.pop(0))
同樣,您不需要從此 function 返回任何內容。
您的is_sorted
也可以簡化:
def is_sorted(self):
return self.board == sorted(self.board)
我也可能會在您的MarblesBoard
class 中添加一個名為should_rotate
的方法,該方法根據求解器是否應該旋轉或切換返回True
或False
。 它打算稍后由求解器使用:
def should_rotate(self):
return self.board[0] > self.board[1]
接下來, Solver
class。 首先是__init__
方法:
通過命名參數MarblesBoard
(與類同名),您將隱藏 class 的標識符 - 所以我不會調用該參數。 我認為marbles_board
是一個更好的名字。
其次,我認為沒有充分的理由在您的__init__
中明確地將steps
設置為實例變量,因為您使用它的唯一地方是在solve
方法中。 我現在就擺脫它。
第三,我認為將self.board
綁定到MarblesBoard
實例的board
object 不是一個好主意。 如果您的Solver
class 基本上只是環繞MarblesBoard.board
,那么您甚至可能不做這個 class 並在MarblesBoard
class 中完成所有求解同樣,您不需要從__init__
顯式return
。
class Solver:
def __init__(self, marbles_board):
self.marbles_board = marbles_board
solve
也可以簡化一點:
def solve(self):
number_of_steps = 0
while not self.marbles_board.is_sorted():
if self.marbles_board.should_rotate():
self.marbles_board.rotate()
else:
self.marbles_board.switch()
number_of_steps += 1
print(f"Number of steps: {number_of_steps}")
有趣的是,您的solve
實現工作得和它一樣好,看看您如何將self
( Solver
對象)作為rotate
和switch
方法的參數傳遞。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.