基于类的河内塔的实现与栈解决方案的错误

时间:2017-11-02 13:07:12

标签: 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 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")

堆栈类代码(虽然我认为这是错误的并且不适合?)

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)

错误

self.towers = [Stack(), Stack(), Stack()]
   NameError: name 'Stack' is not defined

接受/期望回答:

对于答案的接受,你能不能 1.评论您的解决方案或提供有关堆栈部分中发生的事情的解释 2.提供实现(基于可用的类创建对象)和显示输出的解决方案,如下所示。

**************************** UPDATE ****************** *************:**

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

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")

错误

 for i in range(n, -1, -1):
NameError: name 'n' is not defined

2 个答案:

答案 0 :(得分:1)

最小修改的错误修正:

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")

首先,如果你想给Stacks一个名字,你需要使用dict而不是列表。我还在print函数中添加了moveDisk,其中包含了很多self个错误,并修正了您正在使用的算法。

答案 1 :(得分:0)

以下代码提供了一个代表董事会的河内塔级别,您可以在其中确定钉子和磁盘的数量。然后可以从原点,命运和辅助属性访问Pegs,它们中的最后一个是具有剩余Pegs的列表(默认情况下它使用3但可以是任何数字)。董事会只提供移动方法。最后可以找到两个例子,分别有3个磁盘3个钉子和4个磁盘4个钉子。 Pegs强制执行以正确顺序放置的项目,并且只允许在有一些要提取的项目时提取项目。

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)