0

今日クラスでクイズを出しましたが、惨めに失敗しました。クイズは以下のとおりです。誰かが私にこれを説明するのを手伝ってもらえますか.

  1. Link からリンクを「すぐ左側」で切断するメソッドを Link に追加しopen()て、チェーンを右側に切断しないでネックレスを開くようにします。たとえば、 でネックレスをつかむとlink1、呼び出しはからlink1.open()切断されますが、チェーンを保持している は からに接続されたままになります。link3link1link1link3

これは私が現在持っているものです:

class Diamond(object):
    def __str__(self):
        return "Diamond"

class Ruby(object):
    def __str__(self):
        return "Ruby"

class Visitor:
    def __str__(self):
        return self.__class__.__name__

class Link(object):
    def __init__(self, index, jewel = None):
        self.jewel = jewel
        self.index = index

    def connectTo(self, link):
        self.nextLink = link

    def __next__(self):
        return self.nextLink or None

    def attach(self, jewel):
        if not self.jewel:
            self.jewel = jewel

    def detatch(self):
        stone = self.jewel
        self.jewel = None
        return stone

    def open(self):
        pass

    def __str__(self):
        return "link%d" % (self.index)

class Necklace(object):
    def __init__(self, base):
        self.base = base

    def describe(self):
        link = self.base
        while True:
            print link, "with", link.jewel, "attatched to", link.nextLink, "with", link.nextLink.jewel
            link = link.nextLink
            if link == self.base:
                break

    def getJewel(self):
        link = self.base
        while True:
            link = link
            if isinstance(link.jewel, Diamond):
                print "a", link.detatch()
                break
            link = link.nextLink
            if link == self.base:
                print "nothing..."
                break

    def acceptVisitor(self, visitor):
        visitor.visit(self)

class DiamondThief(object, Visitor):
    def __init__(self, base):
        self.base = base
        self.jewel = self.base.jewel

    def visit(self, necklace):
        necklace.getJewel()

    def searchForDiamond(self):
        self.visit(myNecklace)

link1 = Link(1, Ruby())
link2 = Link(2, Diamond())
link3 = Link(3, Ruby())
link1.connectTo(link2)
link2.connectTo(link3)
link3.connectTo(link1)
myNecklace = Necklace(link1)
myNecklace.describe()

print "Uh on here comes a thief..."
thief = DiamondThief(link1)
print "Oh no he took "
thief.searchForDiamond()
myNecklace.describe()
4

2 に答える 2

1

各クラスで必要な関数を見てみましょう。

  1. Link
    • 変数
      • name(かもしれないだけ)
      • linked_toまたnextlink
      • jewel
    • メソッド
      • connectTo(self,link)
      • attach(self,jewel)
      • detach(self)
      • open(self)
      • get_next(self)
  2. Necklace(以下のコードではありません。独自に作成してください)
    • 変数
      • connections
    • メソッド
      • __next__(self)またnext_link(self)
  3. DiamondThief
    • 変数
      • link
      • diamond
    • メソッド
      • getDiamond(self)
      • search(self)
  4. JewelsのようなDiamondまたはRuby
    • 変数またはメソッドなし

このコードを参照してください。DiamondThief クラスも追加しました...

class Necklace:
    '''My version of necklace'''
    def __init__(self, link):
        self.first = link
        self.current_link = link
    def next(self):
        self.current_link = self.current_link.get_next()
        if self.current_link == self.first:
            raise StopIteration
        return self.current_link
    def __iter__(self):
        return self

class Link(object):
    """A link of a necklace"""
    def __init__(self, name, jewel=None):
        self.name = name
        self.linkedTo = None
        self.jewel = None
        if jewel != None:
            self.attach(jewel)

    def connectTo(self, link):
        '''Connect to link'''
        if isinstance(link,Link):
            self.linkedTo = link
        else:
            raise TypeError

    def attach(self, jewel):
        '''Attach jewel'''
        if self.jewel == None:
            self.jewel = jewel
        else:
            msg = 'There is already a %s attached' % jewel.__class__.__name__
            raise AttributeError(msg)

    def detach(self):
        '''Detach jewel'''
        if self.jewel != None: # 
            je = self.jewel
            self.jewel = None
            return j
        else:
            msg = 'There is nothing to detach'
            raise AttributeError(msg)

    def __str__(self):
        if self.linkedTo != None:
            return "%s(%s) => %s" % \
                   (self.name,self.jewel.__class__.__name__, self.linkedTo.name)
        else:
            return "%s(%s) => %s" % \
                   (self.name,self.jewel.__class__.__name__,None)

    def get_next(self):
        '''Get the next chain'''
        return self.linkedTo

class Diamond(object):
    pass

class Ruby(object):
    pass

class DiamondThief:
    def __init__(self, necklace):
        self.necklace = necklace
        self.diamond = None

    def search(self):
        '''Go link by link to find the Diamond'''
        if self.diamond != None:
            print 'Have a diamond already'
            return 
        first = self.necklace.first
        link = first
        for link in self.necklace: # loop till
            if isinstance(link.jewel, Diamond): # diamond is found
                self.diamond = link.jewel
                link.jewel = None
                print 'Found Diamond'
                break

    def getDiamond(self):
        if self.diamond != None:
            return self.diamond
        else:
            return None

def main():
    # create
    l1 = Link('1',Diamond())
    l2 = Link('2',Ruby())
    l3 = Link('3', Ruby())
    l1.connectTo(l2)
    l2.connectTo(l3)
    l3.connectTo(l1)
    i = DiamondThief()
    try:
        l2.attach(Ruby())
    except AttributeError,e:
        print e
    print l1
    print l2
    print l3
    print '-'*16
    i.search()
    print l1
    print l2
    print l3
main()
于 2013-03-08T08:17:54.243 に答える
0

パート 1 では、Linkクラスで説明されているメソッドを使用して、指定されたネックレスを作成するように単純に求めています。

link1 = Link()
link1.attach(Ruby())
link2 = Link()
link2.attach(Diamond())
link3 = Link()
link3.attach(Ruby())

link1.connectTo(link2)
link2.connectTo(link3)
link3.connectTo(link1)

myNecklace = link1

パート 2 では、Link クラスと DiamondThief クラスの実装が必要です。

Linkを二重にリンクされたリストとして実装する方法は次のとおりです。このパートで実行する必要がある基本的なメソッドを実装するために 2 番目のリンクは実際には必要ありませんがopen、左と右の両方の隣接リンクへの参照があれば、パート 3 での追加がはるかに簡単になります。

class Link(object):
    def __init__(self):
        """Initialize an empty link."""
        self.left = None
        self.right = None
        self.jewel = None

    def connectTo(self, other):
        """Connect another link to the right of this one."""
        if self.right or other.left:
            raise ValueError("Links already have connections")
        self.right = other
        other.left = self

    def attach(self, jewel):
        """Add a jewel to this link."""
        if self.jewel:
            raise ValueError("Link already has a jewel attached")
        self.jewel = jewel

    def detatch(self):
        """Remove and return the jewel attached to this link."
        jewel = self.jewel
        self.jewel = None
        return jewel

DiamondThiefこれがビジターの私の実装です。主な方法は、ダイヤモンドが見つかるか、ループする (または開いたネックレスの端から外れる) まで、visit後続のインスタンスを再帰的に訪問することです。再帰の代わりにループをLink使って同じことを行うこともできますが、こちらの方が簡単に思えました。再帰呼び出しの式は、 if is None (デフォルトではこれになります)が として渡されることを意味することにwhile注意してください。orfirstlinkfirst

class DiamondThief(object):
    def __init__(self):
        """Initialize a DiamondThief"""
        self.diamond = None

    def visit(self, link, first=None):
        """Recursively visit a necklace, searching for a Diamond to steal."""
        if link == first: # looped
            return
        if isinstance(link.jewel, Diamond): # diamond found
            self.diamond = link.detatch()
            return
        if link.right is not None: # not at an open end
            self.visit(link.right, first or link)

    def getDiamond(self):
        return self.diamond

パート 3 では、クラスopenにメソッドを追加するよう求められます。Linkは二重にリンクされているためLink、現在の位置の左側でリストを分割するのは簡単です。単一リンクリストとして実装した場合、最初のインスタンスにリンクされたものを見つけるまで、ネックレス全体をスキャンする必要があります (各リンクからその右隣まで)。ループを形成していないネックレスではまったく機能しません。

とにかく、ここに簡単な実装があります:

def open(self):
    """Disconnect this link from it's left neighbor."""
    if self.left is None:
        raise ValueError("Link is not connected on the left")
    self.left.right = None
    self.left = None
于 2013-03-08T10:48:21.970 に答える