Perfekte Zahlen ausgeben

Tiny9014

Mitglied
Hallo, bin absoluter Anfänger und suche jemanden, der mir diesen Code erklärt. Also wie genau ein Ablauf aussieht. Leider konnte ich nichts passendes hier im Forum finden.

Code:
public class PerfekteZahl {

    public static void main(String[]args) {
       
        int teilersumme = 0;           
        int j = 1;
       
        while(j != teilersumme) {
           
            teilersumme = 0;
           
            for(int i = j / 2; i > 0; i-- ) {
                if(j % i == 0) {
                    teilersumme = teilersumme + i;
                }
            }
            if(teilersumme == j) {
                System.out.print(j + " = ");
               
                for(int i = j / 2; i > 0; i-- ) {
                    if(j % i == 0) {
                        teilersumme = teilersumme + i;
                        System.out.print(i);
                       
                        if(i != 1){
                            System.out.print(" + ");
                        }
                    }
                }
                System.out.println("");
            }
            j++;
        }
    }
}
 
Ja genau... jetzt setzt sich hier gaaanz bestimmt jemand hin, und erklärt für dich Zeile für Zeile den Code, und warum er an jeder Stelle so funktioniert, wie er funktioniert.
Hast du mal daran gedacht, das selber zu versuchen? Bzw., woran scheitert es denn genau?
Ganz nebenbei: Die Aussage "Ich bin absoluter Anfänger, also kann ich das nicht" zählt hierbei nicht.
 
Meine 1.Frage wäre schonmal, warum i=j/2 ist und nicht i=j und warum es i-- und nicht i++?
Danke für deine freundliche Art 😉. Du wirst hier nicht gezwungen, zu antworten.
 
@Tiny9014
Operators
Java:
public class OperatorExample {

    public static void main(String[]args) {
       
        int key = 10;
        int lock = 10;
        System.out.println(key == lock ? Boolean.TRUE : Boolean.FALSE);
        int anotherLock = 11;
        System.out.println(key == anotherLock ? Boolean.TRUE : Boolean.FALSE);
    }
}
/** Output */
true
false
 
Meine 1.Frage wäre schonmal, warum i=j/2 ist und nicht i=j
j kann ja keinen Teiler haben, der größer als j/2 ist (außer sich selbst, was hier aber nicht erwünscht wäre).
und warum es i-- und nicht i++
Weil hier von j/2 bis 1 herunter gezählt wird, um alle Teiler-Kandidaten zu durchlaufen. Man hätte stattdessen auch von 1 bis j/2 herauf zählen können. Dann wäre i++ richtig gewesen.
 
Java:
while(j != teilersumme) {

teilersumme = 0;
Ebenfalls frage ich mich, was dies bezweckt.
Mit jeder Iteration der while-Schleife wird ein neues j als Kandidat dafür, eine perfekte Zahl zu sein, untersucht. Dafür muß die Teilersumme von j ermittelt werden, die deshalb zunächst auf 0 gesetzt wird, weil darin ja noch die Teilersumme des vorherigen Kandidaten abgelegt ist.
Die Bedingung der while-Schleife scheint aber noch nicht ganz ausgereift zu sein.
 
j kann ja keinen Teiler haben, der größer als j/2 ist (außer sich selbst, was hier aber nicht erwünscht wäre).

Doch, eigentlich ist es erwünscht, wenn man es genau nehmen würde. Nach Definition gilt für eine eine Perfekte Zahl
3627e031c536dcff0b99eff7778e0ace371361bc
, inklusive der Zahl selbst. Für n=6 wäre die Summe Ihrerer Teiler inkl. sich selbst 1+2+3+6 = 12 = 2 * 6. 6 ist damit eine Perfekte Zahl. Abgeleitet von dieser Definition ist jedoch ist jedoch Die Summe der Teiler von n exklusive n damit n. Daraus kann man ableiten, dass der nächstekleiner Teiler von n nach n nur halb so groß wie n sein kann. Daher beginnt die Schleife bei n/2 - im Code ist n ein wachsendes j.
 
Zuletzt bearbeitet:
Doch, eigentlich ist es erwünscht, wenn man es genau nehmen würde. Nach Definition gilt für eine eine Perfekte Zahl
3627e031c536dcff0b99eff7778e0ace371361bc
, inklusive der Zahl selbst.
Na ja, es entspricht nicht so ganz meinem Verständnis von "eigentlich ist es erwünscht", wenn ich zwar bereits das richtige Ergebnis habe, aber trotzdem noch einmal denselben Aufwand investiere, um es zu verdoppeln, damit ich durch anschließende Division mit zwei doch noch das bereits zuvor bekannte Resultat erreiche.😉
Die Definitionen sigma(n) = 2n und sigma*(n) = n sind äquivalent, von daher würde ich ersteres nicht "die", sondern "eine" Definition nennen und die erste ist auch nicht "genauer" als die zweite.
 
Hi @Tiny9014 😉 Ma bisschen rum probiert:
Java:
public static void main(String[] args) {
    int k = 2;
    while (k < 90) {
        BigInteger l = BigInteger.valueOf(2).pow(k).subtract(BigInteger.ONE);
        if (l.isProbablePrime(1)) {
            System.out.println(k + ", " + BigInteger.valueOf(2).pow(k - 1).multiply(l));
        }
        k++;
    }
}

Die ersten 10 Zahlen:
Code:
2, 6
3, 28
5, 496
7, 8128
13, 33550336
17, 8589869056
19, 137438691328
31, 2305843008139952128
61, 2658455991569831744654692615953842176
89, 191561942608236107294793378084303638130997321548169216

Ich gehe davon aus dass es einfach keine ungeraden Zahlen gibt - und Euklid und Euler.... schon auch iewie schlau waren....

Meine Vermutung iss wenn Du k erhöhst erhöht sich dramatisch die Laufzeit. 😱😱😱

@mihe7 Was wäre Dein Eindruck?😛
 

Zurück
Oben