Universität Karlsruhe Einstieg in die Informatik und algorithmische

Werbung
Universität Karlsruhe
SS 2005
Institut für Angewandte Mathematik II
Dr. K. Grüner
Dipl.-Math. J.-P. Weiß
17. Mai 2005
Praktikum zu
Einstieg in die Informatik und algorithmische Mathematik
Programmieren mit C++
Aufgabenblatt 5
Bearbeitungszeitraum: 18. Mai - 31. Mai 2005
Aufgabe 13: Sieb des Eratosthenes
Pflichtaufgabe bis 31. Mai!
Das Sieb des Eratosthenes wird verwendet, um eine Tabelle der Primzahlen bis zu einer vorgegebenen Zahl N zu erzeugen.
Wenn n √
≤ N gilt und n keine Primzahl ist, so muß n durch eine Primzahl p teilbar sein, für
die p ≤ N gilt. Aus der Liste der Zahlen 1, 2, 3, 4, . . . , N streicht man somit nacheinander
die folgenden Zahlen:
• 1 (1 ist keine Primzahl)
• 4, 6, 8, 10, . . . , d.h. 22 und alle weiteren geraden Zahlen
• 9, 15, 21, 27, . . . , d.h. 32 und alle weiteren Vielfachen von 3, die noch nicht gestrichen
sind
• 25, 35, 55, 65, . . . , d.h. 52 und alle weiteren Vielfachen von 5, die noch nicht gestrichen
sind
Das
√ Verfahren wird mit der nächsten noch verfügbaren Zahl fortgesetzt, bis diese größer als
N ist. Die Zahlen, die übrig bleiben, sind die gesuchten Primzahlen.
Schreiben Sie ein C++-Programm, das alle Primzahlen bis N = 10000 mit Hilfe des beschriebenen Verfahrens bestimmt. Gehen Sie wie folgt vor:
• Vereinbaren Sie ein Feld geeigneten Typs und geeigneter Größe und initialisieren Sie dieses
mit den Zahlen von 1 bis N .
• Das Streichen einer Zahl erfolgt durch das Nullsetzen des entsprechenden Wertes im Feld.
• Streichen Sie zunächst die 1 und setzen sie eine Laufvariable n auf den Wert 2.
• Durchlaufen Sie eine Schleife von n2 bis N , in der Sie alle Vielfachen der Laufvariablen
streichen.
• Bestimmen sie den nächsten Wert der Laufvariablen, indem Sie die nächste Zahl ungleich
Null verwenden. Wiederholen Sie dann den vorangehenden Punkt.
√
• Brechen Sie ab, wenn die Laufvariable n den Wert N erreicht hat.
• Geben Sie die ermittelten Primzahlen mit 10 Zahlen pro Zeile auf dem Bildschirm aus.
Verwenden Sie zum Testen zunächst kleinere Werte für N .
Aufgabe 14: Determinantenberechnung
Pflichtaufgabe bis 31. Mai!
Die Determinante det(A) einer reellen n × n Matrix


a11 a12 · · · a1n
 a21 a22 · · · a2n 


A =  .. ..
..  = (aij )i,j=1,...,n
 . .
. 
ann
an1 · · ·
soll durch den folgenden Algorithmus berechnet werden:
1.) Zunächst wird die Matrix A in ein Produkt zweier n × n Matrizen L = (lij ) und U = (uij )
zerlegt, d.h. es gilt A = L · U , wobei L eine links-untere Dreiecksmatrix und U eine
rechts-obere Dreiecksmatrix ist. Die Koeffizienten von L und U berechnen sich dabei wie
folgt:

Für j = 1, . . . , i



j−1

X




=
a
−
lik · ukj
l
ij
ij




k=1





 Falls lii 6= 0
Für i = 1, . . . , n
Für j = i +
n
Ã1, . . . ,i−1
!


X




lik · ukj /lii
uij = aij −



k=1





Falls lii = 0




Abbruch und Fehlermeldung
2.) Die Determinante von A ergibt sich dann als Produkt der Diagonalelemente von L:
det(A) =
n
Y
k=1
lkk = l11 · l22 · · · lnn .
Anmerkung: Die Diagonalelemente von U werden hier als 1 gewählt, jedoch nicht gesetzt.
Es gilt dann die Formel det(A)= det(L · U )= det(L)·det(U )=det(L).
Setzen Sie den oben angegebenen Algorithmus in ein C++-Programm um. Das Programm soll
dabei die folgenden Teile enthalten:
• Lesen Sie die Größe n der Matrix A ein.
• Erstellen Sie zweidimensionale, dynamische Felder zur Darstellung der reellen n × n Matrizen A, L und U und initialisieren Sie diese mit Nullen.
• Lesen Sie die Matrix A elementweise ein.
• Bestimmen Sie die Determinante der Matrix A gemäß 1.) und 2.) und geben Sie das
Ergebnis aus.
• Geben Sie den belegten Speicherplatz wieder frei.
Bestimmen Sie die Determinanten der Matrizen




2 1 0 −2
¶
µ
3 1 2

1 3
1 3 3 −1 

,  4 1 3 , 
 3 2 4 −3  .
2 5
−1 1 5
2 −2 2 3
(Ergebnis: -1,-7, 85)
• Lesen Sie eine ganze Zahl N > 1 vom Typ int ein.
• Vereinbaren Sie zwei Felder prim und expo vom Typ int der festen Größe 20.
• Implementieren Sie eine Funktion int kT(int n), die zu einer ganzen Zahl n > 1 deren
kleinsten Teiler d > 1 bestimmt. Z.B. ist der kleinste Teiler der Zahl 8 die 2, von 21 ist
3 der kleinste Teiler und von 17 die 17 selbst. Bestimmen Sie den kleinsten Teiler nach
dem folgenden Algorithmus.
d := 1;
Wiederhole
d := d + 1;
bis d ein Teiler von n ist
Ist d ein Teiler von n, so gilt n%d = 0. Beachten Sie, daß dieser Algorithmus nicht
sonderlich gut ist, da als kleinste Teiler nur Primzahlen in Frage kommen.
• Bestimmen Sie die Primfaktorzerlegung von N gemäß
Wiederhole
d =kT(n);
n = n/d;
bis n = 1
Hinweise:
1. Beachten Sie die Indexverschiebung von {1, . . . , n} nach {0, . . . , n−1} in C++. Sie können
dieses Problem umgehen, indem Sie Felder der Größe n + 1 vereinbaren und jeweils die
erste Zeile und Spalte nicht belegen.
2. Der angegebene Algorithmus scheitert, wenn nicht alle lii ungleich Null sind. Das bedeutet
jedoch nicht, daß die Determinante dann Null sein muß. In diesem Fall ist es erforderlich
zunächst Zeilenvertauschungen in der Matrix A (mit Hilfe der Pivotsuche, vgl. Vorlesung)
durchzuführen, wodurch der Wert der Determinante bis auf das Vorzeichen nicht geändert
wird.
Aufgabe 15: Primfaktorzerlegung
(freiwillig, keine Pflichtaufgabe!)
Hierbei ergeben die Werte für d die Folge der Primfaktoren. Die Primfaktoren treten
entsprechend ihrer Vielfachheit oft auf.
• Legen Sie die Primfaktoren ohne Wiederholungen in dem Feld prim ab. In das Feld
expo legen Sie die entsprechenden Vielfachheiten ab. So ergeben sich z. B. für die Zahl
7260 = 22 · 31 · 51 · 112 die Felder prim= [2, 3, 5, 11, 0, . . . , 0] und expo= [2, 1, 1, 2, 0, . . . , 0].
• Erzeugen Sie eine Ausgabe der Form
Die Primfaktoren von 7260 sind
2 mit der Vielfachheit 2
3 mit der Vielfachheit 1
5 mit der Vielfachheit 1
11 mit der Vielfachheit 2
Eine ganze Zahl N > 1 besitzt eine eindeutige Zerlegung in ihre Primfaktoren der Form
N = pα1 1 · pα2 2 · . . . · pαMM .
Hierbei sind die pi , i = 1, . . . , M , Primzahlen und die Exponenten αi , i = 1, . . . , M , ihre
Vielfachheiten. Eine Primzahl ist eine Zahl, die außer durch eins und sich selbst durch keine
weitere Zahl ganzzahlig ohne Rest teilbar ist. Erstellen Sie ein C++-Programm, das zu einer
vorgebenen Zahl deren Primfaktorzerlegung bestimmt. Gehen Sie dabei wie folgt vor.
Testen Sie ihr Programm mit den Zahlen 1296, 149396, 29791, 40071, 9699690. Überprüfen
Sie das Ergebnis, indem Sie sich klarmachen, daß die gefundenen Primfaktoren in der Tat
Primzahlen sind und multiplizieren Sie diese zur Probe mit dem Taschenrechner miteinander.
Welche Primfaktorzerlegung besitzt Ihr Geburtsdatum in achtstelliger Schreibweise (z.B. 17052005)?
Herunterladen