C# :: Aufgabe #216

2 Lösungen Lösungen öffentlich

Brüche und überladene Operatoren

Anfänger - C# von Exception - 09.06.2018 um 09:07 Uhr
- Erstelle eine Klasse "Bruch"

- In dieser Klasse gibt es zwei Attribute: Zähler, Nenner (jeweils Integer)

- In dieser Klasse gibt es zudem noch überladene Opteratoren (+, -, *, /)
Diese Operatoren haben jeweils zwei Parameter, die übergeben werden müssen -> zwei Objekte der Klasse Bruch.
Die Operatoren geben einen neuen Bruch zurück.

In der Hauptmethode (oder sonst wo) soll dann folgendes möglich sein:
Quellcode ausblenden C#-Code
Bruch b1 = new Bruch(1, 2);
Bruch b2 = new Bruch(3, 4);
Bruch b3 = b1 + b2;  // auch -, *, /

- Die Klasse Bruch braucht für das Teilen von Brüchen evtl. noch ein bisschen mehr... #Methoden ;)

- Das Anlegen / Erzeugen von Brüchen soll mit Textboxen realisiert werden, sodass das ganze Programm grafisch etwas her macht.

- Die Rechenopertation (+,-,*,/) soll mit einer Dropdown Liste o.ä. ausgewählt werden.

- Mit einem Button soll die Berechnung starten und das Ergebnis anschließend in zwei weitere Textboxen (read only) geschrieben werden.

- Damit die Brüche nicht zu groß werden (50/100 o.ä.) soll bevor das Ergebnis in die Textbox geschrieben wird geschaut werden, ob sich der neue Bruch kürzen lässt.

Lösungen:

vote_ok
von Z3RP (1020 Punkte) - 18.06.2018 um 08:47 Uhr
BruchC Klasse
Quellcode ausblenden C#-Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Bruch
{
    public class BruchC
    {
        public double zaehler { get; set; }
        public double nenner { get; set; }

        public BruchC(double zaehler, double nenner)
        {
            this.zaehler = zaehler;
            this.nenner = nenner;
        }

        public static BruchC operator +(BruchC b1, BruchC b2)
        {
            bruchKuerzen(ref b1, ref b2);
            if (b1.nenner == b2.nenner)
            {
                return new BruchC(b1.zaehler + b2.zaehler, b1.nenner);
            }
            else
            {
                return new BruchC(b1.zaehler * b2.nenner + b2.zaehler * b1.nenner, b1.nenner * b2.nenner);
            }

        }

        public static BruchC operator -(BruchC b1, BruchC b2)
        {
            bruchKuerzen(ref b1, ref b2);
            if (b1.nenner == b2.nenner)
            {
                return new BruchC(b1.zaehler - b2.zaehler, b1.nenner);
            }
            else
            {
                return new BruchC(b1.zaehler * b2.nenner - b2.zaehler * b1.nenner, b1.nenner * b2.nenner);
            }

        }

        public static BruchC operator *(BruchC b1, BruchC b2)
        {
            bruchKuerzen(ref b1, ref b2);

            return new BruchC(b1.zaehler * b2.zaehler, b1.nenner * b2.nenner);
        }

        public static BruchC operator /(BruchC b1, BruchC b2)
        {
            BruchC newB2 = new BruchC(b2.nenner, b2.zaehler);
            BruchC newB = b1* newB2;
            bruchKuerzen(ref newB2, ref newB);

            return newB;
        }

        private static void bruchKuerzen(ref BruchC b1, ref BruchC b2)
        {
            if (b1 != null)
                for (double i = b1.nenner; i >= 0; i--)
                {
                    if (b1.nenner % i == 0 && b1.zaehler % i == 0)
                    {
                        b1.nenner /= i;
                        b1.zaehler /= i;
                        break;
                    }
                }

            if (b2 != null)
                for (double i = b2.nenner; i >= 0; i--)
                {
                    if (b2.nenner % i == 0 && b2.zaehler % i == 0)
                    {
                        b2.nenner /= i;
                        b2.zaehler /= i;
                        break;
                    }
                }
        }
    }
}


MainWindow.xaml
<Window x:Class="Bruch.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Bruch"
mc:Ignorable="d"
Title="Bruch Rechner" Height="180.932" Width="249.153" WindowStyle="ToolWindow" ResizeMode="NoResize">
<Grid>
<TextBox x:Name="z1" PreviewTextInput="NumberValidationTextBox" HorizontalAlignment="Left" Height="27" Margin="21,19,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="27" TextAlignment="Center"/>
<TextBox x:Name="n1" PreviewTextInput="NumberValidationTextBox" HorizontalAlignment="Left" Height="27" Margin="21,51,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="27" TextAlignment="Center"/>
<TextBox x:Name="z2" PreviewTextInput="NumberValidationTextBox" HorizontalAlignment="Left" Height="27" Margin="97,19,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="27" TextAlignment="Center"/>
<TextBox x:Name="n2" PreviewTextInput="NumberValidationTextBox" HorizontalAlignment="Left" Height="27" Margin="97,51,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="27" TextAlignment="Center"/>
<TextBox x:Name="z3" HorizontalAlignment="Left" Height="27" Margin="166,19,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="27" IsReadOnly="True" TextAlignment="Center"/>
<TextBox x:Name="n3" HorizontalAlignment="Left" Height="27" Margin="166,51,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="27" IsReadOnly="True" TextAlignment="Center"/>
<Label Content="= " HorizontalAlignment="Left" Margin="142,33,0,0" VerticalAlignment="Top" Height="31" Width="19"/>
<Button Content="Rechne" HorizontalAlignment="Left" Margin="21,97,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click"/>
<ComboBox x:Name="opr" HorizontalAlignment="Left" Margin="54,37,0,0" VerticalAlignment="Top" Width="38" Height="27" SelectedIndex="0"/>

</Grid>
</Window>


MainWindow.xaml.cs
Quellcode ausblenden C#-Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace Bruch
{
    /// <summary>
    /// Interaktionslogik für MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            opr.Items.Add("+");
            opr.Items.Add("-");
            opr.Items.Add("*");
            opr.Items.Add("/");
        }

        private void NumberValidationTextBox(object sender, TextCompositionEventArgs e)
        {
            var textBox = sender as TextBox;
            e.Handled = Regex.IsMatch(e.Text, "[^0-9]+");
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            BruchC b1 = new BruchC(Convert.ToDouble(z1.Text), Convert.ToDouble(n1.Text));
            BruchC b2 = new BruchC(Convert.ToDouble(z2.Text), Convert.ToDouble(n2.Text));




            BruchC b3 = null;


            switch (opr.SelectedItem)
            {
                case "+":
                    b3 = b1 + b2;
                    break;
                case "-":
                    b3 = b1 - b2;
                    break;
                case "*":
                    b3 = b1 * b2;
                    break;
                case "/":
                    b3 = b1 / b2;
                    break;
            }


            z3.Text = Convert.ToString(b3.zaehler);
            n3.Text = Convert.ToString(b3.nenner);
        }
    }
}
vote_ok
von daniel59 (4260 Punkte) - 12.07.2018 um 07:30 Uhr
MainWindow.xaml.cs
Quellcode ausblenden C#-Code
using System.Windows;

namespace WpfBruchrechner
{
    /// <summary>
    /// Interaktionslogik für MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void buttonCalc_Click(object sender, RoutedEventArgs e)
        {
            int le, ld, re, rd;
            if (int.TryParse(textBoxEnumeratorLeft.Text, out le) && int.TryParse(textBoxDenominatorLeft.Text, out ld) && int.TryParse(textBoxEnumeratorRight.Text, out re) && int.TryParse(textBoxDenominatorRight.Text, out rd) && ld != 0 && rd != 0)
            {
                Fraction left = new Fraction(le, ld);
                Fraction right = new Fraction(re, rd);
                Fraction result;
                string action = comboBoxAction.SelectedItem.ToString();

                switch (action)
                {
                    case "+":
                        result = left + right;
                        break;

                    case "-":
                        result = left - right;
                        break;

                    case "*":
                        result = left * right;
                        break;

                    case "/":
                        if (re == 0)
                        {
                            MessageBox.Show("Eingaben ungültig!", "", MessageBoxButton.OK, MessageBoxImage.Warning);
                            return;
                        }
                        result = left / right;
                        break;

                    default:
                        result = new Fraction(0, 0);
                        break;
                }

                textBoxEnumeratorResult.Text = result.Enumerator.ToString();
                textBoxDenominatorResult.Text = result.Denominator.ToString();
            }
            else
            {
                MessageBox.Show("Eingaben ungültig!", "", MessageBoxButton.OK, MessageBoxImage.Warning);
            }
        }
    }
}


MainWindow.xaml
Quellcode ausblenden XML-Code
<Window
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfBruchrechner"
        xmlns:System="clr-namespace:System;assembly=mscorlib" x:Class="WpfBruchrechner.MainWindow"
        mc:Ignorable="d"
        Title="Bruchrechner" SizeToContent="WidthAndHeight" ResizeMode="CanMinimize">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <Grid Grid.Row="0">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="Auto"/>
            </Grid.ColumnDefinitions>
            <Grid Grid.Column="0" Margin="10">
                <TextBox x:Name="textBoxEnumeratorLeft" HorizontalAlignment="Left" Height="23" Margin="54,10,0,0" TextWrapping="Wrap" Text="1" VerticalAlignment="Top" Width="50" TextAlignment="Center"/>
                <TextBlock x:Name="textBlock" HorizontalAlignment="Left" Margin="10,13,0,0" TextWrapping="Wrap" Text="Zähler" VerticalAlignment="Top"/>
                <TextBox x:Name="textBoxDenominatorLeft" HorizontalAlignment="Left" Height="23" Margin="54,38,0,0" TextWrapping="Wrap" Text="1" VerticalAlignment="Top" Width="50" TextAlignment="Center"/>
                <TextBlock x:Name="textBlock1" HorizontalAlignment="Left" Margin="10,41,0,0" TextWrapping="Wrap" Text="Nenner" VerticalAlignment="Top"/>
            </Grid>
            <ComboBox x:Name="comboBoxAction" Grid.Column="1" Width="50" Height="23" SelectedIndex="0">
                <System:String>+</System:String>
                <System:String>-</System:String>
                <System:String>*</System:String>
                <System:String>/</System:String>
            </ComboBox>
            <Grid Grid.Column="2" Margin="10">
                <TextBox x:Name="textBoxEnumeratorRight" HorizontalAlignment="Left" Height="23" Margin="54,10,0,0" TextWrapping="Wrap" Text="1" VerticalAlignment="Top" Width="50" TextAlignment="Center"/>
                <TextBlock x:Name="textBlock2" HorizontalAlignment="Left" Margin="10,13,0,0" TextWrapping="Wrap" Text="Zähler" VerticalAlignment="Top"/>
                <TextBox x:Name="textBoxDenominatorRight" HorizontalAlignment="Left" Height="23" Margin="54,38,0,0" TextWrapping="Wrap" Text="1" VerticalAlignment="Top" Width="50" TextAlignment="Center"/>
                <TextBlock x:Name="textBlock3" HorizontalAlignment="Left" Margin="10,41,0,0" TextWrapping="Wrap" Text="Nenner" VerticalAlignment="Top"/>
            </Grid>
        </Grid>
        <Grid Grid.Row="1">
            <Button x:Name="buttonCalc" Margin="10" Content="=" Click="buttonCalc_Click"/>
        </Grid>
        <Grid Grid.Row="2">
            <Grid HorizontalAlignment="Center" VerticalAlignment="Center" Margin="10">
                <TextBox x:Name="textBoxEnumeratorResult" HorizontalAlignment="Left" Height="23" Margin="54,10,0,0" TextWrapping="Wrap" Text="1" VerticalAlignment="Top" Width="50" TextAlignment="Center"/>
                <TextBlock x:Name="textBlock4" HorizontalAlignment="Left" Margin="10,13,0,0" TextWrapping="Wrap" Text="Zähler" VerticalAlignment="Top"/>
                <TextBox x:Name="textBoxDenominatorResult" HorizontalAlignment="Left" Height="23" Margin="54,38,0,0" TextWrapping="Wrap" Text="1" VerticalAlignment="Top" Width="50" TextAlignment="Center"/>
                <TextBlock x:Name="textBlock5" HorizontalAlignment="Left" Margin="10,41,0,0" TextWrapping="Wrap" Text="Nenner" VerticalAlignment="Top"/>
            </Grid>
        </Grid>
    </Grid>
</Window>


Fraction.cs
Quellcode ausblenden C#-Code
using System;
using System.Collections.Generic;
using System.Linq;

namespace WpfBruchrechner
{
    public class Fraction
    {
        private int enumerator;
        public int Enumerator { get { return enumerator; } set { enumerator = value; } }//Zähler
        private int denominator;
        public int Denominator { get { return denominator; } set { denominator = value; } }//Nenner

        public Fraction(int enumerator, int denominator)
        {
            this.enumerator = enumerator;
            this.denominator = denominator;
        }

        public override string ToString()
        {
            return $"{Enumerator}/{Denominator}";
        }

        public void Short()
        {
            ShortFraction(ref enumerator, ref denominator);
        }

        public void Expand(int v)
        {
            if (v != 0)
            {
                enumerator *= v;
                denominator *= v;
            }
        }

        public Fraction Inverse()
        {
            return new Fraction(denominator, enumerator);
        }

        //Operatoren
        public static Fraction operator +(Fraction left, Fraction right)
        {
            int kgv = GetLowestCommenMultiple(left.Denominator, right.Denominator);
            Fraction l = left;
            Fraction r = right;

            l.Expand(kgv / l.Denominator);
            r.Expand(kgv / r.Denominator);

            Fraction ret = l;
            ret.Enumerator += r.Enumerator;
            ret.Short();

            return ret;
        }

        public static Fraction operator -(Fraction left, Fraction right)
        {
            int kgv = GetLowestCommenMultiple(left.Denominator, right.Denominator);
            Fraction l = new Fraction(left.Enumerator, left.Denominator);
            Fraction r = new Fraction(right.Enumerator, right.Denominator);

            l.Expand(kgv / l.Denominator);
            r.Expand(kgv / r.Denominator);

            Fraction ret = l;
            ret.Enumerator -= r.Enumerator;
            ret.Short();

            return ret;
        }

        public static Fraction operator *(Fraction left, Fraction right)
        {
            Fraction ret = new Fraction(left.Enumerator * right.Enumerator, left.Denominator * right.Denominator);
            ret.Short();
            return ret;
        }

        public static Fraction operator /(Fraction left, Fraction right)
        {
            Fraction ret = new Fraction(left.Enumerator * right.Denominator, left.Denominator * right.Enumerator);
            ret.Short();
            return ret;
        }

        //KGV
        private static Dictionary<int, int> PrimeFactorization(int a)
        {
            Dictionary<int, int> primes = new Dictionary<int, int>();
            for (int b = 2; a > 1; b++)
            {
                if (a % b == 0)
                {
                    int x = 0;
                    while (a % b == 0)
                    {
                        a /= b;
                        x++;
                    }
                    primes.Add(b, x);
                }
            }
            return primes;
        }

        private static int GetLowestCommenMultiple(params int[] source)
        {
            var distinct = source.Distinct();
            var divs = from i in distinct select PrimeFactorization(i);

            Dictionary<int, int> result = new Dictionary<int, int>();
            foreach (var dic in divs)
            {
                foreach (var item in dic)
                {
                    if (result.ContainsKey(item.Key))
                    {
                        if (result[item.Key] < item.Value)
                        {
                            result[item.Key] = item.Value;
                        }
                    }
                    else
                    {
                        result.Add(item.Key, item.Value);
                    }
                }
            }

            int mul = 1;
            foreach (var item in result)
            {
                mul *= (int)Math.Pow(item.Key, item.Value);
            }
            return mul;
        }

        //Kettenbruch
        private static void ShortFraction(ref int enumerator, ref int denominator)
        {
            int[] fraction = GetContinuedFraction(enumerator, denominator);
            TransformContinuedFraction(fraction, out enumerator, out denominator);
        }

        private static void TransformContinuedFraction(int[] fraction, out int enumerator, out int denominator)
        {
            if (fraction.Length == 1)
            {
                enumerator = fraction[0];
                denominator = 1;
            }
            else if (fraction.Length >= 2)
            {
                int zl = 1;
                int nl = fraction[fraction.Length - 1];

                int zt = zl;
                int nt = nl;

                for (int i = fraction.Length - 2; i >= 1; i--)
                {
                    zt += (nt * fraction[i]);
                    int t1 = zt;
                    int t2 = nt;

                    zt = t2;
                    nt = t1;
                }

                enumerator = zt + (fraction[0] * nt);
                denominator = nt;
            }
            else
            {
                throw new ArgumentException();
            }
        }

        private static int[] GetContinuedFraction(int z, int n)
        {
            int zt = z;
            int nt = n;

            int za = (z % n);

            int a = (z - (za)) / n;
            if (za == 0)
            { return new int[1] { a }; }
            int b = n / za;
            List<int> result = new List<int>() { a, b };
            int c = n % za;
            while (c != 0)
            {
                int t = za % c;
                result.Add(za / c);
                za = c;
                c = t;
            }

            return result.ToArray();
        }
    }
}
1800394

Du scheinst einen AdBlocker zu nutzen. Ich würde mich freuen, wenn du ihn auf dieser Seite deaktivierst und dich davon überzeugst, dass die Werbung hier nicht störend ist.