我給了一個字符串2*x + 5 - (3*x-2)=x + 5
,我需要解決x
。我的思維過程是我將它轉換為表達式樹,類似於
=
/ \
- +
/\ /\
+ - x 5
/\ /\
* 5 * 2
/\ /\
2 x 3 x
但是我如何從這裡實際減少樹?還有其他想法嗎?
你必須使用代數公理來減少它
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時,解決它。
假設等式可以減少到f(x)= 0,並且f(x)= a * x + b。
您可以將表達式樹中的所有葉子轉換為f(x),例如:2 - > 0 * x + 2,3 * * - > 3 * x + 0,然後您可以對f(x)進行算術運算表達樹。最後求解方程f(x)= 0。
如果函數比多項式複雜得多,則可以對x進行二元搜索,並使用表達式樹來計算等式的左側和右側。