C 分流码算法和表达树实现
C++ shunting yard algorithm and expression tree implementation
我是C 的新手,并使用分流码算法来构建表达树。我已经遇到了几天的问题。我正在尝试获取根节点的值,但它失败了。
infix输入
(1+2)*(3/4)-(5+6)
以下代码是基于划痕码的函数:
vector<string> infixToRPN(vector<string> tokens) {
vector<string> output;
stack<string> stack;
string o1;
string o2;
//traverse tokens
for (int i = 0; i < tokens.size(); ++i) {
// if token is operator
if (isOperator(tokens[i])) {
string o1 = tokens[i];
if (!stack.empty()) {
string o2 = stack.top();
while (isOperator(o2) && comparePrecendence(o1, o2) <= 0) {
// pop off o2 and on to the output;
stack.pop();
output.push_back(o2);
if (!stack.empty())
o2 = stack.top();
else
break;
}
}
//push o1 on to the stack;
stack.push(o1);
}
//if token is left bracket
else if (tokens[i] == "(") {
stack.push(tokens[i]);
}
//if token is right bracket
else if (tokens[i] == ")") {
string topToken = stack.top();
while (stack.top() != "(") {
output.push_back(topToken);
stack.pop();
if (stack.empty()) break;
topToken = stack.top();
}
if (!stack.empty()) stack.pop();
}
// if token is number and add it to ouput;
else
{
output.push_back(tokens[i]);
}
}
//pop the rest of token
while (!stack.empty()) {
string restToken = stack.top();
output.push_back(restToken);
stack.pop();
}
return output;
}
测试结果表明解析器似乎有效:
12+34/*56+-
所以我想错误可能发生在我的buildtree函数中。建造后,getRoot((函数返回的值始终与正确的值不一致。就我而言,当我得到" 0"时,根应为" - "。
ExprTree ExprTree::buildTree(vector<string> tokens){
ExprTree t ;
TreeNode * n, * n1, * n2;
TreeNode * r = t.getRoot();
vector<string> postfix = infixToRPN(tokens);
stack<TreeNode *> stack;
for (int i = 0; i < postfix.size(); ++i) {
//if number
if (!isOperator(postfix[i])) {
n = createOperatorNode(postfix[i]);
stack.push(n);
}
else // if operator
{
n= createOperatorNode(postfix[i]);
if (!stack.empty())
t = ExprTree(stack.top());
// pop two tree nodes
n1 = stack.top();
stack.pop();
n2 = stack.top();
stack.pop();
//set children nodes;
n->setLeftChild(n2);
n->setRightChild(n1);
stack.push(n);
}
}
return t;
}
您的算法看起来不错,但是您返回的树存在错误。
从RPN符号中构建节点后,堆栈中应剩下一个节点。返回该节点的节点或该节点的树。
因此,基本上是:
for (int i = 0; i < postfix.size(); ++i) {
// build tree
}
// enforce that there is only one node on the stack
return ExprTree(stack.top());
您也可以随时跟踪顶部,但是如果这样做,则必须使新操作员节点成为顶部。在您的代码中,您将右手操作装置为顶部。
请注意,在这种情况下,您还应该在处理数字时跟踪顶部,否则,当您的表达仅由一个数字组成时,您将具有null Top节点。另请注意,如果正确执行此操作,您的顶部将永远是将其推入堆栈的最后一项;换句话说,堆栈的顶部。
相关文章:
- 如果没有malloc,链表实现将失败
- 如何在c++中实现处理器调度模拟器
- 如何在c++中使用引用实现类似python的行为
- 实现无开销push_back的最佳方法是什么
- 使用简单类型列表实现的指数编译时间.为什么
- 如何在BST的这个简单递归实现中消除警告
- 实现一个在集合上迭代的模板函数
- 我应该实现右值推送功能吗?我应该使用std::move吗
- 如何正确实现和访问运算符的各种自定义枚举器
- C++Union/Struct位域的实现和可移植性
- 这个极客对极客的trie实现是否存在内存泄漏问题
- 在c++中实现LinkedList时,应出现未处理的错误
- 为左值和右值的包装器实现C++范围
- 使用模板进行堆栈实现; "name followed by :: must be a class or namespace"
- 使用GSoap实现ONVIF
- 在用于格式4的arm模拟器中实现功能时的一个问题
- 用于AVX的ln(x)的实现,m256
- 用常见虚拟函数实现的任意组合来实现派生类的正确方法是什么
- 在C++中,如何在类和函数(可能是模板化的)的头中编写完整的实现
- C 分流码算法和表达树实现