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。T 本身可以存在于方程中的多个位置。
  3. 由于代码已编译,您可以使用 .NET 数学函数,但这也意味着输入可能被滥用,比任何 SQL 注入都要糟糕。
  4. 是二分查找。因此,如果您的方程不是简单的线性方程,它将失败。
  5. 由于整数运算总是产生整数,并且没有小数点的普通数字被 C# 解析为整数,如果你想要双精度结果,数字必须明确设置为这样(在你的等式中,至少 52、6 或 12 之一必须是用小数点书写,例如 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 回答