C++ 从字符串解方程,得到C

C++ 从字符串解方程,得到C,c++,c,string,linear-algebra,solver,C++,C,String,Linear Algebra,Solver,我想知道是否有人有信息或经验,如何做一些听起来简单,但在试图编程时看起来不像的事情。 其思想是:给出一个包含等式的字符串,例如:“2*x=10”(这很简单,但可能会变得非常复杂,例如sqrt(54)*35=x^2;等等),程序将返回x=5,并可能给出他如何到达那里的日志 这可行吗?如果有,有人有线索吗?关于信息,有一个网站()在PHP中做同样的事情,但不是开源的 谢谢你的帮助 如果方程变得复杂,肯定不会只有几行C/C++代码 对于线性方程组,您必须模拟线性代数书籍中描述的方法之一。它的代码足够小

我想知道是否有人有信息或经验,如何做一些听起来简单,但在试图编程时看起来不像的事情。 其思想是:给出一个包含等式的字符串,例如:“2*x=10”(这很简单,但可能会变得非常复杂,例如sqrt(54)*35=x^2;等等),程序将返回x=5,并可能给出他如何到达那里的日志

这可行吗?如果有,有人有线索吗?关于信息,有一个网站()在PHP中做同样的事情,但不是开源的


谢谢你的帮助

如果方程变得复杂,肯定不会只有几行C/C++代码


对于线性方程组,您必须模拟线性代数书籍中描述的方法之一。它的代码足够小。

一个更正:这不是线性代数,它通常意味着多个方程和未知数的矩阵

你的例子当然并不复杂

您需要的是一个简单的表达式语法和解析器。将方程解析为抽象语法树,并遍历该树进行计算

如果您正在编写Java,它可能看起来像。另一个例子是。也许这将是足够的灵感为你想出你自己的C++。 你可能还想看看Mathematica和Wolfram的阿尔法。斯蒂芬·沃尔夫拉姆是世界上最好的数学家和计算机科学家之一。他有很多东西,你可以重复使用,而不是自己写

您必须定义“解决”是什么意思,以及您希望返回的内容

有符号解和数值解。你指的是哪一个?两者都同样有效,但它们是不同的。您将根据您的答案应用不同的技巧

另一点:有许多“求解”方程的技术,它们在很大程度上取决于方程的类型。如果你给我类似于
f(x)=0的东西,我会想到牛顿法之类的寻根算法。如果你给我一个常微分方程,我可能会尝试用龙格-库塔法进行替换或数值积分。如果你给我一个偏微分方程,我可以应用有限差分、有限元或边界元技术。(不要让我从椭圆、抛物线和双曲型偏微分方程开始。)


关键是你的问题非常笼统,答案在很大程度上取决于你想做什么。更多细节可能会有所帮助。

首先,您必须正确定义可以作为输入的方程类型。然后,您应该创建一个好的抽象来表示方程,例如多项式类。当您想要使用更复杂的表达式时,可以选择数值表达式的树。如果您有很好的规则将表达式转换为前缀表示法,那么解析可能非常容易,使用堆栈进行计算也很容易。一旦你有了艺术树或多项式,你就可以实现转换来计算变量。

这就是所谓的“解析”,尽管计算机科学已经解决了这个问题,但在你彻底理解它之前,它一点也不简单。有一门完整的计算机科学学科描述了如何解决这个问题。在C语言中,必须定义输入的语法(可能包含优先规则),然后对输入执行词法分析,然后解析结果,最后评估解析树

然而,在Ruby之类的语言中,由于您对字符串操作有如此彻底的支持,并且由于您有如此巨大的运行时能力,您可以用一行代码解决问题,如下所示:

puts(eval($_)) while gets

是的,这将涵盖比您要求的更多的内容。

您可以尝试在SymPy中链接到您的C(或C++)代码,并使用它来求解您的方程


IIRC,SymPy有这种功能。另外,在Python内部将输入字符串操作为可用的表达式,然后将其传递给Symphy进行求解应该更容易。

问题有两个部分:解析表达式,并以符号方式求解它们。我不打算对第一个问题说太多,因为其他答案已经很好地涵盖了这个主题;我个人的建议是为前缀表示法中的表达式编写一个简单的递归下降解析器

第二部分,解析解方程,将是棘手的。一般来说,有一些特殊类型的方程,存在标准方法来寻找解析解:

  • 线性方程组:任何直接线性解算器。如果你想显式地展示这些步骤,并且方程/未知数的数量很少,我推荐一些简单的方法,比如无激励高斯消去法或克拉默规则

  • 多项式方程组:变量代换后,等价于求单个多项式的根。如果它们通常具有度,则必须将表达式解析为一些内部表示。许多线性代数书籍建议使用矩阵(或
    std::vector
    )来表示系数。该项的指数由其在向量中的位置定义

    例如,表达式:

     2 + 3x + 5x^2
    
    可以表示为数组或
    std::vector

    std::vector<int> expression;
    expression[0] = 2; // 2 * x ^ 0
    expression[1] = 3;
    expression[2] = 5;
    
    std::向量表达式;
    表达式[0]=2;//2*x^0
    表达式[1]=3;
    表达式[2]=5;
    
    编写求值函数变得微不足道,留给读者作为练习

    求解多个方程变得更加复杂。已有用于此的库和算法。谷歌搜索应该能找到一些好东西。:-)

    我建议从简单的术语开始,并为此构建一个解析器。一旦成功,您就可以将解析器更改为也接受函数名

    若您试图简化在
    =
    两侧都有术语的表达式,只需编写