我有一个类似的需求,需要重新排列方程以改变主题。我已经创建了一个带有示例Dart代码的gist,你可以在DartPad上运行它
这里。请注意,Dart是一种类似于Javascript和Java的语言,所以希望你能理解它。
这段代码允许你构建一个由Node组成的表达式树,每个Node都有一个表示运算符或变量的字符串token,并且可能有一个或两个操作数子Node。(如果你需要将文本转换为表达式的代码,构建Node,我可以稍后添加。)
方程的主题或“lhs”不在表达式中,而是在“rhs”中。操作rearrangeNode可以改变方程的主题,提取newSubject并插入oldSubject。
以下是方便起见的代码:
class ExpressionInvalid implements Exception {
final String msg;
ExpressionInvalid(this.msg);
}
class Node {
final String token;
Node? left;
Node? right;
Node(this.token, [this.left, this.right]);
Node? findNode(String subject) {
Node? sNode;
int count = 0;
for (var node in [left, right]) {
if (node != null) {
var nNode = node.findNode(subject);
if (nNode != null) {
count++;
sNode = nNode;
}
}
}
if (token == subject) {
count++;
sNode = this;
}
if (count > 1) throw ExpressionInvalid('More than one node for $subject');
return sNode;
}
Node? rearrangeNode(String newSubject, String oldSubject, Node? child) {
if (token == newSubject) {
if (child != null) return child;
return Node(newSubject);
}
if (left != null) {
if (left!.findNode(newSubject) != null) {
var newToken = token;
if (token == "+") newToken = "-";
if (token == "-" && right != null) newToken = "+";
if (token == "*") newToken = "/";
if (token == "/") newToken = "*";
var other = child ?? Node(oldSubject);
child = Node(newToken, other, right);
return left!.rearrangeNode(newSubject, oldSubject, child);
}
}
if (right != null) {
if (right!.findNode(newSubject) != null) {
var newToken = token;
if (token == "+") newToken = "-";
if (token == "-") newToken = "-";
if (token == "*") newToken = "/";
if (token == "/") newToken = "/";
var other = child ?? Node(oldSubject);
if (token == "+") child = Node(newToken, other, left);
if (token == "-") child = Node(newToken, left, other);
if (token == "*") child = Node(newToken, other, left);
if (token == "/") child = Node(newToken, left, other);
return right!.rearrangeNode(newSubject, oldSubject, child);
}
}
return null;
}
@override
String toString() =>
"($token${left != null ? ' $left' : ''}${right != null ? '$right' : ''})";
}
void main() {
var tree1 = Node("-", Node("-", Node("x"), Node("N")), Node("y"));
var tree2 = Node("+", Node("C"), Node("-", Node("-", Node("N"), Node("g")), Node("h")));
var tree3 = Node("*", Node("j"), Node("+", Node("N"), Node("c")));
var tree4 = Node("*", Node("a"), Node("-", Node("N")));
for (var tree in [tree1, tree2, tree3, tree4]) {
var newTree = tree.rearrangeNode("N", "O", null);
print("O = $tree => N = $newTree");
}
}