Collatz-Problem in C Lösung



  • Hallo liebe C-Spezialisten.

    Ich habe folgende Aufgabenstellung zum Collatz-Problem (3n+1):

    1. Schreiben Sie ein Programm das zwei zahlen m und p einließt und daraus eine Collatz Zahlenfolge bildet.
    2. Es muss auch ausgeben welches die größte Zahl ist, die in ihren Schritten enthalten ist. Parameter max
    3. Das Programm muss folgende Prozedur implementieren und verwenden: void converge (int n, in *steps, int *max);
    4. Es sollen die Anzahl der Schritte im Parameter steps gespeichert werden, welche benötigt werden um das Problem zu lösen.

    Mein Code bisher:
    #include <stdio.h>

    int main(void) {
    int m;
    int p;

    printf("Erste Zahl eingeben: ");
    scanf("%d", &m);
    printf("Zweite Zahl eingeben: ");
    scanf("%d", &p);

    printf("Collatz-Reihe von %d: \n", m);
    while(m != 1) {
    if(m%2 == 0) {
    m = m / 2.0;
    printf("%d\n", m);
    }
    else {
    m = 3 * m + 1;
    printf("%d\n", m);
    }
    }
    printf("Collatz-Reihe von %d: \n", p);
    while(p != 1) {
    if(p%2 == 0) {
    p = p / 2.0;
    printf("%d\n", p);
    }
    else {
    p = 3 * p + 1;
    printf("%d\n", p);
    }
    }
    return 0;
    }

    Punkt 1 funktioniert. Doch wie bekomme ich den Rest mit Maximalwert und Anzahl der Schritte hin?



  • Ich bin mal so frei: (zu formatieren)

    #include <stdio.h>
    
    int main(void) {
    	int m;
    	int p;
    
    	printf("Erste Zahl eingeben: ");
    	scanf("%d", &m);
    	printf("Zweite Zahl eingeben: ");
    	scanf("%d", &p);
    
    	printf("Collatz-Reihe von %d: \n", m);
    	while (m != 1) {
    		if (m % 2 == 0) {
    			m = m / 2.0;
    			printf("%d\n", m);
    		}
    		else {
    			m = 3 * m + 1;
    			printf("%d\n", m);
    		}
    	}
    	printf("Collatz-Reihe von %d: \n", p);
    	while (p != 1) {
    		if (p % 2 == 0) {
    			p = p / 2.0;
    			printf("%d\n", p);
    		}
    		else {
    			p = 3 * p + 1;
    			printf("%d\n", p);
    		}
    	}
    	return 0;
    }
    


  • Ich hoffe es wirkt nicht thread-räuberisch, aber ich hab mal versucht, den Code bei mir zu übersetzen. Ich musste um ihn kompiliert zu bekommen, drei Änderungen vornehmen (mit den Fehler-Codes von Visual Studio gekennzeichnet)

    Ob die Ausgabe so stimmt, habe ich nicht überprüft. Da habe ich Dein Ding versucht zu übernehmen.

    Punkt 2 wäre, den max-Wert einer Reihe auszugeben?
    Punkt 3 und 4 habe ich noch nicht richtig verstanden.

    #define _CRT_SECURE_NO_WARNINGS // wg error C4996 // irgendwas im Code ist veraltet
    #include <stdio.h>
    
    void printCollatzReihe(int v)
    {
    	printf("Collatz-Reihe von %d: \n", v);
    
    	while (v > 2) {
    		if (v % 2 == 0) {
    			v = v / 2; // wg warning C4244 // in integer-Rechnungen nur integer nehmen
    			printf("%d\n", v);
    		}
    		else {
    			v = 3 * v + 1;
    			printf("%d\n", v);
    		}
    	}
    }
    
    int main(void) {
    	int m;
    	int p;
    	int errCode;
    
    	printf("Erste Zahl eingeben: ");
    	if (scanf("%d", &m)) errCode = 0; // wg error C6031 // scanf benötigt einen Rückgabe Wert
    
    	printf("Zweite Zahl eingeben: ");
    	if (scanf("%d", &p)) errCode = 0;
    	
    	printCollatzReihe(m);
    	printCollatzReihe(p);
    
    	return 0;
    }
    


  • Punkt 3:

    //void printCollatzReihe(int v)
    void converge (int n, int *steps, int *max)
    

    Punkt 2:
    *max in der Funktion mit dem entsprechenden Wert füllen und später ausgeben
    Punkt 4:
    *steps in der Funktion mit dem entsprechenden Wert füllen



  • Hm, ohne thread-räuberisch zu wirken, ich bekomme es nur mit Referenzen hin. Oder ich habs immer noch nicht verstanden.

    #define _CRT_SECURE_NO_WARNINGS // scanf scheint veraltet bzw unsafe
    #include <stdio.h>
    
    void converge(int n, int& steps, int& max)
    {
    	steps = 0;
    	max = 0;
    	printf("Collatz-Reihe von %d: \n", n);
    
    	while (n > 2) {
    		if (n % 2 == 0) {
    			n = n / 2; 
    			printf("%d\n", n);
    		}
    		else {
    			n = 3 * n + 1;
    			printf("%d\n", n);
    		}
    		steps ++;
    		if (n > max) max = n;
    	}
    }
    
    int main(void) {
    	int m;
    	int p;
    	int errCode;
    
    	printf("Erste Zahl eingeben: ");
    	if (scanf("%d", &m)) errCode = 0; 
    
    	printf("Zweite Zahl eingeben: ");
    	if (scanf("%d", &p)) errCode = 0;
    
    	int steps;
    	int max;
    	
    	converge(m, steps, max);
    	printf("steps: %d \n", steps);
    	printf("max: %d \n", max);
    
    	converge(p, steps, max);
    	printf("steps: %d \n", steps);
    	printf("max: %d \n", max);
    
    	return 0;
    }
    


  • This post is deleted!


  • @zeropage sagte in Collatz-Problem in C Lösung:

    Hm, ohne thread-räuberisch zu wirken, ich bekomme es nur mit Referenzen hin.

    Die gibts in C nicht ...
    Und dass die Anzahl der benötigten Schritte ausgegeben werden soll, steht nicht in der Aufgabenstellung.



  • Und wie macht man das in C ohne Referenzen, bzw mit Pointern (?)?


  • Mod

    @zeropage sagte in Collatz-Problem in C Lösung:

    Und wie macht man das in C ohne Referenzen, bzw mit Pointern (?)?

    Prinzipiell genauso wie mit Referenzen, die Syntax ist halt ein bisschen anders. Aber die Syntax von Pointern liest du besser in einem Lehrbuch nach. Du musst halt vor allem aufpassen, dass bei Pointern die Referenzierung nicht automatisch erfolgt, sondern du das ausschreiben musst.

    Kochrezept für die drei wichtigsten Fälle:

    void foo(int &reference)
    {
      printf(%d, reference);
      reference = 123;
    }
    

    wird zu

    void foo(int *pointer)
    {
      printf(%d, *pointer);
      *pointer = 123;
    }
    

    Davon ausgehend können Pointer prinzipiell noch mehr als Referenzen. Aber weil dies alles abdeckt, was Referenzen können, sollte das zur Übersetzung Referenz->Pointer ausreichen.



  • @SeppJ sagte in Collatz-Problem in C Lösung:

    wird zu

    void foo(int *pointer)
    {
      printf(%d, *pointer);
      *pointer = 123;
    }
    

    Besser wäre hier

    void foo (int* const pointer) {
        printf (%d, *pointer);
        *pointer = 123;
    }
    

    da sich eine Referenz ja auch nicht auf eine andere Variable umbiegen lässt.


Log in to reply