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