1

変数を使用して方程式を取得し、その変数の値を計算して出力する方法を知る必要があります。式の例。

2900 = 1 * T * ((52 + 6) / 12)

すべての値を取得して「T」の値を取得するプログラムが必要です。ありとあらゆる助けをいただければ幸いです:)

4

3 に答える 3

3

方程式が同じである場合、パラメータのみが変更され、変数に再配置されます。

方程式全体がユーザー入力である場合、それは醜く速くなり( "2 * cos(log(x ^ 3))= --e ^ tg(x)")、特効薬はありません。あなたができる最も簡単なことは、実行時にそれを評価し(例えば、NCalcを使用して)、ソリューションを「ブルートフォース」することです。

于 2012-11-25T05:18:16.893 に答える
1

まず、方程式をT=...の形式に再配置します。

2900 = 1 * T * ((52 + 6) / 12)

になります(たとえば)

T = 2900/(52 + 6) * 12 / 1

次に、数値を変数に置き換えます

T = a/(b + c) * d / e

次に、aeが与えられたときにTを計算する関数を記述します

double T(double a, double b, double b, double c, double d, double e) {
 return  a/(b + c) * d / e;
}

その後、このように使用します

double T = T(2900, 52, 6, 12, 1)
于 2012-11-25T04:26:01.197 に答える
0

CSharpCodeProviderこれは、方程式をコードとしてコンパイルし、単純なバイナリ検索を使用して T 値を検索するために使用する汚いソリューションです。

using Microsoft.CSharp;
using System;
using System.CodeDom.Compiler;
using System.Linq;
using System.Reflection;

namespace EquationSolver
{
    public class EquationSolver
    {
        MethodInfo meth;
        double ExpectedResult;
        public EquationSolver(string equation)
        {
        var codeProvider = new CSharpCodeProvider();            
        var splitted = equation.Split(new[] {'='});

        ExpectedResult = double.Parse(splitted[0]);

        var SourceString = "using System; namespace EquationSolver { public static class Eq { public static double Solve(double T) { return "+
            splitted[1] + ";}}}";

        System.CodeDom.Compiler.CompilerParameters parameters = new CompilerParameters();
        parameters.GenerateInMemory = true;


        CompilerResults results = codeProvider.CompileAssemblyFromSource(parameters, SourceString);

        var cls = results.CompiledAssembly.GetType("EquationSolver.Eq");
        meth = cls.GetMethod("Solve", BindingFlags.Static | BindingFlags.Public);

    }

    public double Evaluate(double T)
    {            
        return (double)meth.Invoke(null, new[] { (object)T });
    }

    public double SearchT(double start, double end, double tolerance)
    {            
        do
        {
            var results = Enumerable.Range(0, 4).Select(x => start + (end - start) / 3 * x).Select(x => new Tuple<double, double>(
                x, Evaluate(x))).ToArray();
            foreach (var result in results)
            {
                if (Math.Abs(result.Item2 - ExpectedResult) <= tolerance)
                {
                    return result.Item1;
                }
            }
            if (Math.Abs(results[2].Item2 - ExpectedResult) > Math.Abs(results[1].Item2 - ExpectedResult))
            {
                end -= (end - start) / 3;                    
            }
            else
            {
                start += (end - start) / 3;
            }
        } while (true);
    }
  }


}

現状では、厳しい制限があります:

  1. 予想される結果 (この例では 2900) を最初に記載する必要があります。
  2. 解く方程式は、T という名前の変数を 1 つだけ使用して、等号の後に記述する必要があります。T 自体は、方程式の複数の場所に存在する可能性があります。
  3. コードがコンパイルされているため、.NET の数学関数を使用できますが、SQL インジェクションよりもはるかに悪い方法で入力が悪用される可能性があることも意味します。
  4. 二分探索です。したがって、方程式が単純な線形でない場合、失敗します。
  5. 整数演算の結果は常に整数になり、小数点のない単純な数値は C# によって整数として解析されるため、倍精度の結果が必要な場合は、数値をそのように明示的に設定する必要があります (式では、52、6、または 12 の少なくとも 1 つを52.0 のように小数点で書きます)

使用例:

var eq = new EquationSolver( "2900 = 1 * T * ((52 + 6.0) / 12)");
var r = eq.SearchT(int.MinValue,int.MaxValue,0.001);
于 2012-11-25T06:33:59.350 に答える