【问题标题】:Expression Tree from Infix Expression in C++ Structural ProgrammingC++ 结构编程中中缀表达式的表达式树
【发布时间】:2019-12-18 20:15:16
【问题描述】:
struct node
{
 char data;
 node *left, *right;
};

constructTree(string expression)
{
 for(i = 0; i < expression.length(); i++)
 {
  if(!(isOperator(expression[i]))
  {
   temp = createNode(expression[i]);
   push(temp);
  }
  else
  {
   temp = createNode(expression[i]);
   node *temp1, *temp2;
   temp1 = pop();
   temp2 = pop();
   temp->left = temp1;
   temp->right = temp2;
  }
 }
}

int main()
{
 string expression = "(a+b)-c*(d/e)";
 constructTree(expression);
}

我想从中缀表达式构造表达式树,我将把它作为来自用户的字符串。我尝试了很多,现在我感到厌倦了。请一些人帮助我从中缀表达式制作这个表达式树!

【问题讨论】:

标签: c++ data-structures expression-trees


【解决方案1】:

您正在尝试编写解析器。

有很多方法可以做到这一点,其中一些方法特别针对中缀表达式进行了优化,而另一些则更通用。

我个人建议阅读 Recursive Descent 解析器,因为它们相对简单直观,是了解解析器的良好起点。

一个处理加、减、乘、除和括号表达式的简单递归下降解析器看起来像这样(这是伪代码!):

node* readExpr() {
    return readAddOrSub();
}

node* readAddOrSub() {
    leftTree = readMulOrDiv();
    token = peekNextToken();  // look at the next token without consuming it 
    if (token == '+' || token == '-') {
         readNextToken();  // skip operator
         rightTree = readAddOrSub();
         return an addition or subtraction node with leftTree and rightTree as its left and right sub-trees respectively;
    } else {
         return leftTree;
    }
}

node* readMulOrDiv() {
    leftTree = readAtom();
    token = peekNextToken();
    if (token == '*' || token == '/') {
         readNextToken();  // skip operator
         rightTree = readMulOrDiv();
         return a multiplication node with leftTree and rightTree as its left and right sub-trees respectively;
    } else {
         return leftTree;
    }
}

node* readAtom() {
    token = readNextToken()
    if (token == '(') {
         result = readExpr();
         read another token and make sure it's ')';
         return result;
    } else if (token is a number)
         return node holding a number;
    else if (token is a variable)
         return node holding a variable;
    else
         error();
}

这假设你有一些东西可以将你的字符串分解成标记(例如,“5*(a+12)”应该被分解成 7 个标记:数字 5、'*'、'('、变量 'a ', '+', 数字 12, ')')。

运算符优先级是通过解析某个优先级的运算符的函数调用以分层方式处理下一个优先级的函数的方式来捕获的。更具体地说,尝试解析加法/减法节点的函数 (readAddOrSub) 调用解析下一级优先级的函数 (readMulOrDiv) 以获取其左右子树。

请注意,readAddOrSub(和 readMulOrDiv)会调用自身来读取右减法,以便可以将多个加法链接在一起(“1+2+3”),但请注意,这会使解析器固有地右关联(“1+2+3”将被解析为“1+(2+3)”)。

当然,让它成为左联想并不难,但我会把它留给你作为练习!

一些可能有帮助的资源:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-07
    • 1970-01-01
    • 1970-01-01
    • 2017-02-10
    • 1970-01-01
    相关资源
    最近更新 更多