Sitzung: Jeden Freitag in der Vorlesungszeit ab 16 Uhr c. t. im MAR 0.005. In der vorlesungsfreien Zeit unregelmäßig (Jemensch da?). Macht mit!

Javakurs/Übungsaufgaben/Primzahlenaufgabe: Unterschied zwischen den Versionen

K (format)
Zeile 3: Zeile 3:
 
Als [http://de.wikipedia.org/wiki/Primzahl Primzahlen] bezeichnet man alle natürlichen Zahlen die nur durch sich selbst und eins teilbar sind. Also zum beispiel 3, 5, 7, 11, 13, usw. Die 1 ist per definition keine Primzahl.
 
Als [http://de.wikipedia.org/wiki/Primzahl Primzahlen] bezeichnet man alle natürlichen Zahlen die nur durch sich selbst und eins teilbar sind. Also zum beispiel 3, 5, 7, 11, 13, usw. Die 1 ist per definition keine Primzahl.
  
==Einfacher Primzahlen finder==  
+
==Einfacher Primzahlenfinder==  
'''Mindestkenntnisse:''' Schleifen, Basistypen, Bedingungen
 
  
 
'''Aufgabe:'''  
 
'''Aufgabe:'''  
Zeile 12: Zeile 11:
 
'''Hinweise:'''
 
'''Hinweise:'''
  
* Der simpelste Algorithmus um zu ermitteln ob eine Zahl x eine Primzahl ist, ist einfach x durch jede Zahl kleiner als x zu teilen und zu überprüfen ob ein Rest übrig bleibt.
+
* Der simpelste Algorithmus um zu ermitteln ob eine Zahl x eine Primzahl ist, besteht darin x durch jede Zahl kleiner als x zu teilen und zu überprüfen ob ein Rest übrig bleibt.
  
Für die 25 würde der Algorithmus also folgendermassen ablaufen:
+
Für die 25 würde der Algorithmus also folgendermaßen ablaufen:
  
 
25 / 2 = 12 rest 1<br>
 
25 / 2 = 12 rest 1<br>
Zeile 21: Zeile 20:
 
25 / 5 = 5 rest 0 -> 25 ist keine Primzahl
 
25 / 5 = 5 rest 0 -> 25 ist keine Primzahl
  
Wenn der Algorithmuss durchgelaufen ist ohne einen Teiler für x gefunden zu haben muss x eine Primzahl sein.
+
Wenn der Algorithmus durchgelaufen ist ohne einen Teiler für x gefunden zu haben muss x eine Primzahl sein.
  
* Der operator % gibt den Rest zurück der beim teilen von zwei Zahlen übrig bleibt.
+
* Der Modulo-Operator % gibt den Rest zurück der beim Teilen von zwei Zahlen übrig bleibt.
  
* Ihr braucht zwei verschachtelte Schleifen, eine welche die zu überprüfende Zahlen 1 bis n hochzählt und eine die jede dieser Zahlen durch jede kleinere Zahl teilt um auf teilbarkeit zu überprüfen.
+
* Ihr braucht zwei verschachtelte Schleifen, eine welche die zu überprüfende Zahlen 1 bis n hochzählt und eine die jede dieser Zahlen durch jede kleinere Zahl teilt um auf Teilbarkeit zu überprüfen.
  
  
 
==Optimierung des Algorithmus==
 
==Optimierung des Algorithmus==
  
'''Mindestkenntnisse:''' Schleifen, Basistypen, Bedingungen, Arrays<br>
+
'''Vorbemerkung:'''
'''empfohlenen Kenntnisse:''' Schleifen, Basistypen, Bedingungen, Arrays, Methoden
 
  
'''Vorbemerkung:'''
+
Diese Aufgabe kann auf vielerlei Arten gelößt werden und ist weniger zum verstehen von Schleifen, Arrays, Bedingungen und Co gedacht, sondern vielmehr um die sinnvolle Anwendung dieser Konzepte zu üben.
  
Diese Aufgabe kann auf vielerlei Arten gelösst werden und ist weniger zum verstehen von Schleifen, Arrays, Bedingungen und Co gedacht
+
Die Hinweise sind nur als Anregungen zum Lösen der Aufgabe gedacht falls man selbst gar keine Idee hat.  
sondern vielmehr um die sinnvolle Anwendung dieser Konzepte zu üben.
 
Die Hinweise sind nur als Anregungen zum lösen der Aufgabe gedacht falls man selbst gar keine Idee hat.  
 
 
Da es viele Möglichkeiten gibt die Aufgabe zu lösen, die Hinweise jedoch nur einen Weg aufzeigen, solltet ihr erstmal probieren selbst eine Lösung zu finden.
 
Da es viele Möglichkeiten gibt die Aufgabe zu lösen, die Hinweise jedoch nur einen Weg aufzeigen, solltet ihr erstmal probieren selbst eine Lösung zu finden.
  
Zeile 45: Zeile 41:
 
Tatsächlich reicht es wenn man x nur auf Teilbarkeit durch alle Primzahlen die kleiner als x/2 sind überprüft (warum dies so ist wird weiter unten beim Punkt "Hintergrund" erklärt).
 
Tatsächlich reicht es wenn man x nur auf Teilbarkeit durch alle Primzahlen die kleiner als x/2 sind überprüft (warum dies so ist wird weiter unten beim Punkt "Hintergrund" erklärt).
  
Optimiert nun den Algorithmuss aus Aufgabe a) so dass zum überprüfen von Zahl x nur alle Primzahlen kleiner x/2 durchlaufen werden.  
+
Optimiert nun den Algorithmuss aus Aufgabe a) so dass zum Überprüfen von Zahl x nur alle Primzahlen kleiner x/2 durchlaufen werden.  
  
 
'''Optionale Aufgabe:'''
 
'''Optionale Aufgabe:'''
  
Wieviele Primzahlen gibt es zwischen 1 und 10? Wieviele zwischen 1 und 100? 1 und 1000? ...
+
Wie viele Primzahlen gibt es zwischen 1 und 10? Wieviele zwischen 1 und 100? 1 und 1000? ...
  
 
Schreibt euch ein Programm (oder eine Methode) die euch das Verhältniss von gefundenen Primzahlen zu der Anzahl der überprüften Zahlen ausgibt.
 
Schreibt euch ein Programm (oder eine Methode) die euch das Verhältniss von gefundenen Primzahlen zu der Anzahl der überprüften Zahlen ausgibt.
Zeile 55: Zeile 51:
 
'''Hinweise:'''   
 
'''Hinweise:'''   
  
* Speichert euch beim durchlaufen der Zahlen jede gefundene Primzahl in einem Array.
+
* Speichert euch beim Durchlaufen der Zahlen jede gefundene Primzahl in einem Array.
  
* Wie groß muss das Array zum speichern der gefundenen Primzahlen in Abhängigkeit von der Anzahl der zu überprüfenden Zahlen maximal sein? Die optionale Aufgabe hilft dies herrauszufinden.
+
* Wie groß muss das Array zum Speichern der gefundenen Primzahlen in Abhängigkeit von der Anzahl der zu überprüfenden Zahlen maximal sein? Die optionale Aufgabe hilft dies herauszufinden.
  
  
 
'''Hintergrund:'''
 
'''Hintergrund:'''
  
Der Algorithmus aus Aufgabe a ist zwar einfach aber nicht gerade sehr intelligent. Beispielsweise würde es auch reichen beim überprüfen einer Primzahl x nur die ersten x/2 Zahlen zu durchlaufen da beim teilen durch alle grösseren Zahlen nur noch ein Wert zwischen 1 und 2 rauskommen kann.
+
Der Algorithmus aus Aufgabe a ist zwar einfach aber nicht gerade sehr intelligent. Beispielsweise würde es auch reichen beim Überprüfen einer Primzahl x nur die ersten x/2 Zahlen zu durchlaufen da beim Teilen durch alle größeren Zahlen nur noch ein Wert zwischen 1 und 2 rauskommen kann.
  
 
Veranschaulichung:
 
Veranschaulichung:
  
23 / 11 = 2 rest 1<br>
+
23 / 11 = 2 rest 1<br>
23 / 12 = 1 rest 11<br>
+
23 / 12 = 1 rest 11<br>
23 / 13 = 1 rest 10<br>
+
23 / 13 = 1 rest 10<br>
23 / 14 = 1 rest 9<br>
+
23 / 14 = 1 rest 9<br>
...<br>
+
...<br>
23 / 22 = 1 rest 1<br>
+
23 / 22 = 1 rest 1<br>
  
Eine weitere Optimierungsmöglichkeit stellt die Tatsache dar dass eine Zahl die nicht durch zwei teilbar ist, auch nicht durch ein vielfaches von zwei teilbar sein wird. Praktisch heisst das, dass wir die zu überprüfende Zahl nur auf teilbarkeit durch die ungeraden Zahlen sowie der zwei überprüfen müssen.
+
Eine weitere Optimierungsmöglichkeit stellt die Tatsache dar, dass eine Zahl die nicht durch zwei teilbar ist, auch nicht durch ein vielfaches von zwei teilbar sein wird. Praktisch heißt das, dass wir die zu überprüfende Zahl nur auf Teilbarkeit durch die ungeraden Zahlen sowie der zwei überprüfen müssen.
  
 
Beispiel:
 
Beispiel:
  
25 / 2 = 12 rest 1 -> nicht durch zwei teilbar also auch nicht durch 4, 6, 8, 10, usw. -> nur ungerade Zahlen überprüfen<br>
+
* 25 / 2 = 12 rest 1 -> nicht durch zwei teilbar also auch nicht durch 4, 6, 8, 10, usw. -> nur ungerade Zahlen überprüfen<br>
25 / 3 = 8 rest 1<br>
+
* 25 / 3 = 8 rest 1<br>
25 / 5 = 5 rest 0 -> keine Primzahl<br>
+
* 25 / 5 = 5 rest 0 -> keine Primzahl<br>
  
 
Wie man sieht spart man hier schon ein paar Überprüfungen.
 
Wie man sieht spart man hier schon ein paar Überprüfungen.
  
Die Regel dass alle Zahlen die nicht durch 2 teilbar sind auch nicht durch ein vielfaches von 2 teilbar sind lässt sich noch verallgemeinern. Das heisst:
+
Die Regel, dass alle Zahlen die nicht durch 2 teilbar sind auch nicht durch ein Vielfaches von 2 teilbar sind lässt sich noch verallgemeinern. Das heißt:
  
 
Eine Zahl die nicht durch x teilbar ist, ist auch nicht durch ein vielfaches von x teilbar.  
 
Eine Zahl die nicht durch x teilbar ist, ist auch nicht durch ein vielfaches von x teilbar.  
  
Dies bedeutet im Endeffekt dass wir beim überprüfen von x nur alle Primzahlen kleiner x / 2 überprüfen müssen. Da alle anderen Zahlen Vielfache einer kleineren Zahl sind welche wir schon überprüft haben.
+
Dies bedeutet im Endeffekt dass wir beim Überprüfen von x nur alle Primzahlen kleiner x / 2 überprüfen müssen. Da alle anderen Zahlen Vielfache einer kleineren Zahl sind welche wir schon überprüft haben.

Version vom 7. April 2007, 14:59 Uhr

Primzahlen

Als Primzahlen bezeichnet man alle natürlichen Zahlen die nur durch sich selbst und eins teilbar sind. Also zum beispiel 3, 5, 7, 11, 13, usw. Die 1 ist per definition keine Primzahl.

Einfacher Primzahlenfinder

Aufgabe:

Schreibt ein Programm das die ersten n Primzahlen bestimmt und ausgibt.

Hinweise:

  • Der simpelste Algorithmus um zu ermitteln ob eine Zahl x eine Primzahl ist, besteht darin x durch jede Zahl kleiner als x zu teilen und zu überprüfen ob ein Rest übrig bleibt.

Für die 25 würde der Algorithmus also folgendermaßen ablaufen:

25 / 2 = 12 rest 1
25 / 3 = 8 rest 1
25 / 4 = 6 rest 1
25 / 5 = 5 rest 0 -> 25 ist keine Primzahl

Wenn der Algorithmus durchgelaufen ist ohne einen Teiler für x gefunden zu haben muss x eine Primzahl sein.

  • Der Modulo-Operator % gibt den Rest zurück der beim Teilen von zwei Zahlen übrig bleibt.
  • Ihr braucht zwei verschachtelte Schleifen, eine welche die zu überprüfende Zahlen 1 bis n hochzählt und eine die jede dieser Zahlen durch jede kleinere Zahl teilt um auf Teilbarkeit zu überprüfen.


Optimierung des Algorithmus

Vorbemerkung:

Diese Aufgabe kann auf vielerlei Arten gelößt werden und ist weniger zum verstehen von Schleifen, Arrays, Bedingungen und Co gedacht, sondern vielmehr um die sinnvolle Anwendung dieser Konzepte zu üben.

Die Hinweise sind nur als Anregungen zum Lösen der Aufgabe gedacht falls man selbst gar keine Idee hat. Da es viele Möglichkeiten gibt die Aufgabe zu lösen, die Hinweise jedoch nur einen Weg aufzeigen, solltet ihr erstmal probieren selbst eine Lösung zu finden.

Aufgabe:

Um zu ermitteln ob eine Zahl x eine Primzahl ist muss man diese nicht durch sämtliche kleineren Zahlen teilen. Tatsächlich reicht es wenn man x nur auf Teilbarkeit durch alle Primzahlen die kleiner als x/2 sind überprüft (warum dies so ist wird weiter unten beim Punkt "Hintergrund" erklärt).

Optimiert nun den Algorithmuss aus Aufgabe a) so dass zum Überprüfen von Zahl x nur alle Primzahlen kleiner x/2 durchlaufen werden.

Optionale Aufgabe:

Wie viele Primzahlen gibt es zwischen 1 und 10? Wieviele zwischen 1 und 100? 1 und 1000? ...

Schreibt euch ein Programm (oder eine Methode) die euch das Verhältniss von gefundenen Primzahlen zu der Anzahl der überprüften Zahlen ausgibt.

Hinweise:

  • Speichert euch beim Durchlaufen der Zahlen jede gefundene Primzahl in einem Array.
  • Wie groß muss das Array zum Speichern der gefundenen Primzahlen in Abhängigkeit von der Anzahl der zu überprüfenden Zahlen maximal sein? Die optionale Aufgabe hilft dies herauszufinden.


Hintergrund:

Der Algorithmus aus Aufgabe a ist zwar einfach aber nicht gerade sehr intelligent. Beispielsweise würde es auch reichen beim Überprüfen einer Primzahl x nur die ersten x/2 Zahlen zu durchlaufen da beim Teilen durch alle größeren Zahlen nur noch ein Wert zwischen 1 und 2 rauskommen kann.

Veranschaulichung:

23 / 11 = 2 rest 1
23 / 12 = 1 rest 11
23 / 13 = 1 rest 10
23 / 14 = 1 rest 9
...
23 / 22 = 1 rest 1

Eine weitere Optimierungsmöglichkeit stellt die Tatsache dar, dass eine Zahl die nicht durch zwei teilbar ist, auch nicht durch ein vielfaches von zwei teilbar sein wird. Praktisch heißt das, dass wir die zu überprüfende Zahl nur auf Teilbarkeit durch die ungeraden Zahlen sowie der zwei überprüfen müssen.

Beispiel:

  • 25 / 2 = 12 rest 1 -> nicht durch zwei teilbar also auch nicht durch 4, 6, 8, 10, usw. -> nur ungerade Zahlen überprüfen
  • 25 / 3 = 8 rest 1
  • 25 / 5 = 5 rest 0 -> keine Primzahl

Wie man sieht spart man hier schon ein paar Überprüfungen.

Die Regel, dass alle Zahlen die nicht durch 2 teilbar sind auch nicht durch ein Vielfaches von 2 teilbar sind lässt sich noch verallgemeinern. Das heißt:

Eine Zahl die nicht durch x teilbar ist, ist auch nicht durch ein vielfaches von x teilbar.

Dies bedeutet im Endeffekt dass wir beim Überprüfen von x nur alle Primzahlen kleiner x / 2 überprüfen müssen. Da alle anderen Zahlen Vielfache einer kleineren Zahl sind welche wir schon überprüft haben.