我想知道是否有人有关于如何做一些听起来很简单但在尝试编程时看起来不像的信息或经验。 这个想法是:给出一个包含等式的字符串,例如:“2 * x = 10”(这很简单,但它可能变得非常复杂,例如sqrt(54)* 35 = x ^ 2;所以在....)程序会返回x = 5,并可能记录他是如何到达那里的。
这可行吗?如果是这样,有没有人有领先优势?有关信息,这个网站(http://www.numberempire.com/equationsolver.php)在PHP中做同样的事情,但不是开源的。
感谢您的帮助!
答案 0 :(得分:3)
这被称为“解析”,虽然计算机科学已经解决了这个问题,但在你彻底理解之前它并不简单。有一整个计算机科学学科描述了如何解决这个问题。在C中你必须定义输入的语法(可能在其中有优先规则),然后在输入上执行词法分析,然后解析结果,最后评估你的解析树。
但是在Ruby这样的语言中,因为你对字符串操作有如此全面的支持,并且因为你有如此巨大的运行时功能,你可以用一行代码来解决你的问题,如下所示:
puts(eval($_)) while gets
是的,这比你要求的要多。
答案 1 :(得分:2)
首先,您必须正确定义可以作为输入的方程式。然后你应该创建一个很好的抽象来表示方程式,例如多项式类。如果要使用更复杂的表达式,请使用树来表示数值表达式。如果您有良好的规则将表达式转换为前缀表示法,那么解析可能非常简单,然后使用堆栈轻松进行评估。一旦有了算术树或多项式,就可以实现转换来计算变量。
答案 2 :(得分:1)
如果方程确实变得复杂,那么C / C ++代码肯定不会很少。
对于线性方程,您必须模拟线性代数书中描述的方法之一。这段代码足够小。
答案 3 :(得分:1)
一个修正:这不是线性代数,通常意味着多个方程和未知数的基质。
你的例子当然不复杂。
您需要的是一个简单的表达式语法和解析器。将方程解析为抽象语法树并遍历树以对其进行评估。
如果您正在编写Java,它可能看起来像this。另一个例子是symja。也许你有足够的灵感来为C ++提出自己的想法。
您可能还想查看Mathematica和Wolfram的Alpha。斯蒂芬沃尔夫勒姆是世界上最好的数学家和计算机科学家之一。他有很多你可以重用的东西,而不是自己写的。
您必须通过“解决”以及您希望返回的内容来定义您的意思。
有符号解决方案和数值解决方案。你的意思是哪一个?两者都同样有效,但它们是不同的。您将根据您的答案应用不同的技巧。
另一点:有许多“求解”方程的技术在很大程度上取决于方程的类型。如果你给我类似f(x) = 0
的东西,我会想到像牛顿方法那样的根查找算法。如果你给我一个普通的微分方程,我可以尝试使用Runge-Kutta的替换方法或数值积分。如果你给我一个偏微分方程,我可以应用有限差分,有限元或边界元素技术。 (不要让我开始研究椭圆形,抛物线和双曲线偏微分方程。)
关键是你的问题非常通用,答案很大程度上取决于你想要做什么。更多细节可能有所帮助。
答案 4 :(得分:1)
您可以尝试将SymPy链接到C(或C ++)代码并使用它来解决方程式。
IIRC,SymPy具有这种功能。另外,应该更容易将输入字符串操作为Python内部的可用方程式,然后将其传递给SymPy进行求解。答案 5 :(得分:1)
你的问题将会有两个部分:解析方程式,并以象征方式解决它们。我不会对第一个问题说太多,因为其他答案已经很好地涵盖了这个主题;我个人的建议是为前缀表示法中的表达式编写一个简单的递归下降解析器。
第二部分,分析解决方程,将是棘手的。一般来说,有一些特殊的方程式,其中存在标准方法来寻找解析解:
答案 6 :(得分:1)
通常,您必须将表达式解析为一些内部表示。许多线性代数书建议使用矩阵(或std::vector
)来表示系数。该项的指数由其在向量中的位置定义。
例如,表达式:
2 + 3x + 5x^2
可以表示为数组或std::vector
:
std::vector<int> expression;
expression[0] = 2; // 2 * x ^ 0
expression[1] = 3;
expression[2] = 5;
编写评估函数变得微不足道,并留给读者练习。
求解多个方程变得更加复杂。现有的库和算法。谷歌搜索应该提供一些好的东西。 : - )
我建议从简单的术语开始并为此构建解析器。一旦有效,您可以将解析器更改为接受函数名称。
如果您正在尝试简化在=
两侧都有术语的表达式,请记下手动求解时通常会采取的步骤。尝试一些不同的方程式来制定一些规则。现在用C ++实现这些规则。