求解表示为字符串的线性方程

时间:2014-01-10 07:15:44

标签: algorithm expression-trees

我给了一个字符串2*x + 5 - (3*x-2)=x + 5,我需要为x求解。我的思维过程是我将它转换为表达式树,比如,

          =
        /  \
       -    +
      /\    /\
     +  -   x  5
    /\  /\ 
   *  5 * 2
  /\   /\
 2  x  3 x

但是如何从这里实际减少树?还有其他想法吗?

3 个答案:

答案 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上进行二元搜索,并使用表达式树计算方程的左侧和右侧。