代码说明:输入n为整数,其他输入为list(降序)。例如n=3
,A=list(range(n,0,-1))
,B=[]
,C=[]
(较大的整数表示较大的光盘)。
下面的代码有效,但是输入列表变量(start_
,inter_
,end_
)的名称必须为A
,B
,{{1} },因为Hanoi函数包含全局变量C
,A
,B
。这很烦人。
如何用列表表示每个步骤而没有全局变量?换句话说,基本情况的操作(追加,删除)如何取决于输入位置而不是变量名。
例如:
C
是第二个输入变量,start_
是第四个输入变量。
基本情况操作->第四输入变量。append(第二输入变量[-1], 第二个输入变量.remove(第二个输入变量[-1])
end_
----(start_,inter_,end_)代替第五行的(A,B,C)----
def Hanoi(n,start_,inter_,end_):
if n==1:
end_.append(start_[-1])
start_.remove(start_[-1])
print('start_peg , inter_peg, end_peg :{}\t{}\t{}'.format(A,B,C))
else:
Hanoi(n-1,start_,end_,inter_)
Hanoi(1,start_,inter_,end_)
Hanoi(n-1,inter_,start_,end_)
n=3
A=list(range(n,0,-1))
B,C=[],[]
Hanoi(n,A,B,C) #variable name of three list input must be A,B,C
Out:
start_peg , inter_peg, end_peg :[3, 2] [] [1]
start_peg , inter_peg, end_peg :[3] [2] [1]
start_peg , inter_peg, end_peg :[3] [2, 1] []
start_peg , inter_peg, end_peg :[] [2, 1] [3]
start_peg , inter_peg, end_peg :[1] [2] [3]
start_peg , inter_peg, end_peg :[1] [] [3, 2]
start_peg , inter_peg, end_peg :[] [] [3, 2, 1]
答案 0 :(得分:1)
您可以使用列表列表和可选参数来保留三个列表的顺序。这样,您就可以始终以相同的方式打印它们,同时根据算法需要处理项目:
def Hanoi(n,start_,inter_,end_, pegs=None): # new optional argument
if pegs is None:
pegs = [start_, inter_, end_] # build a list of lists if one was not passed in
if n==1:
end_.append(start_.pop()) # using pop makes this much easier
print('start_peg , inter_peg, end_peg :{}\t{}\t{}'.format(*pegs)) # prints in order
else:
Hanoi(n-1,start_,end_,inter_, pegs) # pass on the list of lists in each recursive call
Hanoi(1,start_,inter_,end_, pegs) # this lets the original order be preserved
Hanoi(n-1,inter_,start_,end_, pegs)
n=3
A=list(range(n,0,-1))
B,C=[],[]
Hanoi(n, A, B, C)
我对您的代码进行了附带更改,以调用list.pop
而不是建立索引,然后调用remove
来摆脱最后一项。这样效率更高(O(1)
而不是O(N)
),也更简单!
更重要的更改是使用列表pegs
的列表来保留最初调用时三个列表的顺序。 print
可以使用它以一致的顺序将它们全部写出。
答案 1 :(得分:0)
如何用没有全局变量的列表表示每个步骤?
答案很简单。只需使用您传入的变量的名称即可:
print('start_peg , inter_peg, end_peg :{}\t{}\t{}'.format(start_, inter_, end_))
这就是python处理对象的方式。对象绑定到给定范围内的名称,但是可以在许多范围内命名。您可以将对象绑定到任意多个名称。
例如,假设您拥有(功能之外)
n = 3
A = list(range(n, 0, -1))
B = []
C = []
这些分配将四个不同的对象(int
和三个list
)绑定到四个不同的名称(n
,A
,B
,{{ 1}})。现在,当您致电
C
将相同的四个对象绑定到函数名称空间中的名称Hanoi(n, A, B, C)
,n
,start_
,inter_
。无论您使用全局名称end_
还是本地名称A
,您都在引用内存中的同一对象。
在不相关的注释上,start_
对值已知的对象执行不必要的按值搜索。由于您已经将值分配给了上面一行中的正确堆栈,因此执行删除操作的一种更简单的方法是
start_.remove(start_[-1])
一个更优雅的解决方案是将这两行替换为
del start_[-1]
答案 2 :(得分:-1)
您可以使用第一个元素为列表“命名”:
n=3, A=["A"]+list(range(n,0,-1)), B=["B"], C=["C"]
并修改打印语句:
print('start_peg , inter_peg, end_peg :{}\t{}\t{}'.format( *sorted((start_, inter_, end_)) ))
排序将在“ A”,“ B”,“ C”上生效。
编辑: 如果您不喜欢上面的解决方案,则可以创建一个新类:
class Hanoi:
def __init__(self,start_):
self.n= len(start_)
self.A,self.B,self.C= start_,[],[]
def go(self):
self.Hanoi(self.n,self.A,self.B,self.C)
def Hanoi(self,n,start_,inter_,end_): # <--- your code
if n==1:
end_.append(start_[-1])
start_.remove(start_[-1])
print(self)
else:
self.Hanoi(n-1,start_,end_,inter_)
self.Hanoi(1,start_,inter_,end_)
self.Hanoi(n-1,inter_,start_,end_)
def __str__(self):
return 'start_peg, inter_peg, end_peg :{}\t{}\t{}'.format(self.A,self.B,self.C)
def get_pegs(self):
return self.A,self.B,self.C
#h=Hanoi(list(range(3,0,-1)))
h=Hanoi([3,2,1])
h.go()
A,B,C= h.get_pegs()
print(A,B,C)
Out:
start_peg, inter_peg, end_peg :[3, 2] [] [1]
start_peg, inter_peg, end_peg :[3] [2] [1]
start_peg, inter_peg, end_peg :[3] [2, 1] []
start_peg, inter_peg, end_peg :[] [2, 1] [3]
start_peg, inter_peg, end_peg :[1] [2] [3]
start_peg, inter_peg, end_peg :[1] [] [3, 2]
start_peg, inter_peg, end_peg :[] [] [3, 2, 1]
[] [] [3, 2, 1]