C++ 左子表达式树、右同级表达式树
我完全被一项任务困住了,需要一些帮助 我们正在实现一个树类,它存储并计算一个二进制表达式。下面是这样一个表达的例子:(MAJ(和34)(或1234)(不是5)4)。这指的是这棵树: 树是在LCRS表示中提供给我们的,我们正在构建一个类来对它执行各种操作,例如查找树中的最大数、查找特定运算符的数,或者打印生成给定树的原始公式。通过几个小时的挠头和一堆用来跟踪大型递归函数的纸,我已经弄明白了所有这些 但我无法找出最后一个必需的函数,即C++ 左子表达式树、右同级表达式树,c++,algorithm,recursion,tree,C++,Algorithm,Recursion,Tree,我完全被一项任务困住了,需要一些帮助 我们正在实现一个树类,它存储并计算一个二进制表达式。下面是这样一个表达的例子:(MAJ(和34)(或1234)(不是5)4)。这指的是这棵树: 树是在LCRS表示中提供给我们的,我们正在构建一个类来对它执行各种操作,例如查找树中的最大数、查找特定运算符的数,或者打印生成给定树的原始公式。通过几个小时的挠头和一堆用来跟踪大型递归函数的纸,我已经弄明白了所有这些 但我无法找出最后一个必需的函数,即 bool evaluate(const vector<b
bool evaluate(const vector<bool> &values, Tree_Node* p)
我知道我需要深入到4,意识到这是最简单的(基本)情况,然后开始递归到and,但我不知道如何在返回and时获得正确的值。我需要一个额外的参数还是什么?也许传递操作,或者使用某种额外的指针
//一些澄清材料
这四家运营商是:
- MAJ-如果大多数输入为真,则返回真
- AND-逻辑AND(如果两个输入均为真,则为真)
- 或-逻辑或
- 非-否定
struct Tree_Node {
std::string data;
Tree_Node* left_child;
Tree_Node* right_sibling;
}
树类也是标准的,除了用于赋值的附加函数,
如果需要,我可以发布代码,但它具有您期望的树操作,并且可以正确编译和测试,问题只是关于这个函数
我在这和其他作业之间把头撞在桌子上。。。哦,CS专业的生活。一如既往,我们非常感谢您的任何帮助
编辑:
非常感谢所有帮助我的人。我在这里得到的所有答案真的帮助我解决了问题。有时有助于获得新的视角。另外,std::pair对我来说是新的!有趣的是,因为我有一个自己的模板类,做同样的事情。。。我猜是时候让那个家伙退休了
当我完成作业后,我将在这里发布我的函数和分析,以供将来参考
编辑:
正如承诺的那样,完成的功能。count_children在功能上与rici设置的count函数相同,TruthValues是一个std::int对,与Counts类似。再次感谢那些帮助我解决这个问题的人。当给定一个字符串时,函数switch\u help为switch语句返回适当的数字(例如switch\u help(“多数”)==2
)
bool BooleanFormula::evaluate(常量向量和值,树节点*p){
真值真值=真值(0,0);
int control=开关帮助(p->data);
开关(控制){
案例1://p->data=“多数”
真值=计数子项(值,p->左子项);
返回(真值第一>真值第二);
//如果真多于假,则返回真
案例2://p->data=“和”
真值=计数子项(值,p->左子项);
返回值(真值秒=0);
//如果没有错误,则返回true
案例3://p->data=“或”
真值=计数子项(值,p->左子项);
返回(真值第一次>=1);
//如果至少有一个true,则返回true
案例4://p->data=“不”
返回!(计算(值,p->左_子项));
//返回通过计算子树得到的结果的倒数
默认值://p->data=一些数字
//在这种情况下,我们只是在一个包含索引的节点上
返回值[atoi((p->data).c_str())];
}
}
如果我理解结构,在每个子树上,操作符位于根,第一个操作数作为根的左子级,后续操作数作为根的右链接
第一个操作数,对吗
然后,总体评估方案如下所示:
bool evaluate(const vector<bool> &values, Tree_Node* p) {
bool result;
switch (p->op) {
case BASE:
return values[p->index];
...
case AND:
result = true;
for (op = p->left; op != nullptr; op = op->right)
result &= evaluate (values, op);
return result;
...
}
}
bool求值(常量向量和值,树节点*p){
布尔结果;
开关(p->op){
案例库:
返回值[p->index];
...
案例和:
结果=真;
对于(op=p->left;op!=nullptr;op=op->right)
结果&=评估(值,op);
返回结果;
...
}
}
(这里我假设叶子包含
值数组中的索引。表达式树的递归计算涉及:
- 评估树的每个节点
这反过来又要求:
- 将操作应用于子对象(操作数)列表
现在,让我们尝试稍微系统化。考虑一下你的操作-<代码>不< /COD>,<代码>和,<代码>或和<代码> MaG/<代码>,并考虑如何在操作列表中计算每一个的值。具体来说,我们需要知道列表的内容吗?在所有情况下,以下两个数据都足够了。(只有一种情况下,两者都是必要的):
- 列表中有多少值是
TRUE
- 列表的值中有多少是
FALSE
(或者,第二个可能是“列表中有多少个值?”,这显然是等效的。)
如果FALSE
子项的数量为0,和为TRUE
子项的数量为0;或为FALSE
子项的数量为TRUE
子项的数量大于FALSE
子项的数量,MAJ
为TRUE
子项的数量。(对于操作数列表,NOT
至少有两种泛化,或者您可以将其限制为TRUE
子级数为0,而FALSEbool BooleanFormula::evaluate(const vector<bool> & values, Tree_Node* p){
TruthValues truth_vals = TruthValues(0,0);
int control = switch_help(p->data);
switch (control){
case 1: //p->data = "MAJORITY"
truth_vals = count_children(values, p->left_child);
return (truth_vals.first > truth_vals.second);
//return true if there are more trues than falses
case 2: //p->data = "AND"
truth_vals = count_children(values, p->left_child);
return (truth_vals.second == 0);
//return true if there are no falses
case 3: //p->data = "OR"
truth_vals = count_children(values, p->left_child);
return (truth_vals.first >= 1);
//return true if there is at least one true
case 4: //p->data = "NOT"
return !(evaluate(values, p->left_child));
//return the inverse of what is obtained by evaluating the subtree
default: //p->data = some number
//in this case, we're just at a node with an index in it
return values[atoi((p->data).c_str())];
}
}
bool evaluate(const vector<bool> &values, Tree_Node* p) {
bool result;
switch (p->op) {
case BASE:
return values[p->index];
...
case AND:
result = true;
for (op = p->left; op != nullptr; op = op->right)
result &= evaluate (values, op);
return result;
...
}
}
typedef std::pair<int, int> Counts;
Counts count(Tree_Node* node) {
if (!node) return Counts{0, 0};
Counts rest = count(node->right_sibling);
if (evaluate(node))
return Counts{rest.first + 1, rest.second};
else
return Counts{rest.first, rest.second + 1};
}
typedef std::pair<int, int> Counts;
Counts operator+(const Counts& a, const Counts& b) {
return {a.first + b.first, a.second + b.second};
}
Counts count(Tree_Node* node) {
if (!node)
return Counts{0, 0};
else
return evaluate(node) + count(node->right_sibling);
}