2

与えられた 3 つの値から他のすべての欠落情報を計算できる三角計算機をプログラミングする必要があります。私は値を計算する方法を知っています - それは問題ではありません。しかし、どうすればそれを良い方法でプログラミングできるかわかりません。

インターフェイスは次のようになります。

ここに画像の説明を入力

この 12 個の入力フィールドには、多くの可能な組み合わせがあります。私の最初のアイデアは、すべての組み合わせに if/else ステートメントを使用することでした。しかし、それはあまり効率的ではありません。もっと良い解決策があると確信していますが、その方法がわかりません。誰でも私を助けることができますか?

編集私のコードは現時点でそう見える:

protected void FlaecheBerechnen_Click(object sender, EventArgs e)
    {     
        WerteAuslesen();
        Berechnen();
    }

    protected void WerteAuslesen()
    {
        //Sides
        string strSeite_a = this.txt_a.Text; if (strSeite_a == string.Empty) { i++; } else { if ((double.TryParse(strSeite_a, out seite_a) == false)) { GenerateErrorReport("Seite a"); } }
        string strSeite_b = this.txt_b.Text; if (strSeite_b == string.Empty) { i++; } else { if ((double.TryParse(strSeite_b, out seite_b) == false)) { GenerateErrorReport("Seite b"); } }
        string strSeite_c = this.txt_c.Text; if (strSeite_c == string.Empty) { i++; } else { if ((double.TryParse(strSeite_c, out seite_c) == false)) { GenerateErrorReport("Seite c"); } }

        //Angles
        string strWinkel_a = this.txtAlpha.Text; if (strWinkel_a == string.Empty) { i++; } else { if ((double.TryParse(strWinkel_a, out winkel_a) == false)) { GenerateErrorReport("Winkel Alpha"); } }
        string strWinkel_b = this.txtBeta.Text; if (strWinkel_b == string.Empty) { i++; } else { if ((double.TryParse(strWinkel_b, out winkel_b) == false)) { GenerateErrorReport("Winkel Beta"); } }
        string strWinkel_y = this.txtGamma.Text; if (strWinkel_y == string.Empty) { i++; } else { if ((double.TryParse(strWinkel_y, out winkel_y) == false)) { GenerateErrorReport("Winkel Gamma"); } }

        //Height
        string strHoehe_a = this.txt_ha.Text; if (strHoehe_a == string.Empty) { i++; } else { if ((double.TryParse(strHoehe_a, out hoehe_a) == false)) { GenerateErrorReport("Höhe a"); } }
        string strHoehe_b = this.txt_hb.Text; if (strHoehe_b == string.Empty) { i++; } else { if ((double.TryParse(strHoehe_b, out hoehe_b) == false)) { GenerateErrorReport("Höhe b"); } }
        string strHoehe_c = this.txt_hc.Text; if (strHoehe_c == string.Empty) { i++; } else { if ((double.TryParse(strHoehe_c, out hoehe_c) == false)) { GenerateErrorReport("Höhe c"); } }

        //ErrorReport:
        if (ErrorMessage != null)
        {
            Page.ClientScript.RegisterStartupScript(this.GetType(), "ErrorAlert", "alert('Folgende Angaben sind fehlerhaft: " + ErrorMessage + "');", true);
            return;
        }

        //Logic
        //If more than 3 values....

        string AlertText;

        if (i < 6)
        {
            AlertText = "Es dürfen nur 3 Angaben gemacht werden!";
            Page.ClientScript.RegisterStartupScript(this.GetType(), "ErrorAlert", "alert('" + AlertText + "');", true);
            return;
        }
        if (i > 6)
        {
            AlertText = "Es müssen mindestens 3 Angaben gemacht werden!";
            Page.ClientScript.RegisterStartupScript(this.GetType(), "ErrorAlert", "alert('" + AlertText + "');", true);
            return;
        }
    }

    protected void Berechnen()
    {
        //Höhensatz

        if (seite_a != 0 && seite_b != 0 && seite_c != 0)
        {
            //Calculate missing angles

                //Winkel Gamma
                cos_y = (seite_a * seite_a) + (seite_b * seite_b) - (seite_c * seite_c); //Zähler berechnen
                cos_y = cos_y / (2 * seite_a * seite_b); //Durch Nenner teilen
                winkel_y = Math.Acos(cos_y); //Bogenradius berechnen
                winkel_y = winkel_y * 180 / Math.PI; //In Winkel umrechnen

                //Winkel Beta
                cos_b = (seite_c * seite_c) + (seite_a * seite_a) - (seite_b * seite_b); //Zähler berechnen
                cos_b = cos_b / (2 * seite_c * seite_a); //Durch Nenn teilen
                winkel_b = Math.Acos(cos_b); //Bogenradius berechnen
                winkel_b = winkel_b * 180 / Math.PI; //In Winkel umrechnen

                //Winkel Alpha
                double winkel_a = 180 - winkel_b - winkel_y;

                //Werte eintragen
                txtAlpha.Text = Convert.ToString(winkel_a);
                txtBeta.Text = Convert.ToString(winkel_b);
                txtGamma.Text = Convert.ToString(winkel_y);

            //Flächen berechnen

                //Mit Satz des Heron
                Heron heron = new Heron(seite_a, seite_b, seite_c);
                double FlaecheHeron = heron.Area;
                Page.ClientScript.RegisterStartupScript(this.GetType(), "ErrorAlert", "alert('" + FlaecheHeron + "');", true);     
        }
    }

問題は、可能な組み合わせが非常に多いことです。if (seite_a != 0 && seite_b != 0 && seite_c != 0), etc, etc....

4

1 に答える 1

2

計算を実行するために使用できる可能性のあるすべてのルールを書き留めることができます。角度の合計、正弦の法則、余弦定理などを使用すると思います。これらの各ルールをクラスとして記述し、これらのそれぞれについて可能なラベル付けごとにインスタンスを作成します(つまり、余弦定理を使用してγまたはβを計算しているかどうか)。最終的にオブジェクトのリストが作成され、すべてが共通のインターフェイスを共有します。このインターフェイスを使用して、他の値からいくつかの値を計算できます。次に、このリストを繰り返し処理して、適用されるルールを確認し、それらを使用して追加の値を計算できます。欠落している値の数がゼロに達すると、完了です。

適用するルールを見つけずにすべてのルールを反復処理すると、可能なルールのセットは十分に完成しません。12の入力のうち3つを入力するために、220の可能なすべての方法を試す単体テストを作成して、それらすべてを処理するのに十分なルールのセットがあることを確認することは非常に良い考えだと思います。12個の値の完全なセットから始めて、3つの要素のサブセットをすべて計算し、それらをアプリケーションコードにフィードして、数値エラーを考慮に入れて、結果を期待値と比較するだけです。

上記のアプローチは、パフォーマンスや数値安定性のために最適化されていません。これらのいずれかが問題になる場合は、別のアプローチの方が適している可能性があります。

于 2012-10-15T05:53:12.477 に答える