Labor 5: Python-Listen, Bäume

F2: Gewehrmischung

Das bekannte Rüffelmischen eines Kartenspiels (oder in unserem Fall einer Abfolge von Dingen) führt zu einer neuen Konfiguration von Karten, bei denen auf die oberste Karte die mittlere Karte folgt, dann die zweite Karte, dann die Karte nach der mittleren und so weiter. Angenommen, der Stapel (Reihenfolge) enthält eine gerade Anzahl an Karten, schreiben Sie ein Listenverständnis, das die gemischte Reihenfolge erzeugt.

Hinweis: Um dies als einzelnes Verständnis zu schreiben, finden Sie möglicherweise den Ausdruck k%2, der bei geraden Zahlen 0 und bei ungeraden Zahlen 1 ergibt Zahlen, um nützlich zu sein. Überlegen Sie, wie Sie die von k%2 zurückgegebene 0 oder 1 verwenden können, um alternativ auf den Anfang und die Mitte der Liste zuzugreifen.

 analysieren:

Ich habe direkt den Ausdruck gefunden, der der Regel basierend auf Beispiel 2 entspricht, und ihn dann direkt implementiert.

def riffle(deck):
    """Produces a single, perfect riffle shuffle of DECK, consisting of
    DECK[0], DECK[M], DECK[1], DECK[M+1], ... where M is position of the
    second half of the deck.  Assume that len(DECK) is even.
    >>> riffle([3, 4, 5, 6])
    [3, 5, 4, 6]
    >>> riffle(range(20))
    [0, 10, 1, 11, 2, 12, 3, 13, 4, 14, 5, 15, 6, 16, 7, 17, 8, 18, 9, 19]
    """
    "*** YOUR CODE HERE ***"
    #return [] if len(deck)==0 else deck[0:len(deck)//2]+deck[len(deck)-1:len(deck)//2-1:-1] if len(deck)%2==0 else deck[0:len(deck)//2]+deck[len(deck)-1:len(deck)//2-1:-1]
    #return [] if len(deck)==0 else [deck[x] for x in range(0,len(deck)//2)]+[deck[x] for x in range(len(deck)-1,len(deck)//2-1,-1)]
    return [deck[(i%2)*len(deck)//2+i//2]for i in range(len(deck))]

F4: Blätter sprießen

Definieren Sie eine Funktion sprout_leaves die einen Baum t und eine Liste von Blättern leaves aufnimmt. Es entsteht ein neuer Baum, der mit t identisch ist, bei dem jedoch jeder alte Blattknoten neue Zweige hat, einen für jedes Blatt in leaves.

Angenommen, wir haben den Baum t = tree(1, [tree(2), tree(3, [tree(4)])]):

  1
 / \
2   3
    |
    4

Wenn wir sprout_leaves(t, [5, 6]) aufrufen, ist das Ergebnis der folgende Baum:

       1
     /   \
    2     3
   / \    |
  5   6   4
         / \
        5   6
def sprout_leaves(t, leaves):
    """Sprout new leaves containing the data in leaves at each leaf in
    the original tree t and return the resulting tree.

    >>> t1 = tree(1, [tree(2), tree(3)])
    >>> print_tree(t1)
    1
      2
      3
    >>> new1 = sprout_leaves(t1, [4, 5])
    >>> print_tree(new1)
    1
      2
        4
        5
      3
        4
        5

    >>> t2 = tree(1, [tree(2, [tree(3)])])
    >>> print_tree(t2)
    1
      2
        3
    >>> new2 = sprout_leaves(t2, [6, 1, 2])
    >>> print_tree(new2)
    1
      2
        3
          6
          1
          2
    """
    "*** YOUR CODE HERE ***"

Verwenden Sie Ok, um Ihren Code zu testen:

python3 ok -q sprout_leaves

F5: Verletzen Sie nicht die Abstraktionsbarriere!

Hinweis: Diese Frage enthält keine Code-Schreibkomponente (wenn Sie berry_finder und sprout_leaves richtig implementiert haben!)

Wenn wir Funktionen schreiben, die ein ADT verwenden, sollten wir wann immer möglich den/die Konstruktor(e) und Selektor(e) verwenden, anstatt die Implementierung des ADT anzunehmen. Sich auf die zugrunde liegende Implementierung einer Datenabstraktion zu verlassen, wird als Verletzung der Abstraktionsbarriere bezeichnet, und das wollen wir niemals tun!

Es ist möglich, dass Sie die Doctests für berry_finder und sprout_leaves bestanden haben, selbst wenn Sie die Abstraktionsbarriere verletzt haben. Um zu überprüfen, ob Sie dies getan haben, führen Sie den folgenden Befehl aus:

Verwenden Sie Ok, um Ihren Code zu testen:

python3 ok -q check_abstraction

Die check_abstraction Funktion existiert nur für den Doctest, der die Implementierungen der tree Abstraktion durch etwas anderes austauscht und die Tests der beiden vorherigen ausführt Teile und stellt dann die ursprüngliche Abstraktion wieder her.

Die Art der Abstraktionsbarriere garantiert, dass eine Änderung der Implementierung eines ADT keine Auswirkungen auf die Funktionalität von Programmen haben sollte, die dieses ADT verwenden, solange die Konstruktoren und Selektoren ordnungsgemäß verwendet wurden.

Wenn Sie die OK-Tests für die vorherigen Fragen bestanden haben, diese jedoch nicht, ist die Lösung einfach! Ersetzen Sie einfach jeden Code, der die Abstraktionsbarriere verletzt, z. B. das Erstellen eines Baums mit einem neuen Listenobjekt oder die Indizierung in einen Baum, durch den entsprechenden Konstruktor oder Selektor.

Stellen Sie sicher, dass Ihre Funktionen die Tests sowohl mit der ersten als auch mit der zweiten Implementierung des Tree ADT bestehen und dass Sie verstehen, warum sie für beide funktionieren sollten, bevor Sie fortfahren.

def sprout_leaves(t, leaves):
    """Sprout new leaves containing the data in leaves at each leaf in
    the original tree t and return the resulting tree.

    >>> t1 = tree(1, [tree(2), tree(3)])
    >>> print_tree(t1)
    1
      2
      3
    >>> new1 = sprout_leaves(t1, [4, 5])
    >>> print_tree(new1)
    1
      2
        4
        5
      3
        4
        5

    >>> t2 = tree(1, [tree(2, [tree(3)])])
    >>> print_tree(t2)
    1
      2
        3
    >>> new2 = sprout_leaves(t2, [6, 1, 2])
    >>> print_tree(new2)
    1
      2
        3
          6
          1
          2
    """
    "*** YOUR CODE HERE ***"

Code-1-Analyse:

    # 不能过抽象
    # def find_leaves(t):
    #     for branch in branches(t):
    #         sprout_leaves(branch,leaves)
    #     return t
    # def add_leaves(t):
    #     if is_leaf(t):
    #         t += [tree(x) for x in leaves]
    #         return t
    # find_leaves(t)
    # add_leaves(t)
    # return t

 Code 1 (Q5-Fehler) (Ich hoffe, jemand kann mir einen Rat geben):

Traceback (most recent call last):
  File "D:\pycharm\python document\CS61A class homework\lab05\lab05.py", line 97, in sprout_leaves
    find_leaves(t)
  File "D:\pycharm\python document\CS61A class homework\lab05\lab05.py", line 91, in find_leaves
    sprout_leaves(branch,leaves)
  File "D:\pycharm\python document\CS61A class homework\lab05\lab05.py", line 98, in sprout_leaves
    add_leaves(t)
  File "D:\pycharm\python document\CS61A class homework\lab05\lab05.py", line 95, in add_leaves
    t += [tree(x) for x in leaves]
TypeError: unsupported operand type(s) for +=: 'dict' and 'list'

# Error: expected

# but got
#     Traceback (most recent call last):
#       ...
#     TypeError: unsupported operand type(s) for +=: 'dict' and 'list'

---------------------------------------------------------------------
Test summary
    0 test cases passed before encountering first failed test case

Backup... 50.0% complete

 Code-2-Analyse:

1. Stellen Sie zunächst fest, ob es sich um einen Endlappen handelt

Ja: Neue Blätter hinzufügen

Nein (das heißt, es gibt andere Zweige):

seine Zweige durchqueren

2. Wiederholen Sie die vorherige Arbeit

    #完美代码
    if is_leaf(t):
      return tree(label(t), [tree(x) for x in leaves])
    return tree(label(t), [sprout_leaves(b, leaves) for b in branches(t)])

F6: Bäume hinzufügen

Definieren Sie die Funktion add_trees, die zwei Bäume aufnimmt und einen neuen Baum zurückgibt, bei dem jeder entsprechende Knoten aus dem ersten Baum mit dem Knoten aus dem zweiten Baum hinzugefügt wird. Wenn ein Knoten an einer bestimmten Position in einem Baum vorhanden ist, in dem anderen jedoch nicht, sollte er auch im neuen Baum vorhanden sein.

Hinweis: Möglicherweise möchten Sie die integrierte Zip-Funktion verwenden, um mehrere Sequenzen gleichzeitig zu durchlaufen.

Hinweis: Wenn Sie das Gefühl haben, dass dieses viel schwieriger ist als die vorherigen Baumprobleme, ist das völlig in Ordnung! Das ist ein ziemlich schwieriges Problem, aber Sie können es schaffen! Sprechen Sie mit anderen Studierenden darüber und kommen Sie bei Bedarf darauf zurück.

def add_trees(t1, t2):
    """
    >>> numbers = tree(1,
    ...                [tree(2,
    ...                      [tree(3),
    ...                       tree(4)]),
    ...                 tree(5,
    ...                      [tree(6,
    ...                            [tree(7)]),
    ...                       tree(8)])])
    >>> print_tree(add_trees(numbers, numbers))
    2
      4
        6
        8
      10
        12
          14
        16
    >>> print_tree(add_trees(tree(2), tree(3, [tree(4), tree(5)])))
    5
      4
      5
    >>> print_tree(add_trees(tree(2, [tree(3)]), tree(2, [tree(3), tree(4)])))
    4
      6
      4
    >>> print_tree(add_trees(tree(2, [tree(3, [tree(4), tree(5)])]), \
    tree(2, [tree(3, [tree(4)]), tree(5)])))
    4
      6
        8
        5
      5
    """
    "*** YOUR CODE HERE ***"

analysieren:

1. b1 und b2 sind zwei Zweige, die Bäume hinzufügen

        Holen Sie sich b als leere Liste

2.Henku-Zweigelement

i gehört zu (0-) (für die Anzahl der Elemente in den beiden Zweigen nehmen Sie den Maximalwert))

(1) Wenn i<len1 und <len2:

(Zeigt an, dass die beiden Bäume gemeinsam genutzt werden (Die Zweige, die den Zweig gemeinsam nutzen, können auch unterschiedlich sein), also fahren Sie mit der tiefen Durchquerung fort.)

b.apppend(add_tree(b1[i],b2[i))        

( 2 )i>len1 oder i >len2 (Zweige, die nicht gemeinsam genutzt werden, können direkt hinzugefügt werden)

3. Schließlich zurückgeben: tree(label(b1)+label(b2),b)

( Die Zusätze vor sind Zweige, also ist b der Zweig des gewünschten Baums)

Antwortcode: 

    b1, b2 = branches(t1), branches(t2)
    b = []
    for i in range(max(len(b1), len(b2))):
        if i >= len(b1):
            b.append(b2[i])
        elif i >= len(b2):
            b.append(b1[i])
        else:
            b.append(add_trees(b1[i], b2[i]))
    return tree(label(t1) + label(t2), b)

Vollständiger Antwortcode (Ich habe den cs106l vor kurzem fast zwei Tage lang konfiguriert, aber es war noch nicht erfolgreich. Jemand hat ihn erfolgreich konfiguriert. Bitte schreiben Sie mir privat eine Nachricht. Ich hoffe, Sie haben Zeit): 

Guess you like

Origin blog.csdn.net/2301_79140115/article/details/134840075