Präfixsummen in C ++

Präfixsummen in C ++
Die Präfix -Summen sind die laufenden Gesamtzahlen der Nummern eines Arrays. Es ist eine weitere vollständige Abfolge von Zahlen. Betrachten Sie beispielsweise die folgende Liste: 5, 2, -6, 8, -4, 0, 9, 3, -1, 7

Es gibt zehn Elemente. Stellen Sie sich eine 0 vor, die dieser Liste vorausgeht.

Dann ist 0 + 5 = 5 die erste Präfix -Summe.
0 + 5 + 2 = 7 ist die nächste Präfix -Summe.
0 + 5 + 2 + -6 = 1 ist die Präfix -Summe danach.
0 + 5 + 2 + -6 + 8 = 9 ist die neue Präfix -Summe.

Diese laufende Gesamtsumme setzt sich in der Regel bis zum letzten Element 7 in der angegebenen Liste fort. Die zweite Sequenz (Liste) hat die Präfixsummen von elf Elementen. Das erste Element im Präfix -Summen -Array (zweite Sequenz) ist die angenommene (imaginäre) Null. Die folgenden zwei Tabellen, in denen die zweite Zeile für jede Tabelle die Null-basierten Array-Indizes aufweist, veranschaulichen diese beiden Sequenzen:

Gegebener Tabelle
5 2 -6 8 -4 0 9 3 -1 7
0 1 2 3 4 5 6 7 8 9
Präfix -Summentabelle
5 7 1 9 5 5 14 17 16 23
0 1 2 3 4 5 6 7 8 9 10

Die erste Tabelle ist für das angegebene Array und die zweite Tabelle ist für das Präfix -Summen -Array. Wenn die Anzahl der Elemente im angegebenen Array n ist, ist die Anzahl der Elemente im Präfix -Summen -Array N+1. Dieser Artikel erläutert die Hauptmerkmale von Präfixsummen. In diesem Zusammenhang bedeutet „Pre-“, was zuvor hinzugefügt wurde. Es kann auch bedeuten, dass das Präfix -Array mit Null vorangestellt wird.

Rohe Gewalt

Ein Programmierer sollte die Bedeutung von roher Kraft kennen, wie sie bei der Programmierung verwendet wird. Brute Force bedeutet, ein Problem mit einem direkten Algorithmus zu lösen, der normalerweise nicht so effizient ist (um weniger Zeit und Speicher zu verwenden) wie ein weiterer sorgfältig gelehrter Algorithmus.

Präfixsumme durch Brute Force

Um das Präfix-Summen-Array durch brutale Kraft für das oben gegebene Array zu erzeugen, wird 5 zunächst als erste Präfix-Summe bezeichnet. Dann werden 5 und 2 hinzugefügt, um das nächste Präfix -Sum zu geben, 7. Dann werden 5, 2 und -6 hinzugefügt, um die Präfix -Summe nach 1 bereitzustellen. Als nächstes werden 5, 2, -6 und 8 hinzugefügt, um das neue Präfix -Summe 9 usw. zu geben. Dieses Verfahren kann anstrengend sein.

Anstrengend oder nicht, der Code zum Erstellen des Präfix -Summen -Arrays aus der angenommenen Null durch Brute -Kraft ist:

int n = 10;
int a [] = 5, 2, -6, 8, -4, 0, 9, 3, -1, 7;
int p [n+1];
P [0] = 0;
für (int i = 0; iint sum = 0;
int j;
für (j = 0; Jsum = sum + a [j];

P [j] = sum;

Die äußere For-Loop iteriert von 0 bis nur weniger als N. Die innere For-Loop iteriert von 0 bis i, der Iterationsindex der äußeren Schleife. Damit gibt es 55 Hauptoperationen. Die zeitliche Komplexität dafür ist o (n.Protokoll2N).

Präfixsummen in der linearen Zeit

Die vorherige Zeitkomplexität beträgt ungefähr o (n).Protokoll2N). Der Algorithmus kann so verbessert werden, dass die Summen in linearer Zeit für die Zeitkomplexität O (N) erzeugt werden. Präfix in diesem Zusammenhang bedeutet, die Summe aller vorherigen Elemente dem aktuellen gegebenen Element hinzuzufügen. Betrachten Sie die beiden vorherigen Tabellen, die als eine Tabelle gezeichnet werden, mit einigen Modifikationen:

Präfix -Summentabelle
Gegeben: 5 2 -6 8 -4 0 9 3 -1 7
0 + 5 = 5 + 2 = 7 + -6 = 1 + 8 = 9 + -4 = 5 + 0 = 5 + 9 = 14+3 = 17+ -1 = 16+7 =
0 5 7 1 9 5 5 14 17 16 23
0 1 2 3 4 5 6 7 8 9 10

Die erste Zeile in dieser Tabelle enthält die angegebenen Elemente an ihren zugewiesenen Positionen. Für die zweite und dritte Reihen wird die Startnull angenommen. Für die zweite und dritte Zeilen entspricht jedes Element der Summe aller vorherigen Elemente sowie dem aktuellen Element. Die letzte Zeile hat die Präfix-Summen-Array-Indizes (null basiert). Beachten Sie, dass das Array des Präfix -Summen ein Element länger als das angegebene Array ist.

Dieser Algorithmus erzeugt das Präfix -Summen -Array in der linearen Zeit von O (n) Zeitkomplexität. Das heißt, es gibt ungefähr N -Operationen. Und der empfohlene Präfix -Summencode in C ++ für o (n) Zeitkomplexität lautet:

int n = 10;
int a [] = 5, 2, -6, 8, -4, 0, 9, 3, -1, 7;
int p [n+1];
P [0] = 0;
für (int i = 1; iP [i] = P [i-1] + a [i-1];

Beachten Sie, dass diesmal keine verschachtelte Schleife vorhanden ist. Die Aussagen in den Klammern der For-Schleife sind wesentlich. Der Hauptbetrieb des For-Loop-Körpers ist ebenfalls wichtig. Nach wie vor iteriert der For-Loop von 1 bis weniger als N+1 und nicht von 0 bis weniger als N. Die Aussage des For-Loop-Körpers lautet:

P [i] = P [i-1] + a [i-1];

Dies bedeutet, dass der aktuelle Wert des angegebenen Arrays dem vorherigen Präfix -Sum.

Häufiges Problem für Präfixsummen

Beachten.

Ein häufiges Problem für Präfix-Summen ist es, die Summe eines Unterarrays aufeinanderfolgender Elemente effizient zu finden. Dies ist die Summe einer Scheibe. Das Wort „effizient“ bedeutet, dass ein brutaler Kraftalgorithmus nicht verwendet werden darf. Die begrenzenden Indizes für das Sub-Array sind x und y. Betrachten Sie die angegebene Liste:

5, 2, -6, 8, -4, 0, 9, 3, -1, 7

Die Summe des Sub-Array von Element 8 bis Element 9 lautet:

8 + -4 + 0 + 9 = 13

8 ist bei Index 3 für x; und 9 ist bei Index 6 für y. Die effiziente Möglichkeit, dies zu tun. Für das Präfix -Array sind diese Index y+1 und Index x. Die zugefügte 1 wird entfernt, um den unten gezeigten Präfix -Array -Index zu erhalten, und der effiziente Code lautet:

int n = 10;
int a [] = 5, 2, -6, 8, -4, 0, 9, 3, -1, 7;
int p [n+1];
P [0] = 0;
int x = 3, y = 6;
für (int i = 1; iP [i] = P [i-1] + a [i-1];

Int Slicesum = P [y+1] - P [x];
Cout<Die Ausgabe ist wie erwartet 13, jedoch aus einem effizienten Code.

Abschluss

Die Präfix -Summen sind die laufenden Gesamtsummen der Elemente eines Arrays. Zwei Arrays sind beteiligt: ​​das angegebene Array und das erzeugte Präfix -Summen -Array. Das Präfix -Summen -Array ist länger als das angegebene Array von einem Element. Der Hauptvorgang, um die Elemente des Präfix -Arrays zu erhalten. Verwenden Sie, um die Summe eines Scheibens aus dem angegebenen Array zu erhalten: INT Slicesum = P [y+1] - P [x];

Wobei x der untere Grenzindex des Schichts im angegebenen Array ist und y der Obergrenzeindex des Slice im angegebenen Array ist.