Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Primzahlen Problem

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 < [ 2 ] [ 3 ]
000
28.09.2003, 09:16 Uhr
~Mathias
Gast


Gesucht ist ein c (nicht c++) Programm was Primzahlen sucht (abgefragter Bereich von-bis) und gefundene Primzahlen überprüft ob die gefundene Primzahl durch maximal 2 (kleinere) Primzahlen teilbar ist, wenn ja Ausgabe der gefundenen Primzahl mit den beiden Teilern.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
28.09.2003, 09:32 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


Eine Primzahl ist nur durch sich selbst oder 1 teilbar, also wird dir

"überprüft ob die gefundene Primzahl durch maximal 2 (kleinere) Primzahlen teilbar ist"

nie etwas liefern
--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
28.09.2003, 11:01 Uhr
~Mathias
Gast


Da ist mir wohl ein kleiner Fehler unterlaufen.
Also nochmal:
1.) Primzahlen berechnen, nach Eingabe des Anfangs- und Endwertes
2.) gefundene Primzahl^2-1
3.) Nun überprüfen ob der errechnete Wert das Produkt von maximal 2 kleineren Primzahlen ergibt.
4.) Falls ja, Ausgabe der gefundenen Primzahl und der beiden kleineren Primzahlen

Beispiel:
gefundene Primzahl 7
7^2-1=48
kleinere Primzahl von 7: 5,3,2
48:5=ungleich
48:3=16; geht also
48:2=24; geht also
Ergebnis: 48 hat genau 2 Primzahlenteiler, also Ausgabe der gefundenen Primzahl (7) mit den beiden Teilern 3 und 2.

gefundene Primzahl 11
11^2-1=120
kleinere Primzahlen von 11: 7,5,3,2
120:7=ungleich
120:5=24; geht also
120:3=40; geht also
120:2=60; geht also
Ergebnis: 120 hat mehr als 2 Primzahlteiler, also ist Primzahl 11 nicht möglich

Und das ganze auch noch in c
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
28.09.2003, 11:46 Uhr
Pablo
Supertux
(Operator)



Zitat:
~Mathias postete
Und das ganze auch noch in c

Keine Sorge, C beißt nicht

Also, zuerst muss du eine Funktion einbauen, die dir sagt, ob eine Zahl Prim ist oder nicht. Das geht so:


C++:
int istprim(unsigned int); // nur Protyp
// return 1, wenn Zahl prim ist, return 0 sonst.
// return -1, wenn zahl ==0

// Imlementierung
int istprim(unsigned int zahl)
{
    int i=1, j; // angegeben, die Zahl ist prim.
    if(zahl==0) return -1;
    if(zahl==1) return 0; // 1 ist keine primzahl
    if(zahl==2 || zahl==3 || zahl==5) return 1; //damit for schleife keine Probleme kriegt
    if(!(zahl%2)) return 0; // wenn positiv außer 2, dann ist nicht prim
    for (j=3; j<zahl/2; ++j) // wir brauchen nur bis zur Hälfte gehen; läuft in O(n)
        i *= (zahl % j > 0);
    return i;
}



Um eine Zahl zu exponentieren, muss man die Funktion von math.h

C++:
double pow(double basis, double exponent);


benutzen. Den Rest muss du dir (meiner Meinung nach) selber überlegen. Denn ich verstehe "48:5 = ungleich" und "48:3=16; geht also" nicht.
--
A! Elbereth Gilthoniel!
silivren penna míriel
o menel aglar elenath,
Gilthoniel, A! Elbereth!

Dieser Post wurde am 28.09.2003 um 12:30 Uhr von Pablo Yanez Trujillo editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
28.09.2003, 12:06 Uhr
~Mathias
Gast


gefundene Primzahl 11
11^2-1=120
kleinere Primzahlen von 11: 7,5,3,2
120:7=ungleich
120:5=24; geht also
120:3=40; geht also
120:2=60; geht also
Ergebnis: 120 hat mehr als 2 Primzahlteiler, also ist Primzahl 11 nicht möglich

Mit "ungleich" bzw "geht also" meinte ich ob es (gerade)teilbar ist, also das keine Nachkommastellen rauskommen.
Wenn man 120 durch 7 teilt kommt etwa 17,1428 raus, also ein "krummer Wert".
120 teilt sich durch 3 Primzahlen die kleiner als 7 (Ausgangsbasis) sind und 3 sind einer zuviel, da nur max 2 Zulässig sein dürfen, wie bei dem Beispiel mit der gefundenen Primzahl 7 (siehe oben).

Das Problem (was ich vermute) liegt dadrin das man sich alle gefundenen Primzahlen irgentwie "merken" muß.
Also zb. User sagt Zahlenbereich von 0-100 durchsuchen, also nun erstmal anfangen Primzahlen zu suchen, dann überprüfen ob kleinere Primzahlen schon gefunden wurden und diese nach prim^2-1 überprüfen (siehe oben). Danach aber muß die gefundene Prim gemerkt werden, so das größere gefundene Primzahlen mit dieser überprüft werden können.
Also:
Prim 2 gefunden, überprüfen der Prim im Merker nach prim^2-1, geht nicht(da Merker noch leer),Prim in den Merker
prim 3 gefunden, überprüfen der Prim im Merker nach prim^2-1, geht nicht(da nur 2 drin steht),Prim in den Merker
Prim 5 gefunden, überprüfen der Prim im Merker nach prim^2-1(ergebnis hier 24), geht (da 24 durch 3 teilbar ist und 24 durch 2;Ausgabe von Prim5),Prim in den Merker
Prim 7 gefunden, überprüfen der Prim im Merker nach prim^2-1(ergebnis hier 48),geht (da 48 durch 2 teilbar ist und 48 durch 3;Ausgabe von Prim7),Prim in den Merker
Prim 11 gefunden, überprüfen der Prim im Merker nach prim^2-1(ergebnis hier 120), geht nicht(da 120 zwar durch 5 teilbar ist, aber auch durch 3 und auch durch 2; Beding war ja max durch 2 kleinere Primzahlen teilbar),Prim in den Merker
usw.usw.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
28.09.2003, 12:09 Uhr
Pablo
Supertux
(Operator)


Ach so, das mit dem ungleich hat mich verwirrt, weil das erste was in meinem Kopf kam war: ungleich was????

Also, in deinem Beispiel
120:7 \not \in \mathbb{N} (nicht in der Menge der Natürlichen Zahlen, so kann ich es besser verstehen)

also, ich hab jetzt nix zu tun, ich werde das versuchen.


Bearbeitung:


Zitat:

Das Problem (was ich vermute) liegt dadrin das man sich alle gefundenen Primzahlen irgentwie "merken" muß.


Nicht unbedingt. Das hängt nur davon aus, was man damit machen will. Und mit gefundenen Primzahlen meinst du einfache Primzahlen im Interval [x;y] oder nur die Primzahlen, die die Bedingung erfüllen.

Man kann das direkt mit printf ausgeben, oder wenn du (sagen wir mal) diese Primzahlen naher miteinander multiplizieren, odr addieren (oder was weiß ich) willst, dann lohnt es sich sie zu speichern.

Du kannst ein Array nehmen. Das blöde daran ist, dass man die Länge ständig verändern muss. Man kann auch das Array mit anderen Strategien verwalten, so dass das Array verlängert wird, nur dann wenn alpha(array) := anzahl der gespeicherte Primzahlen / Anzahl der Felder > 1/2 ist. Aber das kann man eben später machen.

Du kannst auch ein Liste erstellen (Single Linked List). Das gute ist, dass man nicht (wie im Fall des Arrays) die Länge ändern soll.

Ich werde versuchen ein Beispielprogramm zu basteln, welches die Primzahlen im Intervall [x;y] (per printf) ausgibt, die diese Eigenschaft erfüllen.


--
A! Elbereth Gilthoniel!
silivren penna míriel
o menel aglar elenath,
Gilthoniel, A! Elbereth!

Dieser Post wurde am 28.09.2003 um 12:21 Uhr von Pablo Yanez Trujillo editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
28.09.2003, 13:01 Uhr
Pablo
Supertux
(Operator)


Wie wäre es damit?

C++:
#include <stdio.h>
#include <math.h>
#include <stdlib.h>

int istprim(unsigned int zahl)
{
    int i=1, j; // angegeben, die Zahl ist prim.
    if(zahl==0) return -1;
    if(zahl==1) return 0; // 1 ist keine primzahl
    if(zahl==2 || zahl==3 || zahl==5) return 1; //damit for schleife keine Probleme kriegt
    if(!(zahl%2)) return 0; // wenn positiv außer 2, dann ist nicht prim
    for (j=3; j<zahl/2; ++j) // wir brauchen nur bis zur Hälfte gehen
        i *= (zahl % j > 0);
    return i;
}

int erfuellt_eigenschaft(unsigned int zahl)
{
  int i, counter=0, z=pow(zahl,2)-1;

  // ich gehe davon aus, dass 0 nicht übergeben wird, sonst kann das eklig werden

  // für die Primzahlen 2, 3 wissen wir, dass sie die Eigenschaft nicht erfüllen (1)
  // für die Primzah und 5 folgt aus (1) dass sie die Eigenschaft nicht erfüllen, weil
  // 5^2=25 ist weder von 2, 3 teilbar ist, also können wir diese sofort ausgeben
  if(zahl == 2 || zahl == 3 || zahl == 5) return 0;
  // wenn wir hier ankommen, ist weil die Primzahl >= 7 ist, also mindestens 3 Primzahlen
  for(i=2; i<zahl; ++i) {
    if (istprim(i)) {
      if(!(z % i)) counter++; // zahl^2-1 ist diese Primzahl teilbar
    }
    if (counter>2) return 0; //wenn es mehr als 2 sind, brauche wir nicht mehr alle andere Primzahlen
  }
  return 1;
}

int main(int args, char** argv)
{
    int i, j=0,x,y;
          
    if (args != 3) {
        printf("usage: %s x y\nx und y sind die Grenzen des Intervalls. Das Interval soll eine Teilmenge der Natürlichen Zahlen sein\n");
        return 0;
    }

    x=atoi(argv[1]);
    y=atoi(argv[2]);
    if(y<x) {
        printf("Das eingebene Interval [%d,%d] ist mathematisch nicht korrekt.\n", x,y);
        return 0;
    }

    // das Programm wird nicht untersuchen, ob die Parameter zahlen sind
        // ich geh davon aus, dass sie Zahlen sind, hoffe ich :)


    // Hier fängt alles an
    for(i=x; i<=y; ++i) {  
      // ist das prim ?
      if (istprim(i)==1)
         j = erfuellt_eigenschaft(i);
      if(j)
        printf("Die Primzahl %d erfüllt die Eigenschaft\n",i);
      j=0;
    }
        
    return 0;
}

}





Man muss das Interval beim Ausführen übergeben
programprimzahl 0 100

Läuft alles in O(n^2), ungefähr, das kann ich natürlich verbessern, gibt mir nur Zeit.

Code:
.
/prim 0 10000
Die Primzahl 7 erfüllt die Eigenschaft
Die Primzahl 17 erfüllt die Eigenschaft



Im Interval [0, 10000] gab es nur die 7 und die 17, die das erfüllt haben, umd Interval [0, 100000] gibt es noch mehrere, aber das Programm rechnet ja immer noch.
--
A! Elbereth Gilthoniel!
silivren penna míriel
o menel aglar elenath,
Gilthoniel, A! Elbereth!

Dieser Post wurde am 28.09.2003 um 13:08 Uhr von Pablo Yanez Trujillo editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
28.09.2003, 13:13 Uhr
Pablo
Supertux
(Operator)



C++:
#include <stdio.h>
#include <math.h>
#include <stdlib.h>

int istprim(unsigned int zahl)
{
    int i=1, j; // angegeben, die Zahl ist prim.
    if(zahl==0) return -1;
    if(zahl==1) return 0; // 1 ist keine primzahl
    if(zahl==2 || zahl==3 || zahl==5) return 1; //damit for schleife keine Probleme kriegt
    if(!(zahl%2)) return 0; // wenn positiv außer 2, dann ist nicht prim
    for (j=3; j<zahl/2; ++j) // wir brauchen nur bis zur Hälfte gehen
        i *= (zahl % j > 0);
    return i;
}

int erfuellt_eigenschaft(unsigned int zahl, int*a, int *b)
{
  int i, counter=0, z=pow(zahl,2)-1;

  // ich gehe davon aus, dass 0 nicht übergeben wird, sonst kann das eklig werden

  // für die Primzahlen 2, 3 wissen wir, dass sie die Eigenschaft nicht erfüllen (1)
  // für die Primzah und 5 folgt aus (1) dass sie die Eigenschaft nicht erfüllen, weil
  // 5^2=25 ist weder von 2, 3 teilbar ist, also können wir diese sofort ausgeben
  if(zahl == 2 || zahl == 3 || zahl == 5) return 0;
  // wenn wir hier ankommen, ist weil die Primzahl >= 7 ist, also mindestens 3 Primzahlen
  for(i=2; i<zahl; ++i) {
    if (istprim(i)) {
      if(!(z % i)) {
         if(counter==0) *a = i;
         if(counter==1) *b = i;
         counter++; // zahl^2-1 ist diese Primzahl teilbar
      }
    }
    if (counter>2) return 0; //wenn es mehr als 2 sind, brauche wir nicht mehr alle andere Primzahlen
  }
  return 1;
}

int main(int args, char** argv)
{
    int i, j=0,x,y,a,b;
          
    if (args != 3) {
        printf("usage: %s x y\nx und y sind die Grenzen des Intervalls. Das Interval soll eine Teilmenge der Natürlichen Zahlen sein\n");
        return 0;
    }

    x=atoi(argv[1]);
    y=atoi(argv[2]);
    if(y<x) {
        printf("Das eingebene Interval [%d,%d] ist mathematisch nicht korrekt.\n", x,y);
        return 0;
    }

    // das Programm wird nicht untersuchen, ob die Parameter zahlen sind
        // ich geh davon aus, dass sie Zahlen sind, hoffe ich


    // Hier fängt alles an
    for(i=x; i<=y; ++i) {  
      // ist das prim ?
      if (istprim(i)==1)
         j = erfuellt_eigenschaft(i,&a,&b);
      if(j)
        printf("Die Primzahl %d erfüllt die Eigenschaft. Die anderen Primzaheln sind %d und %d\n",i,a,b);
      j=0;
    }
        
    return 0;
}

}


--
A! Elbereth Gilthoniel!
silivren penna míriel
o menel aglar elenath,
Gilthoniel, A! Elbereth!
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
28.09.2003, 13:47 Uhr
~(un)wissender
Gast


@Pablo
Die Performance von istprim() ist mies, da sollte man für größere Zahlen schon Heuristiken verwenden.
Außerdem kann du in dieser Schleife:

C++:
for (j=3; j<zahl/2; ++j) // wir brauchen nur bis zur Hälfte gehen
        i *= (zahl % j > 0);


j immer um zwei erhöhen, weil (ungerade Zahl + 1 = gerade Zahl) != Primzahl

Gruß
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
28.09.2003, 13:55 Uhr
Pablo
Supertux
(Operator)


Stimmt, man kann statt ++j
j = j+2; nehmen.
--
A! Elbereth Gilthoniel!
silivren penna míriel
o menel aglar elenath,
Gilthoniel, A! Elbereth!
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 < [ 2 ] [ 3 ]     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: