[英]C++ shunting yard algorithm and expression tree implementation
我是C ++的新手,并使用调车场算法构建表达式树。 我被这个问题困扰了几天。 我试图获取根节点的值,但失败。
中缀输入
(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());
您也可以随时跟踪顶部,但是如果这样做,则必须使新的运算符节点位于顶部。 在代码中,将右操作数放在顶部。
请注意,在这种情况下,在处理数字时,还应跟踪顶部,否则当表达式仅包含数字时,顶部节点将为空。 还要注意,如果操作正确,yourtop将始终是推送到堆栈上的最后一个项目-换句话说,堆栈的顶部。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.