none
Fakultaet berechnen - Visual Studio for-schleife/Arrays RRS feed

  • Frage

  • Moin,

    ich arbeite mit Visual Studio in einer WindowsFormsApp. In dieser gibt es 2 Textfelder (txtEingabeZahl1 und txtEingabeZahl2), eine ListBox (lstAusgabe) zur Ausgabe eines Ergebnisses und einen Buttton (btnBerechne), mit dem die Rechnung gestartet werden soll.

    Was die FormsApp machen soll: die Fakultäten aller Zahlen von txtEingabeZahl1 bis txtEingabeZahl2 berechnen und in der ListBox ausgeben. Die Rechnung sollte mithilfe eines Arrays und for-schleife(n) gemacht werden. Falls die erste eingegebene Zahl größer als die zweite ist, sollen die Zahlen bei Click auf den Button getauscht werden und anschließend die Rechnung erfolgen.

    Mein bisheriger Quellcode sieht so aus:

    namespace Fakultät_berechnen
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }

            double Zahl1, Zahl2, Zwischenablage, Ergebnis = 1;
            int[] ArrayFakultät = new int[5]; //Meiner Logik zufolge sind nur 3, statt 5 Werte nötig.

            private void btnBerechneFakultät_Click(object sender, EventArgs e)
            {
                //lstAusgabe.Items.Clear();

                Zahl1 = Convert.ToDouble(txtEingabeZahl1.Text);
                Zahl2 = Convert.ToDouble(txtEingabeZahl2.Text);

                if (Zahl1 > Zahl2)
                {
                    //Zahlen werden getauscht, falls Zahl1 größer als Zahl2 ist.
                    Zwischenablage = Zahl1;
                    Zahl1 = Zahl2;
                    Zahl2 = Zwischenablage;
                }

                for (; Zahl1 <= Zahl2; Zahl1++)
                    for (int i = 1; i < Zahl1; i++)
                    {
                        Ergebnis = Ergebnis * i;
                        lstAusgabe.Items.Add(Ergebnis);
                    }
            }
        }
    }

    Das Array habe ich noch nicht verwendet, da ich erst in einem Projekt mit Arrays gearbeitet habe.

    Montag, 24. Juni 2019 15:00

Antworten

  • Hi,
    nachfolgend ein vollständige Demo mit den Anregungen der anderen Antworter (BigInteger, Schleife) und einem Array. Die Berechnung ist in der Methode "BerechneFakultaeten" enthalten. Sie liefert ein Array mit allen Zahlen von 1 bis zur letzten Zahl. Ausgegeben wird aber nur beginnend mit der eingebenen "Startzahl".

    using System;
    using System.Numerics;
    using System.Windows.Forms;
    
    namespace WindowsFormsApp1
    {
      public partial class Form1 : Form
      {
        public Form1()
        {
          InitializeComponent();
        }
    
        TextBox txtEingabeZahl1 = new TextBox() { Dock = DockStyle.Top };
        TextBox txtEingabeZahl2 = new TextBox() { Dock = DockStyle.Top };
        Button btnBerechnen = new Button() { Text = "Fakultät berechnen", Dock = DockStyle.Top };
        ListBox lstAusgabe = new ListBox() { Dock = DockStyle.Fill };
        private void Form04_Load(object sender, EventArgs e)
        {
          this.Controls.AddRange(new Control[] { lstAusgabe, btnBerechnen, txtEingabeZahl2, txtEingabeZahl1 });
          btnBerechnen.Click += BtnBerechnen_Click;
        }
        private void BtnBerechnen_Click(object sender, EventArgs e)
        {
          var Zahl1 = Convert.ToInt16(txtEingabeZahl1.Text);
          var Zahl2 = Convert.ToInt16(txtEingabeZahl2.Text);
          int von = (Zahl1 > Zahl2) ? Zahl2 : Zahl1;
          int bis = (Zahl1 > Zahl2) ? Zahl1 : Zahl2;
          lstAusgabe.Items.Clear();
          var werte = BerechneFakultaeten(bis);
          for (int i = von; i <= bis; i++) lstAusgabe.Items.Add($"{i}: {werte[i]}");
        }
    
        private BigInteger[] BerechneFakultaeten(int bis)
        {
          BigInteger[] fak = new BigInteger[bis+1];
          BigInteger wert = 1;
          for (int i = 1; i <= bis; i++) 
          {
            wert = wert * i;
            fak[i] = wert;
          }
          return fak;
        }
      }
    }


    --
    Best Regards / Viele Grüße
    Peter Fleischer (former MVP for Developer Technologies)
    Homepage, Tipps, Tricks


    Dienstag, 25. Juni 2019 08:03

Alle Antworten

  • Bei mir scheitert es, die Arrays einzusetzen und die Fakultätsberechnung mit for-Schleife zu verstehen :D
    Montag, 24. Juni 2019 15:01
  • Hallo,

    die Fakultät ist korrekt, ich vermute aber, du musst z.B. zwischen 2 und 5 die Zahlen 2! , 3!,  4! , 5! berechnen. Was du in der Schleife machst ist aber 1! , 1!*2! , 1! * 2! * 3! ,... Du musst vor der inneren Schleife Ergebnis nochmal auf 1 zurücksetzen. Und das i bis zur Zahl1 laufen lassen.

    for (; Zahl1 <= Zahl2; Zahl1++)
    {
      Ergebnis = 1;
      for (int i = 1; i <= Zahl1; i++)
      {
        Ergebnis = Ergebnis * i;
        lstAusgabe.Items.Add(Ergebnis);
      }
    }


    Wie man in Forms genau mit Arrays umgeht weiß ich nicht, da ich die genaue Syntax nicht kenne. In etwa sähe es zum Beispiel so aus:

    int aFak[100]; // Array int index = 0; // Index im Array int n = 0; // Anzahl Einträge im Array for (; Zahl1 <= Zahl2; Zahl1++) { Ergebnis = 1; for (int i = 1; i <= Zahl1; i++) { Ergebnis = Ergebnis * i; aFak[index] = Ergebnis; index++;
    n++; } } for (int i=1; i < n; i++) { lstAusgabe.Items.Add(aFak[i]); }

    Gruß Guido

    Edit: wie Christoph Biegner korrekterweise erwähnt: nur Ergebnis = … gehört in die Schleife, alles andere da drunter.

    for (; Zahl1 <= Zahl2; Zahl1++)
    {
      Ergebnis = 1;
      for (int i = 1; i <= Zahl1; i++)
      {
        Ergebnis = Ergebnis * i;
      }
      aFak[index] = Ergebnis; 
      index++;
      n++;
    }
    

    Dienstag, 25. Juni 2019 05:51
  • Die Verwendung eines Arrays mit vordefnierter Größe ist problematisch, da man nicht weiss, wieviele Berechnungen durchgeführt werden. Daher ist es sicherlich besser, eine Generische Collection zu verwenden. Aber eigentlich ist auch die nicht nötig, wenn man die berechnete Ausgabe ohnehin direkt ausgibt und nicht weiterverwendet.

    Zudem ist die Fakultät immer das Ergebnis beim Verlassen der inneren Schleife (wenn man sie denn so berechnet, wie das hier geschieht.

                lstAusgabe.Items.Clear();
    
                var Zahl1 = Convert.ToInt16(txtEingabeZahl1.Text);
                var Zahl2 = Convert.ToInt16((txtEingabeZahl2.Text);
    
                if (Zahl1 > Zahl2)
                {
                    //Zahlen werden getauscht, falls Zahl1 größer als Zahl2 ist.
                    var Zwischenablage = Zahl1;
                    Zahl1 = Zahl2;
                    Zahl2 = Zwischenablage;
                }
    
                for (int i = Zahl1; i <= Zahl2; i++)
                {
                    var Ergebnis = 1;
                    for (int j = 1; j <= i; j++)
                    {
                        Ergebnis = Ergebnis * j;
                    }
                    lstAusgabe.Items.Add($"Fakultät von {i} ist {Ergebnis}");
                }


    Dienstag, 25. Juni 2019 06:52
  • Zudem ist die Fakultät immer das Ergebnis beim Verlassen der inneren Schleife (wenn man sie denn so berechnet, wie das hier geschieht.

                lstAusgabe.Items.Clear();
    
                var Zahl1 = Convert.ToInt16(txtEingabeZahl1.Text);
                var Zahl2 = Convert.ToInt16((txtEingabeZahl2.Text);
    
                if (Zahl1 > Zahl2)
                {
                    //Zahlen werden getauscht, falls Zahl1 größer als Zahl2 ist.
                    var Zwischenablage = Zahl1;
                    Zahl1 = Zahl2;
                    Zahl2 = Zwischenablage;
                }
    
                for (int i = Zahl1; i <= Zahl2; i++)
                {
                    var Ergebnis = 1;
                    for (int j = 1; j <= i; j++)
                    {
                        Ergebnis = Ergebnis * j;
                    }
                    lstAusgabe.Items.Add($"Fakultät von {i} ist {Ergebnis}");
                }


    Ohje, das stimmt absolut. Schande auf mein Haupt! War wohl zu früh am morgen. Selbstverständlich gehört nur die Ergebnis-Berechnung in die for Schleife. Alles andere gehört nach draußen.

    Entschuldigung für den falschen Code in meiner letzten Antwort.

    Guido

    Dienstag, 25. Juni 2019 07:12
  • Hallo,

    du sollst ein Array als "Hilfsmittel" oder als "Ergebnisliste" verwenden?

    Nebenbei: Du benötigst nur Ganzzahlen, deshalb würde ich nicht Double konvertieren.
    Vorab: Bedenke, das int.MaxValue bereits für 13! zu klein ist. Für Int64 (long) wird 21! bereits zu groß.

    Es gibt aber den Namespace: System.Numerics;
    Dort gibt es den Typ BIGINTEGER, den würde ich für die Fakultäten verwenden.
    static void Rechne(int von, int bis) {
      BigInteger fakultät = 1;
      for (int i=2; i< von; i++) {
        fakultät *= i;
      }
      for (int i= von; i<=bis; i++) {
        fakultät *= i;
        Ausgabe(i, fakultät);
      }
    }
    
    public static void Ausgabe(int zahl, BigInteger fakultät) {
      string info = $"{zahl} => {fakultät}  Int32-Overflow? {fakultät > Int32.MaxValue}, Int64-Overflow? {fakultät > Int64.MaxValue}";
      //Console.WriteLine(info);
      lstAusgabe.Items.Add(info); }
    Gruß

    Dienstag, 25. Juni 2019 07:16
  • Hi,
    nachfolgend ein vollständige Demo mit den Anregungen der anderen Antworter (BigInteger, Schleife) und einem Array. Die Berechnung ist in der Methode "BerechneFakultaeten" enthalten. Sie liefert ein Array mit allen Zahlen von 1 bis zur letzten Zahl. Ausgegeben wird aber nur beginnend mit der eingebenen "Startzahl".

    using System;
    using System.Numerics;
    using System.Windows.Forms;
    
    namespace WindowsFormsApp1
    {
      public partial class Form1 : Form
      {
        public Form1()
        {
          InitializeComponent();
        }
    
        TextBox txtEingabeZahl1 = new TextBox() { Dock = DockStyle.Top };
        TextBox txtEingabeZahl2 = new TextBox() { Dock = DockStyle.Top };
        Button btnBerechnen = new Button() { Text = "Fakultät berechnen", Dock = DockStyle.Top };
        ListBox lstAusgabe = new ListBox() { Dock = DockStyle.Fill };
        private void Form04_Load(object sender, EventArgs e)
        {
          this.Controls.AddRange(new Control[] { lstAusgabe, btnBerechnen, txtEingabeZahl2, txtEingabeZahl1 });
          btnBerechnen.Click += BtnBerechnen_Click;
        }
        private void BtnBerechnen_Click(object sender, EventArgs e)
        {
          var Zahl1 = Convert.ToInt16(txtEingabeZahl1.Text);
          var Zahl2 = Convert.ToInt16(txtEingabeZahl2.Text);
          int von = (Zahl1 > Zahl2) ? Zahl2 : Zahl1;
          int bis = (Zahl1 > Zahl2) ? Zahl1 : Zahl2;
          lstAusgabe.Items.Clear();
          var werte = BerechneFakultaeten(bis);
          for (int i = von; i <= bis; i++) lstAusgabe.Items.Add($"{i}: {werte[i]}");
        }
    
        private BigInteger[] BerechneFakultaeten(int bis)
        {
          BigInteger[] fak = new BigInteger[bis+1];
          BigInteger wert = 1;
          for (int i = 1; i <= bis; i++) 
          {
            wert = wert * i;
            fak[i] = wert;
          }
          return fak;
        }
      }
    }


    --
    Best Regards / Viele Grüße
    Peter Fleischer (former MVP for Developer Technologies)
    Homepage, Tipps, Tricks


    Dienstag, 25. Juni 2019 08:03