Primzahlenausgabe mit Ober- und Untergrenze

Status
Nicht offen für weitere Antworten.
B

blörk

Gast
Hallo liebe Javaianer,
ich brauche mal wieder eure Hilfe.
Meine heutige Aufgabe ist es ein Programm zu entwerfen dass ca. so aussieht am ende:

Primzahlen:
Bitte Obergrenze eingeben : 25
Die Primzahlen von 1 bis 25 lauten :
2 3 5 7 11 13 17 19 23



Das ganze muss auf einfachstem Niveau mit For- und While Schleifen gelöst werden.
Der Lehrer hat uns ein paar Infolinks zu Primzahlen zur verfügung gestellt mit denen ich allerdings auch nich viel anfangen kann.
Ich hoffe ihr könnt mir helfen.
Einzige Hilfe :
http://www.mathematik.de/ger/information/landkarte/zahlen/primzahlen.html

Primzahltest von Fermat... aber irgendwie steh ich aufm Schlauch.
 
G

Gast

Gast
1. Obergrenze erfahren
2. Schleife bis obergrenze
3. in der schleife die regeln anwenden (bedenke, dass du nur durch die zahlen bis zur haelfte der obergrenze teilen musst) siehe einfach auch in deinem link das systematische entfernen. Hier könnte man z.B. eine While-Schleife nehmen, die als Abbruchbedingung deine ("Teilervariable" > Obergrenze/2) hat.

Damit sollteste jedenfalls schonmal vom Schlauch runter sein.
 
B

blörk

Gast
Also ich habs mal mühsam versucht in ne whileschleif ezu basteln nach dem Text unter der Quelle die ich oben angegeben habe.
Aber iwie gibts mir nur 1 aus xD und das ewig hintereinandern...
Geht das so überhaupt? oder muss dafür die Obergrenze eine Primzahl sein?
Oder hab ich einfach nur ein Fehler in der Programmierung?


Code:
GFS : Primzahlen
Ziel : Eingabe Obergrenze-> Ausgabe der Primzahlen von 1 bis Obergrenze
*/

import java.io.*;
public class PRIM

{
	public static void main (String argv [])throws IOException
	{
		//Deklaration der Variablen
		int obergrenze;
		int h;
		int a;
		int ergebnis;
		int p;
		
		//Deklaration der Hilfvariablen
		String str;
		
		//Eingabeobjekt anlegen
		BufferedReader eingabe = new BufferedReader (new InputStreamReader ( System.in));
		
		
		
		//Eingabe von Wert obergrenze
		System.out.print("Bitte obergrenze eingeben : ");
		
		//Auslesen der Eingabe und Übergabe in "str"
		str= eingabe.readLine();
		
		//Zuweisung des Wertes von "str" in Variable " obergrenze"
		obergrenze = Integer.parseInt(str);
		
		a=1;
		p= obergrenze -1;
		
		while ( a < obergrenze)
		{
		h=(a+1)^(p-1);
		ergebnis=h%5;
		if (ergebnis = 1)
		{
		System.out.println(" " + a);
		}
		}
		

}
}

helft mir^^ ich bin am verzweifeln^^
 

downtimes

Neues Mitglied
Also ich hab mir jetzt nicht angeschaut obs noch wanderst hackt.. aber du solltest dein a auch hochzählen in der While-Schleife.
So wie du das im moment machst ist a in jedem durchlauf immer 1 und dann ist es kein Wunder das so nen Bockmist rauskommt

MFG
 

ARadauer

Top Contributor
ich würde das trennen. ich würde die überprüfung ob das eine primzahl ist, einfach in eine methode auslagern..

Code:
while ( a < obergrenze) 
      { 
      h=(a+1)^(p-1); 
      ergebnis=h%5; 
      if (ergebnis = 1) 
      { 
      System.out.println(" " + a); 
      } 
      }
a und obergrenze wird nirgends verändert... macht wenig sinn..


Code:
public static void main (String argv [])throws IOException 
      { 
         //Deklaration der Variablen 
         int obergrenze; 
         int aktuell = 1;

         //Deklaration der Hilfvariablen 
         String str; 

         //Eingabeobjekt anlegen 
         BufferedReader eingabe = new BufferedReader (new InputStreamReader ( System.in)); 



         //Eingabe von Wert obergrenze 
         System.out.print("Bitte obergrenze eingeben : "); 

         //Auslesen der Eingabe und Übergabe in "str" 
         str= eingabe.readLine(); 

         //Zuweisung des Wertes von "str" in Variable " obergrenze" 
         obergrenze = Integer.parseInt(str); 
       
         while ( aktuell <= obergrenze)
         { 
            if (isPrime(aktuell)) 
            { 
               System.out.print(" " + aktuell); 
            } 
            aktuell++;
         } 


      } 


      public static boolean isPrime(int value){
         // hier deine analyse
      }
 

Leroy42

Top Contributor
blörk hat gesagt.:
...ein Programm zu entwerfen dass ca. so aussieht am ende:

Primzahlen:
Bitte Obergrenze eingeben : 25
Die Primzahlen von 1 bis 25 lauten :
2 3 5 7 11 13 17 19 23
Hmmh! Wie wär's mit:
???:L

Code:
class Primzahlen {
  public static void main(String[] args) {
    System.out.println("Primzahlen:");
    System.out.println("Bitte Obergrenze eingeben : 25");
    System.out.println("Die Primzahlen von 1 bis 25 lauten :");
    System.out.println("2   3   5    7    11   13  17   19   23  ");
  }
}

(SCNR :cool: )
 

0x7F800000

Top Contributor
ooooh mannooooh.... jetzt kommen die schon wieder mit probedivisionen hier angekrabbelt^^ :roll:
DAS IST LAAAAAHM!!!
Es wurde hier doch schon ein Link auf Sieb des Eratosthenes gepostet.
Diese verlinkte Seite.... www.mathematik.de... hm, merkwürdiges Phänomen. So eine Hübsche Seite, so akkurat gemacht, und dennoch mit so einer "platten" Themenauswahl, schon seltsam, aber nett :)
 
B

blörk

Gast
Code:
     while ( aktuell <= obergrenze)
         {
            if (isPrime(aktuell))
            {
               System.out.print(" " + aktuell);
            }
            aktuell++;
         }


      }


      public static boolean isPrime(int value){
         // hier deine analyse
      }


Der obere Teil is klar soweit.
Nur was macht die Bedingung isPrime(aktuell) ?
Und welche Analyse meinst du?
Bzw was genau macht public static boolean isPrime(int value){?

Sry^^ aber ich versteh halt einfach nichts^^
Ihr müsst das alles für Dumme erklären^^
 

ARadauer

Top Contributor
soll true zurück geben fals die zahl eine primzahl ist, fals wenn sie keine ist...
deine anylse ... der code der ermittelt ob die zahl eine primzahl ist ;-)
verschiedene möglichkeiten! müsst ihr wirklich den fermat test machen? da gibts einfachere arten...
 
G

Guest

Gast
Nein einfach nur irgend eine art... hauptsache das Programm funktioniert und ich verstehe den Code und kann ihn erklären.
Da liegt das Problem^^
Viel mehr als Schleifen und If-Formeln haben wir noch nicht durchgenommen...
Und ich komm einfach nicht drauf wie ich dieses Programm nur mit Schleifen und If-Formeln ohne
isPrime und public static boolean isPrime(int value) programmieren soll, da wir diese Befehle noch nie durchgenommen haben und ich nicht 500 Ausdrücke und ihre funktionen im Vortrag erläutern kann.

Wäre sehr dankbar fürn paar Anregungen... Das muss dieses WE fertig werden... und ich weiß immer noch nicht wie alles funktioniert... und solange kann ich auch keine Präsentation vorbereiten...
Also helft mir bitte schnell^^
 

AmunRa

Gesperrter Benutzer
hab nun eine ganz blöde art die würde aber ganz einfach zu programmieren sein

Du nimmst ein Array mit der Länge deiner Obergrenze.

Das füllst du dann mit boolschen werten die alle true sind.
Jeder dieser Boolschen-Werte steht für eine Zahl

d.h index 0 steht für zahl 1 index 1 ->2, index 2->3 und so weiter index (obergrenze-1) ->obergrenze

danach nimmst eine Forschleife

for (i=2; i<obergränze/2; i++){}

setzt so zuerst jeden zweiten boolschen Wert auf false und dann jeden dritten, und dann jeden 4 , 5, 6 ...... und .. am schluss gibst du jede zahl aus die noch den Wert true hat.



Nja weis nicht ob das geholfen hat

würde aber funktionieren




(is das Sieb des Eratosthenes)
 

Tobias

Top Contributor
Nun ja, weil ich heute nacht nichts anderes zutun hatte ... Verstehen solltest du das natürlich schon irgendwie selbst, ist das Sieb des Erastosthenes, implementiert ohne besondere Optimierungen in etwa so, wie AmunRa es vorgeschlagen hat (auch wenn ich der Zugänglichkeit wegen eine dreiwertige Logik benutzt hab).

Code:
public class Erastosthenes {

	private static final int PRIME = 0;

	private static final int NOT_PRIME = 1;

	private static final int DONT_KNOW = -1;

	private int[] numbers;

	private int current;

	public Erastosthenes(int upper) {
		assert (upper > 2);
		numbers = new int[upper + 1];
		current = 2;

		numbers[0] = NOT_PRIME;
		numbers[1] = NOT_PRIME;
		for (int i = 2; i < numbers.length; i++) {
			numbers[i] = DONT_KNOW;
		}
	}

	public boolean allFound() {
		for (int i = current; i < numbers.length; i++) {
			if (numbers[i] == DONT_KNOW) {
				return false;
			}
		}
		return true;
	}

	public void markNext() {
		while (!(numbers[current] == DONT_KNOW)) {
			current++;
			assert current < numbers.length;
		}

		numbers[current] = PRIME;

		int i = 2;
		while ((current * i) < numbers.length) {
			numbers[current * i] = NOT_PRIME;
			i++;
		}
	}

	public void print() {
		int printedPrimes = 0;
		for (int i = 0; i < numbers.length; i++) {
			if (numbers[i] == PRIME) {
				if (printedPrimes != 0) {
					System.out.print(", ");
				}

				printedPrimes++;
				System.out.print(i);
			}
		}
		System.out.println();
	}

	public static void main(String[] args) throws Exception {
		if (args.length < 1) {
			System.out.println("Aufruf: java Erastosthenes <upperBound>");
			System.out.println("UpperBound must be greater 2.");

			System.exit(1);
		}

		Erastosthenes e = new Erastosthenes(Integer.parseInt(args[0]));
		int i = 1;
		while (!e.allFound()) {
			e.markNext();
			System.out.print(i + ". Iteration:");
			e.print();
			i++;
		}
	}

}
 

0x7F800000

Top Contributor
@ARadauer und sonstige fans des Fermat-tests:
Damit kann man keine Primzahlen finden, damit kann man nur finden, dass etwas nicht prim ist, das ist freilich was anderes. Spätestens bei der 561 geht's eh schief.

@Tobias: na gott sei dank, zumindest mal einer implementiert hier den Sieb! :toll: aber besonders kurz ist die variante auch nicht geworden, >80 zeilen, eine eigene separate klasse mit 3 hilfsmethoden omg^^:?:

kriegst du doch auch wesentlich billiger:
Code:
	public static java.util.List<Integer> sieve(int upperBound){
		
		boolean[] a=new boolean[upperBound];	// markierungs-array
		a[0]=a[1]=true;							// 0 und 1 markieren
		int sqrt=(int)Math.sqrt(upperBound)+1;	// nur bis sqrt(n) gehen
		java.util.List<Integer> result=new java.util.LinkedList<Integer>();
		//alle zusammengesetzte zahlen markieren und unterwegs primzahlen einsammeln
		for(int i=0; i<=sqrt; i++){
			if(!a[i]){
				//primzahl in der ergebnissliste speichern
				result.add(Integer.valueOf(i));
				//alle vielfachen von i als nicht prim markieren
				for(int k=i*i; k<a.length; k+=i) a[k]=true;
			}
		}
		//restlichen primzahlen einsammeln
		for(int i=sqrt+1; i<a.length; i++){
			if(!a[i]){
				//primzahl in der ergebnissliste speichern
				result.add(Integer.valueOf(i));
			}
		}
		return result;
	}
außerdem sollte man alle vielfachen durch summation, nicht multiplikation rausfinden, das ist einen tick schneller und anschaulich klarer. Und zu suchen braucht man auch nur bis zur quadratwurzel (wobei man normalerweise natürlich keine echte quadratwurzel nehmen würde (die methode gibts für big integer eh nich, weil man die nicht braucht), man müsste eigentlich den log_2(n) finden und die zahl um log_2(n)/2-1 nach rechts bitschiften, das wäre auch eine ganz gute grenze.

[wobei man "normalerweise" wohl eh nicht den Sieb des eratosthenes nehmen würde] :)
 
B

blörk

Gast
Genau das meinte ich -.-
Solche Codes verstehe ich nicht...
Kinder , ich bin im Java Grundkurs im Gymnasium^^
Das muss doch gehn mit ein paar einfachen Schleifen und If-Formeln...
 

mahe

Aktives Mitglied
Selbstverständlich geht das auch:
Code:
	public static void main(String argv[]) throws IOException {
		int obergrenze;

		String str;

		BufferedReader eingabe = new BufferedReader(new InputStreamReader(System.in));
		System.out.print("Bitte obergrenze eingeben : ");
		str = eingabe.readLine();
		obergrenze = Integer.parseInt(str);

		for (int aktuell = 1; aktuell <= obergrenze; ++aktuell) {
			boolean prime = true;
			for (int i = 2; i + i <= aktuell; ++i) {
				if (aktuell % i == 0) {
					prime = false;
					break;
				}
			}
			if (prime) {
				System.out.println(aktuell);
			}
		}
	}

Hier wird einfach (gänzlich unoptimiert) durchdividiert (Modulo-Operator: %).
 

Landei

Top Contributor
Es muss
Code:
for (int i = 2; i * i <= aktuell; ++i) {
heißen.
 

0x7F800000

Top Contributor
blörk hat gesagt.:
Das muss doch gehn mit ein paar einfachen Schleifen und If-Formeln...
nunja, da sind ja auch nur zwei schleifen und zwei if-abfragen und nix weiter. Und die schleifen sehen auch noch fast gleich aus, die eine läuft halt bis zur wurzel, die zweite läuft nach der wurzel. Wenn dich das stört, dann kannst du die liste wegschmeißen und alles in einem array einsammeln, aber dafür bräuchtest du nochmal ne schleife, das sieht dann irgendwann dämlich aus...
 
B

blörk

Gast
Ok super^^
das hat mir schonmal sehr weiter geholfen.. funktionieren tuts bei mir, nun hab ich allerdings nur noch ein paar Fragen zum Verständniss damit ichs auch der Klasse oder dem Lehrer alles erklären kann falls nötig.

Ich hab den Code nun etwas vereinfacht damits beim Vortrag auch jeder Depp versteht.
Inklusive natürlich mir xD


/*
GFS : Primzahlen
Ziel : Eingabe von Obergrenze => Ausgabe von allen Primzahlen zwischen 1 und Obergrenze
*/

import java.io.*;
public class Primzahlen
{



public static void main (String argv [])throws IOException
{
//Deklaration der Variablen
int obergrenze;
int aktuell;
int i;


//Deklaration der Hilfvariablen
String str;

//Eingabeobjekt anlegen
BufferedReader eingabe = new BufferedReader (new InputStreamReader ( System.in));



//Eingabe von Wert obergrenze
System.out.print("Bitte obergrenze eingeben : ");

//Auslesen der Eingabe und Übergabe in "str"
str= eingabe.readLine();

//Zuweisung des Wertes von "str" in Variable " obergrenze"
obergrenze = Integer.parseInt(str);

//Warnung falls obergrenze <= 1 ist
if (obergrenze <=1)
{
System.out.println("Obergrenze muss > als 1 sein");
}



// For Schleife => Startwert = 2 ; Bedingung aktuell <= obergrenze ; Zählschritt aktuell ++
for (aktuell= 2; aktuell <= obergrenze; aktuell++)
{

// Boolesche Zahlen -> True setzen
boolean prime = true; //Was genau macht diese Zeile?



// For Schleife => Startwert = 2 , Bedingung i * i <= aktuell ; Zählerschritt i++
for (i = 2; i * i <= aktuell; i++) // Warum i*i? und nicht nur i <= aktuell??
{

/* If-Formel => Wenn aktueller Wert % i = 0 ergibt,keine Primzahl
( wenn bei "%"(Restfunktion) 0 raus kommt=> ist die Zahl restlos teilbar => keine Primzahl)
*/

if (aktuell % i == 0)

{
prime = false;
}

}

// If-Formel => Falls prime durch keine Zahl restlos teilbar ist 0 => Primzahl , Zahl Ausgeben

if(prime) // Warum ist die Bedingung hier nur Prime? Und nicht prime = true? oder sowas...
{
System.out.print( " "+ aktuell + " ");

}

}



}

}
 

mahe

Aktives Mitglied
Die Variable prime (Boolean) zeigt an ob die aktuelle Zahl eine Primzahl ist. Dazu wird prime zuerst auf true gesetzt.
Wird in der inneren Schleife festgestellt, dass die Zahl keine Primzahl ist, wird prime auf false gesetzt.
Dies wird auch später abgefragt.

Bei boolschen Variablen ist
if (prime) {}
und
if (prime == true) {}
dasselbe.

Die If-Anweisung braucht nur einen boolschen Wert und prime ist bereits einer.

Code:
for (i = 2; i * i <= aktuell; i++)
Das ist nun schon eine Optimierung.
Es würde auch so funktionieren:
Code:
for (i = 2; i < aktuell; i++)
Aber dann würden viele Divisionen umsonst gemacht.


(übrigens: Die Code-Tags nicht vergessen sonst sieht das so unansehnlich aus!)
 

Tobias

Top Contributor
@Ebenius: Üblicherweise mache ich solche Tests natürlich nicht mit assert, aber für diese Klasse war's einfach schön bequem.

@Andrey: Mir ging es weder um Kürze noch um Geschwindigkeit, sondern ausschließlich um Verständlichkeit. Und die fordert halt ihren Platz ...
 
Status
Nicht offen für weitere Antworten.

Ähnliche Java Themen

Neue Themen


Oben