Ich versuche, die Idee hinter dem Präfixsumme Konzept zu begreifen am Beispiel in der Präfixsumme Lektion von Codility here (Der Pilzsammler Problem)Python - Präfixsumme Algorithmus
Mein Verständnis präsentiert suchen ist, dass die Das gesamte Konzept basiert auf der einfachen Eigenschaft, dass zum Finden einer Summe aller Elemente zwischen zwei Positionen A (pos_left, pos_right) eines Arrays A ein zweites Array P verwendet wird, bei dem alle Elemente nacheinander summiert werden und die gesuchte Summe als
berechnet wird Wert (P (pos_right + 1)) - Wert (P (pos_left)).
A 1 2 3 4 5 6
P 0 1 3 6 10 15 21
sum of all elements between A[2] and A[5] = 3+ 4 + 5 = 12
or using the prefix sums" P[5+1] - P[2] = 15 -3 = 12
Das Problem
Es ist eine Straße mit Pilze an jedem Ort durch einen nicht leeren Vektor dargestellt. Angesichts der ursprünglichen Position eines Pflückers und seines Bewegungsbereichs wird die maximale Anzahl an zu sammelnden Pilzen gesucht.
Mit Blick auf das Beispiel verstehe ich nicht die Logik hinter der Konstruktion der Schleifen. Kann jemand die Mechanik dieses Algorithmus klären?
Zweitens fand ich die Positionsindexierung in diesem Beispiel sehr verwirrend und umständlich. Ist es üblich, den Vektor mit Präfix-Summen mit der Null am Anfang "zu verschieben"? (Die Tatsache, dass das Zählen von Elementen in Vektoren in Python mit 0 beginnt, führt bereits zu Verwirrung).
Die Lösung
def prefix_sums(A):
n = len(A)
P = [0] * (n + 1)
for k in xrange(1, n + 1):
P[k] = P[k - 1] + A[k - 1]
return P
def count_total(P, x, y):
return P[y + 1] - P[x]
# A mushroom picker is at spot number k on the road and should perform m moves
def mushrooms(A, k, m):
n = len(A)
result = 0
pref = prefix_sums(A)
for p in xrange(min(m, k) + 1): # going left
left_pos = k - p
right_pos = min(n - 1, max(k, k + m - 2 * p))
result = max(result, count_total(pref, left_pos, right_pos))
for p in xrange(min(m + 1, n - k)):
right_pos = k + p
left_pos = max(0, min(k, k - (m - 2 * p)))
result = max(result, count_total(pref, left_pos, right_pos))
return result
I einige Beispiel für ein kleines Array ausgeführt haben A= [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
wählten die Position k = 5 und den Bereich m = 3. Ich verstehe nicht die Logik der Bereiche der Schaffung durch die zwei Schleifen zu überprüfen.
ich die folgenden Parameter für die Schleifen
(p=, left_pos=, right_pos=)
loop 1 (0,5,8), (1,4,6),(2,3,5),(3,2,5)
loop 2 (0,2,5), (1,4,6), (2,5,7), (3,5,8)
Die rangies variieren. Warum?
Version für das Debuggen
def mushrooms2(A, k, m):
n = len(A)
result = 0
pref = prefix_sums(A)
l1 =min(m, k) + 1
print 'loop p in xrange(min(m, k) + 1): %d' % l1
for p in xrange(min(m, k) + 1):
print 'p %d' % p
print 'A= %r' % A
print 'pref= %r' % pref
left_pos = k - p
right_pos = min(n - 1, max(k, k + m - 2 * p))
result = max(result, count_total(pref, left_pos, right_pos))
print 'left_pos = k - p= %d' % left_pos
print 'right_pos= min(n-1,max(k,k+m-2*p))= %d' % right_pos
print 'max'
print '(result %d' % result
print 'count_total(pref, left_pos, right_pos)) %r, %r, %r, %r' % (pref,left_pos, right_pos,count_total(pref, left_pos, right_pos))
print 'result= %d' % result
print 'next p'
l2=min(m + 1, n - k)
print 'loop xrange(min(m + 1, n - k)): %d' % l2
for p in xrange(min(m + 1, n - k)):
print 'p %d' % p
print 'A= %r' % A
print 'pref= %r' % pref
right_pos = k + p
left_pos = max(0, min(k, k - (m - 2 * p)))
result = max(result, count_total(pref, left_pos, right_pos))
print 'right_pos = k + p= %d' % right_pos
print 'left_pos = max(0, min(k, k - (m - 2 * p)))= %d' % left_pos
print 'max'
print '(result %d' % result
print 'count_total(pref, left_pos, right_pos)) %r, %r, %r, %r' % (pref,left_pos, right_pos,count_total(pref, left_pos, right_pos))
print 'result= %d' % result
print 'next p'
print 'result %d' % result
return result
Python-Indexierung/Slices sind nullbasiert. Je nachdem, was Sie erreichen möchten, kann die Verwendung von berechneten * Loop-Variablen * für Slices oder Indizes produktiv sein. – wwii