C++ Alle teiler einer Zahl zu langsam :(

4 Antworten

Vom Fragesteller als hilfreich ausgezeichnet

Das hat weniger mit C++ zu tun, vielmehr solltest du dir Gedanken über einen anderen Algorithmus machen. Eine Idee wäre:

  • gib eine Zahl x ein
  • finde alle Primzahlen <= x (Sieb von Eratosthenes / Sieb von Atkin)
  • wenn x selbst eine Primzahl ist, breche ab (dann gibt es nur 2 Faktoren - 1 und x)
  • führe eine Primfaktorzerlegung auf x durch
  • ermittle alle Kombinationen dieser Primfaktoren
  • sortiere die Liste der Kombinationen und gib sie aus - bei großen Zahlen kann das aber durchaus eine lange Liste werden.
ceevee  07.12.2012, 16:31

Das, was du PerfectMuffin geantwortet hast, ist aber was anderes als das, was du in der Aufgabenstellung beschrieben hast. Das Problem lässt sich auch eleganter lösen, wenn man Mathe kann. ;) Hier mal eine Lösung in richtigem C++

#include <iostream>

using namespace std;

int main()
{
  unsigned long zahl = 999999999;
  unsigned int teiler = 7;

  unsigned long anzahl = zahl/teiler;

  for(unsigned long i=1;i<=anzahl;i++)
  {
    cout<<i*teiler<<endl;
  }
  return 0;
}

Das Programm braucht zwar auch eine ganze Weile, bis es fertig ist, der Flaschenhals hierbei ist aber die Ausgabe der vielen Zahlen (insgesamt 142857142), und das kannst du bei deiner Aufgabenstellung nicht umgehen. Die große Eingangszahl würde übrigens in einer int-Variablen überlaufen (d.h. dein Ergebnis wäre dementsprechend auch falsch), da musst du einen anderen Datentyp wählen. Setz erstmal die Grundlagen, bevor du überlegst, wie du die CPU-Auslastung steigerst.

0
20: 7,14    
30: 7,14,21,28

Das sind noch nichts anderes als alle Vielfachen von 7. Also kannst du in der Schleife einfach immer um die Zahl 7 einen Schritt weitergehen (anstatt 7 einzelne Schritte und jedes mal zu überprüfen ob es schon durch 7 teilbar ist)

int schrittweite = 7;

// teiler += x ist dasselbe wie teiler = teiler + x
for(int teiler = schrittweite; teiler <= maximum; teiler  += schrittweite) 
{
     printf("%i\n", Teiler);
}

Wier lange braucht er den? Bei Deiner Eingabe sind immerhin 999 Milliionen 999 Tausend 999 Operationen nötig, um alle Zahlen auszurechnen und anzuzeigen.

Dann ist da noch ein Problem mit dem Begriff Teiler!

7 ist kein Teiler von 10. 10 ist nur durch 1, 2 und 5 ohne Rest teilbar. So die offizielle Definition in der Mathematik für den Begriff Teiler.

Wenn Du aber alle durch 7 teilbare Zahlen kleiner als Dein Eingabewert suchst, ist Dein Ansatz wieder richtig, Du hast es dann nur falsch erklärt. Und dann würde ich es auch etwas anders Programmieren.

KilerAffe 
Fragesteller
 07.12.2012, 09:07

Jetzt stimmts :)

int main() { int Zahl; int Teiler

printf("Bitte gib eine Zahl ein >");
scanf("%i", &Zahl);
fflush(stdin);

for(Teiler = 1; Teiler <= Zahl; Teiler = Teiler + 1)
{
    if(Zahl%Teiler==0)
    {
        printf("%i\n", Teiler);
        Teiler = Teiler + 1;
    }
}
system("Pause");
return 0;

}

0
WhiteGandalf  07.12.2012, 13:29
@KilerAffe
  • Guck genau hin!
  • Mache einen Testlauf!
  • Überlege, warum die Ausgabe nicht stimmt!
0

Mit Teilern hat das eigentlich gar nix zu tun, ein Teiler wäre ein Zahl, die "Zahl" ohne Rest teilt.

Was du willst, kannst du viel schneller erreichen:

for(Siebener = 7; Siebener <= Zahl; Siebener = Siebener + 7)

{

   printf("%i\n", Siebener);

}

KilerAffe 
Fragesteller
 07.12.2012, 08:46

Also muss ich zuerst int siebener machen? Dann siebener einlesen mit scanf?

Oder wie muss ich das genau machen?

0
FataMorgana2010  07.12.2012, 08:55
@KilerAffe

Das solltest du wirklich selber machen können.... Ich habe doch nur den irreführenden Variablennamen "Teiler" durch "Siebener" ersetzt... Natürlich musst du weiterhin Zahl scannen:

int main()

{ int Zahl; int Siebener;

printf("Bitte gib eine Zahl ein >");

scanf("%i", &Zahl);

fflush(stdin);

for(Siebener = 7; Siebener <= Zahl; Siebener = Siebener + 7)

{

printf("%i\n", Siebener);

}

system("Pause");

return 0;

}

0
KilerAffe 
Fragesteller
 07.12.2012, 09:12
@bmke2012

hahah habs jetzt doch selber geschafft :)

0