Fakultät programmieren!

Status
Für weitere Antworten geschlossen.

DJWxD

Cadet 1st Year
Registriert
Nov. 2020
Beiträge
12
#include <stdio.h> /* Programm zur Übung 2*/
#include <math.h>

int main(void)
{
int k, ergebnis, wie_weit, j, fakultat;

scanf("%i", &wie_weit);
fakultat=1;

for(k=1;k<=wie_weit;k=k+1)
{
j=k*2;

fakultat=fakultat*k;
printf("%i! = %i\n", j, fakultat);
}

return 0;
}

Hallo,
im folgendem Programm würde ich gerne die einzelnen Fakultäten berechnen von "j" in diesem Fall.
J wird pro lauf um 2 größer, also wenn ich 5 eingebe, kommt 2,4,6,8 und 10 raus. Von diesen Zahlen würde ich jetzt gerne die Fakultät berechnen. Ich hab es schon damit probier die Fakultät Variable mit *2 zu berechnen, jedoch ohne erfolg.
LG
Damon
PS: das Programm hier hab übrigens ich geschrieben, hatten sich letztens n paar beschwert das ich hier keine eigen Leistung erbringe.
 
Moin,
dazu zweierlei:
a) Wenn du bereits mit dem Forum bzgl. Programmieren kollidiert bist, solltest du mittlerweile die CODE-Tags kennen.
b) Da dir die mathematische Basis zu fehlen scheint, was du überhaupt zu tun hast: https://de.wikipedia.org/wiki/Fakultät_(Mathematik) Öhm. Moment, hab möglicherweise missverstanden, was du überhaupt vorhast, falls ich das nun richtig interpretiere, versuchst du innerhalb einer Schleife zwei Variablen zu modifizieren, die aber unabhängig voneinander laufen. Falls dir das irgendwie weiterhilft bzw. eine Erklärungsentwirrung triggert. ;)
 
  • Gefällt mir
Reaktionen: BAGZZlash, Raijin, Madman1209 und 2 andere
Dann brauchst du in deiner For-Schleife noch eine Schleife, die alle natürlichen Zahlen bis j multipliziert.
 
  • Gefällt mir
Reaktionen: honky-tonk
Ich hoffe, ich kann dir mit meiner Antwort helfen.
Die Fakultät einer beliebigen natürlichen Zahl berechnet man entweder
  • iterativ, indem man eine Schleife programmiert, in der solange mit (Zahl-1) multipliziert wird, bis man bei 1 ankommt (alternativ Hochzählen bis Zahl)
  • rekursiv, indem man mit dem Rückgabewert eine Subroutine multipliziert, die man mit dem Argument (Zahl-1) aufruft und als Antwort entweder am Ende eine 1 oder einen erneuten Subroutinenaufruf bekommt.
 
DJWxD schrieb:
Von diesen Zahlen würde ich jetzt gerne die Fakultät berechnen. Ich hab es schon damit probier die Fakultät Variable mit *2 zu berechnen, jedoch ohne erfolg.
naja, wie berechnet man denn die Fakultät einer Zahl? Alles was du bisher mit deiner Schelife gemacht hast ist die Eingabewerte für die Fakultätsberechnung - aber selbst berechnet hast du sie noch nicht ...


Nicht dass ich verstehe warum du für die ersten n geraden Zahlen das tun willst, aber kann mir auch egal sein. Aber du hast also 2, 4, 6, 8 und 10. Davon willst du die Fakulatät berechnen. Für jede einzelne Zahl. Also musst du doch auch was machen, oder nicht?
DJWxD schrieb:
Ich hab es schon damit probier die Fakultät Variable mit *2 zu berechnen, jedoch ohne erfolg.
Das verstehe ich überhaupt nicht. Nimm dir n Zettel und Stift und berechne die Fakultät schrittweise. Was genau willst du hier mit der Zahl 2?
Fakultät von 2 ist bei dir 2 * 2, oder wie soll ich das verstehen?

Kurzum, deine Schleife gibt dir bisher nur den Input für eine weitere Prozedur welche dann für den Input unabhängig von den anderen Ergebnissen die Fakultät berechnet.

Und ja, mit Optmierung würde man natürlich Ergebnisse von vorherigen Zahlen gerne wiederverwenden - logoischerwiese könntest du die Fakultät von 4 bei der Berechnung der Fakultät von 6 wiederverwenden - aber bei dir heißt es ein Schritt vor dem anderen.


Achja, du weißt schon was Fakultät ist? Nicht dass du das hier mit 2er Potenzen verwechselst?! Da darfst du gerne mit 2 multiplizieren ...
 
  • Gefällt mir
Reaktionen: xenon-seven
Dein Problem ist, dass du versucht, in ein und derselben Schleife zwei komplett verschiedene Dinge zu tun. Du zählst k einerseits hoch, um daraus j zu berechnen, aber du willst die Fakultät ja nicht auf Basis von k, sondern j berechnen! Das klappt so natürlich nicht.

Für j muss die k-Schleife bis wie_weit zählen, aber die Berechnung der Fakultät muss ja eine Multiplikation in einer Schleife bis j durchführen. Gibst du nun bei wie_weit 5 ein, zählst du also von 1 bis 5, daraus ergibt sich dann aber zB in der letzten Iteration für j eine 10 und diese 10 ist es, die du in einer Schleife für die Berechnung der Fakultät bräuchtest.


Wie berechnet man die Fakultät in einer Schleife? So wie man es von Hand macht.

4! ist 1 * 2 * 3 * 4

Ergo: In einer Schleife mit 4 Iterationen jeweils das vorherige Multiplikationsergebnis mit dem aktuellen Zähler multiplizieren.


Zur besseren Übersicht würde ich dir empfehlen, für die Berechnung der eigentlichen Fakultät eine separate Funktion zu schreiben, zB "int fakul(int f)". Diese Funktion rufst du dann in deiner k-Schleife mit dem aktuellen j-Wert auf und hast direkt die gewünschte Fakultät, ohne dich mit ineinander verschachtelten Schleifen vertun zu können.
 
Besser 1. die Code-Funktion im Forum nehmen und 2. den Algorithmus vereinfachen.
C++:
#include <stdio.h>   /* Programm zur Übung 2*/
#include <math.h>

int main(void)
{
int wie_weit, fakultaet;

   scanf("%i", &wie_weit);
   fakultaet=1;
   printf("%i! = ", wie_weit);

   while (wie_weit > 1)
   {
     fakultaet=fakultaet*wie_weit;
     wie_weit--;
   }
   printf("%i\n", fakultaet);
return 0;
}

Wenn du die Fakultät bis 4 willst, musst du nich 1*2*3*4 rechnen, sondern kannst auch 4*3*2 rechnen. Das Multiplizieren mit 1 kannst du auslassen. Und wenn du die Variable wie_weit direkt benutzt und runterzählst, brauchst du nur 2 statt 4 Variablen.

Mit einer integer kannst du übrigens nur bis 12! gehen, dann überschreitest du die maximale Größe des Datentyps.
 
@Fortatus : Du ignorierst dabei aber völlig die Vorgabe, dass bei einer Eingabe von 5 durch den Benutzer die Fakultäten für 2 / 4 / 6 / 8 / 10 berechnet werden sollen und nicht einfach nur für die Eingabe 5.

DJWxD schrieb:
wenn ich 5 eingebe, kommt 2,4,6,8 und 10 raus. Von diesen Zahlen würde ich jetzt gerne die Fakultät berechnen.
 
Geht es um die Fakultät der ersten X ganzzahligen Vielfachen von 2? Oder soll bei Eingabe von 5 die Fakultät von 1,2,3,4,5 und bei Eingabe von 10 die Fakultät von 1,2,3,4,5,6,7,8,9,10 ausgegeben werden? (Dh. ist die Ausgabe der Fak von 2,4,6,8,10 gewollt oder ein Bug in dieser Implementierung?)

Selbst wenn ich alle Posts hier lese, bin ich mir nicht sicher, was wirklich gewollt ist.

C++:
#include <stdio.h>   /* Programm zur Übung 2*/
#include <math.h>

int main(void)
{
int wie_weit, i, fakultaet;

   scanf("%i", &wie_weit);
   fakultaet=1;

   for(i=1;i<=wie_weit;i++)
   {
     fakultaet=fakultaet*i;
     printf("%i! = %i\n", i, fakultaet);
   }
return 0;
}
Immernoch 2 Variablen gespart. Wenn es bei Eingabe von 5 die Fakultät bis 10 ausgeben soll: Vor die for-Schleife ein wie_weit *= 2; packen.
Wenn nur die Vielfachen von 2 ausgegeben werden sollen, eine if (i%2 == 0) Bedingung um den printf in der Schleife packen.
 
Zuletzt bearbeitet:
also wenn 5 eingegeben wird, willst du ausgegeben haben die fakultät von 0,1,2,3,4 und 5?
sprich 1, 1, 2, 6, 24, 120?

Beim programmieren ist es sinnvoll wiederkehrende Dinge in Funktionen auszulagern, sprich die Fakultätsberechung wäre so etwas, der du einen integer übergibst und einen integer zurückbekommst.

Auch eine prettyPrint Funktion könntest du schreiben, aber das erstmal nebensächlich.

Abstrahieren ist das magische Wort.

Edith:
Du könntest auch ein Array erstellen, das muss ja nicht groß sein :p
 
Zuletzt bearbeitet:
Ich sag's mal so: unabhängig davon wie die Aufgabe nun tatsächlich aussieht - jeder hier versteht darunter offensichtlich etwas anderes - sollte @DJWxD genug Input haben, um selbst weiterzukommen.
 
Also wenn ich das richtig verstehe, sollst du für die ersten n geraden Zahlen die Fakultät berechnen, also für dein Beispiel mit n=5 wären das die Zahlen (1*2)!, (2*2)!, (3*2)!, (4*2)! und (5*2)!.

Das würde ich mit zwei Methoden machen: Eine, die dir die Fakultät jeweils einer dieser Zahlen berechnet, und eine weitere, die deine Aufgabe unter Verwendung dieser Methode löst. Du könntest beides natürlich auch in einer einzelnen Methode machen, aber dann hättest du eine innere Schleife (also eine Schleife in einer Schleife), was recht unübersichtlich und nicht so flexibel einsetzbar ist.

Hier mal das Ganze in Java, da ich mich mit C++ leider nicht auskenne:
Java:
//Hier wird die Fakultät für jeweils eine Zahl berechnet
public static int factorial(int n) {
    int factorial = 1;
    for (int i = 1; i <= n; i++) {
        factorial *= i;
    }
    return factorial;
}

//Dies löst deine Aufgabe mit Hilfe der obigen Methode
public static int[] solve(int n) {
    int[] list = new int[n];
    for (int i = 0; i < n; i++) {
        list[i] = factorial((i+1)*2)//i+1 aufgrund der Indexverschiebung
    }
    return list;
}
Wie du siehst, berechnet factorial(int n) die Fakultät einer beliebigen Zahl n, während solve(int n) eine Liste der Größe n erstellt, die mit den jeweiligen Fakultäten gefüllt wird. factorial(int n) wird hier also jeweils das Doppelte aller natürlichen Zahlen von 1 bis n übergeben.
Wichtig: n sind hier lediglich die inneren Variabelnamen der Methoden und unabhängig voneinander.
 
SaschaHa schrieb:
Also wenn ich das richtig verstehe, sollst du für die ersten n geraden Zahlen die Fakultät berechnen, also für dein Beispiel mit n=5 wären das die Zahlen (1*2)!, (2*2)!, (3*2)!, (4*2)! und (5*2)!.
du vergißt die gerade Zahl 0.
 
@peter.hahn
0! ist ein Sonderfall. Will man diesen berücksichtigen, kann man factorial(int n) am Anfang einfach eine if-Abfrage wie if (n == 0) return 1; hinzufügen, wodurch die Methode automatisch mit dem Rückgabewert 1 beendet wird. solve(int n) müsste dementsprechend eine Liste der Größe n+1 erstellen und mit Daten füllen, sodass die Methode entsprechend abgeändert werden muss. Wenn ich das richtig sehe, soll das in der Aufgabe jedoch nicht berücksichtigt und lediglich eine Liste der Größe n erstellt werden, aber theoretisch hast du natürlich Recht.
 
@SaschaHa und jetzt? du hattest sie vergessen. Punkt. Sonst hättest du korrekterweise geschrieben (ausgeschlossen gerade Zahl 0).
Beim Programmieren muss man so genau arbeiten..
 
@peter.hahn
Sei doch nicht so streng mit ihm. Schließlich ist die genaue Aufgabenstellung nicht bekannt.
Dass 0!=1 definiert ist, wissen wir. Andererseits stellt sich mir die Frage, ob 0 jetzt wirklich zu den natürlichen Zahlen gehört und die normale Fakultät (Späße mit der Gamma-Fkt. seien mal ausgeklammert) nicht nur ausschließlich für diese definiert ist.
Bei sonstigen Sonderfällen könnte man sich ja noch um das Resultat bei Eingabe einer negativen Zahl kümmern.

Dass wir uns die Finger wund schreiben, bringt ja nichts, solange sich der TE nicht meldet.
 
BoardBricker schrieb:
Andererseits stellt sich mir die Frage, ob 0 jetzt wirklich zu den natürlichen Zahlen gehört
Als natürliche Zahl, wäre es Definitionssache, sicherlich, aber nur dort.

Und ja, der TE hat mehr als Genug Info für seine Hausaufgaben bekommen, die er für seine Formulierung überhaupt nicht verdient hatte.
 
Zuletzt bearbeitet:
Also programmtechnisch musst du doch lösen:
Eingabe
Array-definition Fakultät(Eingabe)
Schleife A=1 bis Eingabe
Array(A)=!(Eingabe*2)
Return

Ausgabe entsprechend
 
@peter.hahn
Aus meiner Formulierung, bei der ich sogar auf das Beispiel des Threaderstellers eingehe, der die 0 selbst nicht berücksichtigt hat, geht doch eindeutig hervor, dass ich mich auf die ersten geraden Zahlen größer 0 beziehe, auch wenn ich das nicht explizit dazugesagt habe. Du scheinst ja selbst bereits aus dem Kontext geschlossen zu haben, dass ich keine negativen geraden Zahlen meine, obwohl ich auch diese in meiner Formulierung nicht explizit ausgeschlossen habe. Warum also die Doppelmoral?

Solange der Threadersteller uns nicht sagt, was genau die Aufgabenstellung ist und er selbst die 0! nicht berücksichtigt, müssen wir doch auch nicht sämtliche Abfragen beachten, die möglicherweise gar nicht für die Aufgabe relevant sind.

Und wenn du wissen willst, wie genau ich arbeite: Ich verwende für gewöhnlich Annotations, um die erlaubten Parameter zu definieren. Sonderfälle frage ich dann an anderer Stelle ab oder implementiere eine Sekundärmethode, die das übernimmt. Vorteil: Die Hauptmethode ist ohne all diese Abfragen etwas schneller, was insbesondere bei Verwendung innerhalb von Schleifen (wie hier) einen Performance-Schub bringen kann.
 
Status
Für weitere Antworten geschlossen.
Zurück
Oben