Zahlenkette invertieren in C?

4 Antworten

Rekursiv geht's etwa so:

int revert ( int zahl ) {
    if (zahl<10)
        return zahl;

    int ziffer = zahl%10;
    int rest = zahl / 10;
    return 10^??? * ziffer + revert(rest);
}

Das Problem steckt im „10^???“: Du weißt nicht, wie viele Stellen rest hat, und das lässt sich auch nicht so einfach herausfinden.

In einer ähnlichen Frage hatte Schachpapa aber eine geniale Idee: Er übergibt auch das Resultat (anfangs 0) und klebt daran die abgetrennte Ziffer immer hinten an. Das ist billig (resultat*10+ziffer).

Es funktioniert wie mit einem Stapel Bücher a und einem anfangs leeren Stapel b: lege das oberste Buch von a oben auf b. Sobald a leer ist, enthält b alle Bücher von a in umgedrehter Reihenfolge − und man muss dazu nicht herausfinden, wie hoch die Stapel sind.

int shiftall ( int a, int b ) {
    if (a==0)      // "Stapel" a ist leer
        return b;

    int z = a%10;  // "oberste" Ziffer
    a = a/10;      // aus a entfernen
    b = 10*b+z;    // und "oben" auf b legen

    return shiftall(a, b);
}

int revert ( int zahl ) { return shiftall(zahl, 0); }

chudad 
Beitragsersteller
 10.11.2021, 14:10

Ich hab noch ne Frage, kannst du meine Anfrage zumindest temporär annehmen?

chudad 
Beitragsersteller
 10.11.2021, 14:06

Ok danke sehr hilfreich, ja der Schachpapa hat mir schon das ein oder andere mal geholfen

Du kannst dir die einzelnen Stellen mit Modulo und Ganzzahldivisionen "holen".

Die einzelnen Stellen stellen fügst du dann "umgekehrt" wieder zusammen:

1000 * n1 + 100 * n2 + 10 + n3 + n4

(n1 -n4 sind hierbei EIner- Zehnher-, Hunderter- und Tausenderstelle der ursprünglichen Zahl)

ohne dabei komplexe C Skills anzuwenden. Also ohne Schleifen, Zeiger usw. Also Rekursion wäre möglich, 

Zumindest Schleifen sollte man nicht als "komplexe Skills" einordnen, sondern sich damit vertraut machen.


chudad 
Beitragsersteller
 10.11.2021, 10:23

Noch ne andere Frage, was ist wenn ich die Anzahl der Elemente nicht im Vorhinein festlege, ich also während der Laufzeit eine Zahlenkette eingebe, die unterschiedlich lang sein kann? Wie mach ich das dann mit Rekursion, also dass es dann solange abarbeitet bis ich das Ende erreich habe?

chudad 
Beitragsersteller
 10.11.2021, 10:21

Aber ich würde gerne erstmal versuchen Rekursion richtig zu verstehen bevor ich mit Schleifen anfange.
Danke für die Antwort👌

gfntom  10.11.2021, 10:22
@chudad

Meiner Meinung nach bedeutet das, das Pferd von hinten aufzuzäumen, aber wie du meinst.

chudad 
Beitragsersteller
 10.11.2021, 10:24
@gfntom

Ja würde auch gerne Schleifen benutzen, wäre viel entspannter. Aber Rekursion kann auch sinnvoll sein wenn man es versteht, was ich derzeit noch nicht von mir behaupten kann.

Mal so runtergeschrieben, nicht getestet, iterativ und rekursiv

// iterativ

if(zahl<10)return zahl;
int j=10;
do{j*=10;}while(zahl>=j)
j/=10;
int vorderste_stelle;
while{zahl>0}
    vorderste_stelle=zahl/j;    
    printf("%i\n";vorderste_stelle);
    zahl = zahl - vorderste_stelle;
    j/=10;
}

//rekursiv
void start(int zahl){
   int j=10;
   do{j*=10;}while(zahl>=j)
   j/=10;
   print_i(zahl, j);
}
void print_i(int zahl, int j){
   if(zahl<10)printf("%i";zahl);return;
   vorderste_stelle=zahl/j;    
   printf("%i\n";vorderste_stelle);
   print_i(zahl - vorderste_stelle,j/10);
}
    


Woher ich das weiß:eigene Erfahrung – Hobby und teilweise beruflich

chudad 
Beitragsersteller
 10.11.2021, 11:32

Danke, kannst du mir sagen (brauchst nicht extra nen Code Schreiben) wie ich die die rekursiv Variante ohne Pointer mache? Also noch einfacher?

nobytree2  10.11.2021, 11:45
@chudad

die untere Version ist eine rekursive ohne Pointer. Es werden ja nur Daten weitergegeben und keine zurückgeholt (das würde man über return oder bei mehreren über pointer machen).

chudad 
Beitragsersteller
 10.11.2021, 12:06
@nobytree2

Jo alles gut, ich nutze das hier auch eher um auf Ideen zu kommen.

Mein Vorschlag zur "Umkehrung" einer Zahl:

   int iZahl1,iZahl2;

   iZahl1 = 1234;
   iZahl2 = 0;
   while(iZahl1 > 0) {
        iZahl2 *= 10;
        iZahl2 += iZahl1 % 10;
        iZahl1 /= 10;
   }

chudad 
Beitragsersteller
 10.11.2021, 11:43

Danke, hast du auch nen Vorschlag, ohne Pointer und while? Und das man das als rekursive Funktion erstellt, bei der man beliebig große Zahlen eingeben kann?

tunik123  10.11.2021, 12:02
@chudad

Pointer kommen dort gar nicht vor, nur eine Multiplikation mit 10, eine Modulo-Division und eine "echte" Division durch 10.

Man kann das theoretisch auch rekursiv programmieren, aber was soll das?

Im Vergleich zu Schleifen ist Rekursion mindestens zwei Level schwieriger. Da würde ich als Anfänger die Finger von lassen.

Die Größe der Zahlen wird nur durch den Zahlenbereich des int begrenzt.

chudad 
Beitragsersteller
 10.11.2021, 12:06
@tunik123

Naja würde das gerne verstehen und da bietet sich sowas an, ist es möglich dein Programm in eine rekursives zu wandeln?
Erstmal danke für die Antwort.