C#: Problem mit der Schleife in der Primfaktorzerlegung?

2 Antworten

Vom Fragesteller als hilfreich ausgezeichnet

Was soll diese Zeile machen:

while ( (zahl/teiler != 1) && (zahl%teiler != 0));

... die hat keinen Body und macht nichts, d.h. wenn die Bedingung erfüllt ist, bleibt sie auch erfüllt, und du hast eine Endlosschleife.

Woher ich das weiß:Studium / Ausbildung – Studium und Promotion in Angewandter Mathematik
Luca211299 
Fragesteller
 09.06.2021, 21:11

Danke für Deine Antwort.

Ich habe mich da an folgendes Beispiel orientiert:

int n = 0;
do
{
    Console.Write(n);
    n++;
} while (n < 5);
// Output:
// 01234
do    
        {
                teiler++;   
                while (zahl % teiler == 0)  
                {
                    zahl = zahl / teiler;
            <nobr>@teiler * </nobr>
            Console.Write((teiler) + "*");    
        }         
         } while ((zahl/teiler != 1) && (zahl%teiler != 0));

Kann man das so nicht machen?

0
ShimaG  09.06.2021, 21:18
@Luca211299

Ah, sorry, verlesen - do... while. Ja, das kannst du machen.

Aber mal zur Zahl 2...

Du teilst die 2 erst durch teiler (mit dem Wert 2), dann ist zahl danach auf dem Wert 1.

Die innere While-Schleife terminiert dann, weil der Rest von 1 (mod 2) nicht Null ist.

Die äußere do..while-Schleife terminiert nicht, weil zahl/teiler ungleich 1 ist (in Integer-Arithmetik ist 1/2=0), und zahl%teiler is wie oben 1, was nicht Null ist. Damit ist diese Bedingung für teiler=2 erfüllt, und dasselbe gilt auch für alle größeren Werte von teiler.

Wenn du da noch "&& (teiler < zahl)" in die Abbruchbedingung schreibst, sollte das funktionieren. Ist nicht schön und nicht optimal, was die Laufzeit angeht, tut aber.

1
Luca211299 
Fragesteller
 09.06.2021, 21:25
@ShimaG

Hat geklappt, vielen Dank.

Ja, muss mir nochmal die gesamte Schleife anschauen und sie optimieren, so dass die Laufzeit kürzer wird.

Gruß Luca

0
regex9  09.06.2021, 21:38
@Luca211299

Beachte im Übrigen, dass in deinem HTML-Dokument mehrere Fehler enthalten sind.

1) Der Doctype fehlt.

<!doctype html>

2) Das action-Attribut darf keinen leeren Wert haben. Wenn du es nicht brauchst / es auf dieselbe URL verweisen soll, lass es komplett weg.

3) Das div-Element wird nicht geschlossen.

4) Das nobr-Element gehört nicht zum Standard. Verwende CSS stattdessen.

<span style="white-space: nowrap;">Your text ...</span>
2
  do
  {
    teiler++;
    // ...
  }
  while ((zahl/teiler != 1) && (zahl%teiler != 0));

Diese Schleifenbedingung ist hoffnungslos fehlerhaft. Was bei zahl==2 passiert, hat ShimaG ja schon aufgedröselt.

Korrekt wäre:

 while (zahl > 1);

denn dann wurden alle Teiler von zahl in der Schleife gefunden und heraus-dividiert.

Zur Sicherheit würde ich stattdessen sogar

 while (zahl > teiler);

schreiben. Das wird auch dann abbrechen, wenn irgendwas in der Schleife schief lief und ein Teiler vergessen wurde (z.B. weil teiler nicht sauber initialisiert wird).

Und wenn es schneller gehen soll, prüfe nur die echten Primteiler:

 while (zahl > teiler*teiler);

Wenn zahl überhaupt noch einen größeren Teiler hat, dann nur sich selbst. Jetzt kann die Schleife tatsächlich korrekt mit zahl>1 enden, und das ist dann der letzte Faktor.

Im Augenblick gibst Du nach der Schleife sowieso "*zahl" aus, was bei Dir momentan immer "*1" produziert. Mit obiger Abkürzung kann da auch der letzte Primfaktor erscheinen.

Beispiel: zahl = 6126

  • Ohne Optimierung erscheint nach 1020 Durchläufen 6126=2*3*1021*1.
  • Mit Optimierung erscheint schon nach 31 Durchläufen 6126=2*3*1021.
Luca211299 
Fragesteller
 11.06.2021, 09:22

Auch dir Danke, für deine Erklärungen.

0