我给了一个字符串2*x + 5 - (3*x-2)=x + 5
,我需要为x
求解。我的思维过程是我将它转换为表达式树,比如,
=
/ \
- +
/\ /\
+ - x 5
/\ /\
* 5 * 2
/\ /\
2 x 3 x
但是如何从这里实际减少树?还有其他想法吗?
答案 0 :(得分:5)
你必须使用来自代数的公理来减少它
a * (b + c) -> (a * b) + (a * c)
这是通过检查传递树中每个节点的类型来完成的。一旦事物完全扩展为术语,您就可以检查它们实际上是线性的等等。
树中的值可以是变量或数字。将这些表示为继承自某些AbstractTreeNode类的类并不是很整洁,但是因为cplusplus没有多个分派。因此最好以“c”方式进行。
enum NodeType {
Number,
Variable,
Addition //to represent the + and *
}
struct Node {
NodeType type;
//union {char*, int, Node*[2]} //psuedo code, but you need
//something kind of like this for the
//variable name ("x") and numerical value
//and the children
}
现在,您可以使用switch case查询节点及其子节点的类型。
正如我之前所说 - c ++惯用代码将使用虚函数,但缺少必要的多次调度来干净地解决这个问题。 (无论如何你都需要存储类型)
然后你对术语等进行分组并解决方程式。
您可以使用规则来规范化树,例如
constant + variable -> variable + constant
将x始终放在术语的左侧。然后可以更轻松地简化x * 2 + x * 4
var * constant + var * constant -> (sum of constants) * var
在你的例子中......
首先,通过移动术语(按照上述规则)简化'='
右侧将是-1 *(x + 5),变为-1 * x + -1 * 5.左侧将更难 - 考虑用+ -1 * b替换a - b。
最终,
2x + 5 + -3x + 2 + -x + -5 = 0
然后,您可以按照您想要的方式对术语进行分组。 (通过扫描等)
(2 + -3 + -1)x + 5 + 2 + -5 = 0
总结一下,当你有mx + c时,解决它。
答案 1 :(得分:1)
假设您有一阶方程,请检查每一侧的所有叶子。在每一侧,有两个箱子:一个用于添加包含X倍数的所有叶子,另一个用于包含多个常量的叶子。当您从叶子的每个分支上升树时,可以添加到bin或乘以每个bin。你最终会得到一些概念上像
的东西a*x + b = c*x + d
此时,你可以解决
x = (d - b) / (a - c)
答案 2 :(得分:1)
假设等式可以减少到f(x)= 0,并且f(x)= a * x + b。
您可以将表达式树中的所有叶子转换为f(x),例如:2 - > 0 * x + 2,3 * x - > 3 * x + 0,那么你可以在表达式树中进行f(x)的算术运算。最后求解方程f(x)= 0。
如果函数比多项式复杂得多,可以在x上进行二元搜索,并使用表达式树计算方程的左侧和右侧。