Python 基于类的Hanoi塔的实现

Python 基于类的Hanoi塔的实现,python,class,Python,Class,作为OOP的初学者,我希望能得到一些关于如何实现以下解决方案的指导。我希望它能像我的其他解决方案那样打印河内塔楼的解决方案(例如,从1号杆移动到3号杆,等等) 我想要的实现/期望的输出如下所示: Enter the height (no. of discs) in your tower:3 =For a tower of height: 3 ....here is the solution====== Move disc from First Pole to Last Pole Move d

作为OOP的初学者,我希望能得到一些关于如何实现以下解决方案的指导。我希望它能像我的其他解决方案那样打印河内塔楼的解决方案(例如,从1号杆移动到3号杆,等等)

我想要的实现/期望的输出如下所示:

Enter the height (no. of discs) in your tower:3

=For a tower of height: 3 ....here is the solution======

Move disc from First Pole to Last Pole
Move disc from First Pole to Second Pole
Move disc from Last Pole to Second Pole
Move disc from First Pole to Last Pole
Move disc from Second Pole to First Pole
Move disc from Second Pole to Last Pole
Move disc from First Pole to Last Pole

...and you're done!
很明显,我很高兴变量可以引用第一个极点,第二个极点,或者仅仅是A,B,C,以便于编码

当前代码

class TowerOfHanoi:
     def __init__(self, numDisks):
         self.numDisks = numDisks
         self.towers = [Stack(), Stack(), Stack()]
         for i in range(n, -1, -1):
             towers[0].push(i);

     def moveDisk(src, dest):
         towers[dest].push(towers[src].pop())

     def moveTower(n, src, spare, dest):
        if n == 0:
            moveDisk(src, dest)
        else:
            moveTower(n-1, src,dest, spare)
            moveDisk(src, dest)

tower=TowerOfHanoi(3)
tower.moveTower(3,"A","B","C")
堆栈类代码(尽管我认为这是错误的,不太适合?)

错误

self.towers = [Stack(), Stack(), Stack()]
   NameError: name 'Stack' is not defined
 for i in range(n, -1, -1):
NameError: name 'n' is not defined
接受/期望答案:

你能接受我的回答吗 1.评论您的解决方案或解释堆栈部分中发生的情况 2.提供实现(基于工作的类创建对象)和显示输出的解决方案,如下所示

****************************更新****************************************:**

我也试过这个,我真的不明白它是如何结合在一起的,这就是为什么需要解释的原因。。。它还出现了一个错误

class TowerOfHanoi:
     def __init__(self, numDisks):
         self.numDisks = numDisks
         self.towers = [Stack(), Stack(), Stack()]
         for i in range(n, -1, -1):
             towers[0].push(i);

     def moveDisk(src, dest):
         towers[dest].push(towers[src].pop())

     def moveTower(n, src, spare, dest):
        if n == 0:
            moveDisk(src, dest)
        else:
            moveTower(n-1, src,dest, spare)
            moveDisk(src, dest)

class Stack:
     def __init__(self):
         self.items = []

     def isEmpty(self):
         return self.items == []

     def push(self, item):
         self.items.append(item)

     def pop(self):
         return self.items.pop()

     def peek(self):
         return self.items[len(self.items)-1]

     def size(self):
         return len(self.items)

n=int(input("Enter n"))
tower=TowerOfHanoi(3)
tower.moveTower(3,"A","B","C")
错误

self.towers = [Stack(), Stack(), Stack()]
   NameError: name 'Stack' is not defined
 for i in range(n, -1, -1):
NameError: name 'n' is not defined

下面的代码提供了一个Hanoi Tower类,表示一个可以确定销钉和磁盘数量的板。然后可以从origin、destiny和aux属性访问这些peg,最后一个属性是包含剩余peg的列表(默认情况下,它使用3,但可以是任意数字)。该板仅提供移动方法。最后可以找到两个示例,分别是3个圆盘3个销钉和4个圆盘4个销钉。钉子强制项目按正确的顺序放置,并且只允许在有一些项目要提取时提取项目

class Disk:
    def __init__(self, size):
        self.size = size

    def __repr__(self):
        return "<Disk size={}>".format(self.size)

    def __eq__(self, other):
        if hasattr(other, 'size'):
            return self.size == other.size
        return NotImplemented

    def __ne__(self, other):
        if hasattr(other, 'size'):
            return self.size != other.size
        return NotImplemented

    def __lt__(self, other):
        if hasattr(other, 'size'):
            return self.size < other.size
        return NotImplemented

    def __le__(self, other):
        if hasattr(other, 'size'):
            return self.size <= other.size
        return NotImplemented

    def __gt__(self, other):
        if hasattr(other, 'size'):
            return self.size > other.size
        return NotImplemented

    def __ge__(self, other):
        if hasattr(other, 'size'):
            return self.size >= other.size
        return NotImplemented


class Peg:
    def __init__(self, _id):
        self.id = _id
        self.__items = []

    def __repr__(self):
        return "<Peg {} {}>".format(self.id, self.__items)

    def __len__(self):
        return len(self.__items)

    def is_empty(self):
        return len(self) == 0

    def fits(self, item):
        if self.is_empty():
            return True
        return self.__items[-1] > item

    def push(self, item):
        if self.fits(item):
            self.__items.append(item)
        else:
            raise ValueError("Item {} doesn't fit in peg {}".format(item, self.id))

    def pop(self):
        if not self.is_empty():
            return self.__items.pop()
        else:
            raise ValueError("Peg {} does not have any item.".format(self.id))

    def peek(self):
        if not self.is_empty():
            return self.__items[-1]
        else:
            raise ValueError("Peg {} does not have any item.".format(self.id))

class TowerOfHanoi:
    def __init__(self, disks=3, pegs=3):
        self.origin = Peg('origin')
        self.destiny = Peg('destiny')
        self.aux = [Peg('aux{}'.format(i)) for i in range(1, pegs-1)]
        for i in range(disks, 0, -1):
            self.origin.push(Disk(i))

    def __repr__(self):
        return "<ToH from={} to={} by={}>".format(self.origin, self.destiny, self.aux)

    def move(self, frm, to):
        to.push(frm.pop())
        print("Moved {} from {} to {}.".format(to.peek(), frm.id, to.id))



tower = TowerOfHanoi()

tower.move(tower.origin,  tower.destiny)
tower.move(tower.origin,  tower.aux[0])
tower.move(tower.destiny, tower.aux[0])
tower.move(tower.origin,  tower.destiny)
tower.move(tower.aux[0],  tower.origin)
tower.move(tower.aux[0],  tower.destiny)
tower.move(tower.origin,  tower.destiny)

print(tower)


tower_4_4 = TowerOfHanoi(4, 4)

tower_4_4.move(tower_4_4.origin,  tower_4_4.destiny)
tower_4_4.move(tower_4_4.origin,  tower_4_4.aux[0])
tower_4_4.move(tower_4_4.destiny, tower_4_4.aux[0])
tower_4_4.move(tower_4_4.origin,  tower_4_4.aux[1])
tower_4_4.move(tower_4_4.origin,  tower_4_4.destiny)
tower_4_4.move(tower_4_4.aux[1],  tower_4_4.destiny)
tower_4_4.move(tower_4_4.aux[0],  tower_4_4.aux[1])
tower_4_4.move(tower_4_4.aux[0],  tower_4_4.destiny)
tower_4_4.move(tower_4_4.aux[1],  tower_4_4.destiny)

print(tower_4_4)
类磁盘:
定义初始值(自身,大小):
self.size=大小
定义报告(自我):
返回“”格式(self.size)
定义(自身、其他):
如果hasattr(其他“尺寸”):
返回self.size==other.size
返回未执行
定义(自身、其他):
如果hasattr(其他“尺寸”):
返回self.size!=其他尺寸
返回未执行
定义(自身、其他):
如果hasattr(其他“尺寸”):
返回self.size=其他.size
返回未执行
等级挂钩:
定义初始化(自,id):
self.id=\u id
self.\uu项目=[]
定义报告(自我):
返回“”。格式(self.id、self.\u项)
定义(自我):
返回透镜(自身项目)
def为空(自身):
返回长度(自身)==0
def配合(自身、项目):
如果self.is_为空():
返回真值
返回自。\u项目[-1]>项目
def推送(自身,项目):
如果自身适合(项目):
self.\u items.append(项目)
其他:
raise VALUERROR(“项{}不适合peg{}”。格式(项,self.id))
def pop(自我):
如果不是self.is_为空():
返回self.\u items.pop()
其他:
raise VALUERROR(“Peg{}没有任何项。”.format(self.id))
def peek(自):
如果不是self.is_为空():
返回自己的项目[-1]
其他:
raise VALUERROR(“Peg{}没有任何项。”.format(self.id))
河内第三类:
def uuu init uuuu(self,disks=3,pegs=3):
self.origin=Peg(‘origin’)
self.destiny=Peg(‘destiny’)
self.aux=[Peg('aux{}'.格式(i))表示范围(1,pegs-1)中的i]
对于范围内的i(磁盘,0,-1):
self.origin.push(磁盘(i))
定义报告(自我):
返回“”格式(self.origin、self.destiny、self.aux)
def移动(自身、frm、to):
to.push(frm.pop())
打印(“将{}从{}移动到{}..format(to.peek(),frm.id,to.id))
塔楼=塔楼
塔。移动(塔。原点,塔。命运)
tower.move(tower.origin,tower.aux[0])
塔.移动(塔.命运,塔.辅助[0])
塔。移动(塔。原点,塔。命运)
塔.移动(塔.辅助[0],塔.原点)
塔。移动(塔。辅助[0],塔。命运)
塔。移动(塔。原点,塔。命运)
印刷品(塔式)
塔楼4=河内塔楼(4,4)
塔4。移动(塔4。原点,塔4。命运)
塔4.移动(塔4.原点,塔4.辅助[0])
塔4.移动(塔4.命运,塔4.辅助[0])
塔4.移动(塔4.原点,塔4.辅助[1])
塔4。移动(塔4。原点,塔4。命运)
塔4.移动(塔4.辅助[1],塔4.命运)
塔4.移动(塔4.辅助[0],塔4.辅助[1])
塔4.移动(塔4.辅助[0],塔4.命运)
塔4.移动(塔4.辅助[1],塔4.命运)
印刷品(塔架4)

修改最少的错误更正:

class TowerOfHanoi:
     def __init__(self, numDisks, src, spare, dest):
         self.numDisks = numDisks
         self.towers = {
                        src: Stack(),
                        spare: Stack(),
                        dest: Stack()
                       }
         for i in range(n, 0, -1):
             self.towers[src].push(i);

     def moveDisk(self, src, dest):
         self.towers[dest].push(self.towers[src].pop())
         print("{} --> {}".format(src, dest))

     def moveTower(self, n, src, spare, dest):
        if n >= 1:
            self.moveTower(n-1, src, dest, spare)
            self.moveDisk(src, dest)
            self.moveTower(n-1, spare, src, dest)

class Stack:
     def __init__(self):
         self.items = []

     def isEmpty(self):
         return len(self) == 0

     def push(self, item):
         self.items.append(item)

     def pop(self):
         if not self.isEmpty():
             return self.items.pop()
         else:
             raise IndexError("pop from empty Stack")

     def peek(self):
         return self.items[len(self.items)-1]

     def __len__(self):
         return len(self.items)

n = int(input("Enter n: "))
tower = TowerOfHanoi(n, "A", "B", "C")
tower.moveTower(n, "A", "B", "C")

首先,如果要给堆栈命名,需要使用
dict
而不是列表。我还向
moveDisk
函数添加了一个
print
,相当多的
self
s,您丢失了它们,并更正了您使用的算法。

看起来您只是将调用
Stack()
作为存根,希望有人能为您填充其余的部分?这个错误没有多大意义,因为它似乎是意料之中的。但是要明白,SO不是一种代码编写服务。您需要发布解决方案的最佳尝试,然后就您遇到的问题提出具体问题。请发布您的
堆栈
类代码。我有一个堆栈类实现如下-更新您需要导入的代码
堆栈
。鉴于您显示的错误,它不会将其拾取。顺便说一句,您可以使用
self.items[-1]
访问最后一个元素。谢谢您的帮助,但我希望对发布的原始代码进行解答/修复,而不仅仅是一个全新的解决方案