简体   繁体   English

使用堆栈和二叉树c构建表达式树

[英]Building an expression tree using a stack and a binary tree c

I am given an arithmetic formula containing operators +, -, *, / and parentheses (which might or might not change the natural precedence of operators). 我给了一个算术公式,其中包含运算符+,-,*,/和括号(这可能会或可能不会更改运算符的自然优先级)。 An example would be the following one: a / b + f – (c + d) * e – a * c. 例如:a / b + f –(c + d)* e – a * c。 and I am asked to use a stack (implemented as a linked list) in order to keep track of the operands and the operators: an example of how my program should work is the following: 并要求我使用一个堆栈(实现为链接列表)以跟踪操作数和运算符:以下是我的程序应如何工作的示例:

  • Read a, push on operand stack 读一个,压入操作数栈
  • Read /, push on operator stack 读/,压入运算符堆栈
  • Read b, push on operand stack 读b,压入操作数堆栈
  • Read +: has lower precedence than / , so: 读+:的优先级低于/,因此:
    • pop 2 operands (a and b) from operand stack 从操作数堆栈中弹出2个操作数(a和b)
    • pop / from operator stack 从操作员弹出/弹出
    • create subtree and push on operand stack 创建子树并压入操作数堆栈
    • operator stack is empty, so push + on it 操作符堆栈为空,因此在其上按+
  • Read f, push on operand stack 读取f,压入操作数堆栈
  • Read - : has same precedence as + , so: 读-:优先级与+相同,因此:
    • pop 2 operands from operand stack 从操作数堆栈中弹出2个操作数
    • pop operator + from operator stack 弹出运算符+来自运算符堆栈
    • create a tree with operator + as the root and the two operands as left and right children 创建一个以运算符+为根,两个操作数为左,右子代的树
    • push the root of the created tree back on the operand stack 将创建的树的根推回操作数堆栈
    • operator stack is empty, so push - on it 操作员堆栈为空,因此在其上推入

The problem that I have difficulty understanding is how can I distinguish the precedence of the operands ! 我难以理解的问题是如何区分操作数优先级

Here is an incomplete version of the code that I wrote: 这是我编写的代码的不完整版本:

#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>

typedef struct btnode Btree;
typedef struct node s_Node;

struct btnode {
    char info; 
    Btree *left; 
    Btree *right;
};


struct node {
    char element;
    s_Node*next;
}; 

typedef struct{
    s_Node *top_stack;
} stack_t; 

int IsOperator(char c);

main () {
    FILE* fp;
    stack_t operands;
    stack_t operators;
    char c;
    operands=NewStack();
    operators=NewStack();
    fp= fopen ("Myfile.txt", "r");
    if (fp== NULL)
        printf ("   FILE COULD NOT BE OPENED");
    else
    {
        c=getc(fp);
        while (!feof (fp))
        {
            if ( c== ' ');
            else 
            {
                printf ("Here is your character: %c\n", c);
                if (IsOperator (c))
                    Push (c, &operands);
                else if ( isalpha (c))


            }
        c=getc(fp);
        }
    }
}

int IsOperator(char c)
{   
    switch(c)
    {
        case '+':
        case '-':
        case '/':
        case '*':
        return 1;
        default:
        return 0;
    }
} 

stack_t NewStack()
{
    stack_t *n_stack;
    n_stack=(stack_t*)malloc(sizeof(stack_t));
    n_stack->top_stack=NULL;
    return (*n_stack);  
}

int Push(char e, stack_t *q)
{       
    s_Node *nn;
    nn= (s_Node*)malloc(sizeof(s_Node));

    if(Full(*q))
    {
        printf("\n\t Stack is Full !! \n\n");
        return 0;   // return 0 if enstack NOT successful
    }
    else 
    { 
        nn->element=e; // Storing the elemnt read inside the the new node
        nn->next=q->top_stack; // Pointing the new node to the top of the stack
        q->top_stack=nn; // Changing the top of the stack
        return 1;
    }
}

Thank you in advance! 先感谢您!

for algorithm you are using, operands has no precedence. 对于您使用的算法,操作数没有优先级。 But in bottom-up shift-reduce parser, it does have precedence as @WhozCraig said at comment of this post below. 但是在自底向上的移位减少解析器中,它确实具有优先级,正如@WhozCraig在下面的这篇文章的评论中所说。

The operands always be pushed into operand stack and will be popped out 2 and calculated with an operator then pushed again to operand stack as a single operand. 操作数总是被压入操作数堆栈中,并会弹出2并由一个运算符进行计算,然后再次作为单个操作数被压入操作数堆栈。

For your formula: a / b + f – (c + d) * e – a * c 对于您的公式:a / b + f –(c + d)* e – a * c

  • a 一种
  • push to operand stack push送到操作数堆栈
  • operand : a 操作数
  • operator : 操作员

  • / /

  • push to operator stack push送到操作员堆栈
  • operand : a 操作数
  • operator : / 运算子 :/

  • b b

  • push to operand stack push送到操作数堆栈
  • operand : ab 操作数 :ab
  • operator : / 运算子 :/

  • + +

  • + <= / -> pop /, a & b -> a / b -> push to operand stack + <= / -> pop /,a b-> a / b->推送到操作数堆栈
  • push + to operator stack +到运算符堆栈
  • operand : (a / b) 操作数 :(a / b)
  • operator : + 运算子 :+

  • f F

  • push to operand stack 推送到操作数堆栈
  • operand : (a/b) f 操作数 :(a / b)f
  • operator : + 运算子 :+

  • - -

  • - <= + -> pop +, (a/b) & f -> (a/b) + f -> push to operand stack - <= + -> pop +,(a / b) f->(a / b) + f->压入操作数堆栈
  • operand : ((a/b)+f) 操作数 :((a / b)+ f)
  • operator : - 操作员 :-

  • (

  • push to operator stack 推送到操作员堆栈
  • operand : ((a/b)+f) 操作数 :((a / b)+ f)
  • operator : - ( 运算子:-(

  • c C

  • push to operand stack 推送到操作数堆栈
  • operand : ((a/b)+f) c 操作数 :((a / b)+ f)c
  • operator : - ( 运算子:-(

  • + +

  • push to operator stack 推送到操作员堆栈
  • operand : ((a/b)+f) c 操作数 :((a / b)+ f)c
  • operator : - ( + 运算子 :-(+

  • d d

  • push to operand stack 推送到操作数堆栈
  • operand : ((a/b)+f) cd 操作数 :((a / b)+ f)cd
  • operator : - ( + 运算子 :-(+

  • )

  • until '(' popped, pop all operator in stack one by one and calculate with 2 operands 直到'('弹出,一一弹出堆栈中的所有运算符,并使用2个操作数进行计算
  • -> pop +, c & d -> c + d -> push to operand stack -> pop +,c d-> c + d->推送到操作数堆栈
  • operand : ((a/b)+f) (c+d) 操作数 :((a / b)+ f)(c + d)
  • operator : - ( 运算子:-(
  • -> pop (, stop popping operator stack ->弹出(,停止弹出运算符堆栈
  • operand : ((a/b)+f) (c+d) 操作数 :((a / b)+ f)(c + d)
  • operator : - 操作员 :-

  • * *

  • * > - push to operator stack * > -推送到操作员堆栈
  • operand : ((a/b) + f) (c + d) 操作数 :((a / b)+ f)(c + d)
  • operator : - * 运算子 :-*

  • e Ë

  • * > - push to operand stack * > -推送到操作数堆栈
  • operand : ((a/b) + f) (c + d) e 操作数 :((a / b)+ f)(c + d)e
  • operator : - * 运算子 :-*

  • - -

  • - <= * pop *, (c + d) & e -> (c + d) * e -> push to operand stack - <= * pop *,(c + d) e->(c + d)* e->压入操作数堆栈
  • operand : ((a/b)+f) ((c+d)*e) 操作数 :((a / b)+ f)((c + d)* e)
  • operator : - 操作员 :-
  • - <= - pop -, ((a/b)+f) & ((c+d)*e) -> ((a/b)+f) - ((c+d)*e) -> push to operand stack - <= - pop-,(((a / b)+ f) ((c + d)* e)->((a / b)+ f) - ((c + d)* e)->推操作数栈
  • push - to operator stack 推送到操作员堆栈
  • operand : (((a/b)+f)-((c+d)*e)) 操作数 :((((a / b)+ f)-((c + d)* e))
  • operator : - 操作员 :-

  • a 一种

  • push to operand stack 推送到操作数堆栈
  • operand : (((a/b)+f)-((c+d)*e)) a 操作数 :((((a / b)+ f)-((c + d)* e))a
  • operator : - 操作员 :-

  • * *

  • * > - push to operator stack * > -推送到操作员堆栈
  • operand : (((a/b)+f)-((c+d)*e)) a 操作数 :((((a / b)+ f)-((c + d)* e))a
  • operator : - * 运算子 :-*

  • c C

  • push to operand stack 推送到操作数堆栈
  • operand : (((a/b)+f)-((c+d)*e)) ac 操作数 :((((a / b)+ f)-((c + d)* e))ac
  • operator : - * 运算子 :-*

  • end of line 行结束

  • pop all operators in stack one by one 逐一弹出堆栈中的所有运算符
  • pop *, a & c -> (a*c) -> push to operand stack pop *,a&c->(a * c)->推送到操作数堆栈
  • operand : (((a/b)+f)-((c+d)*e)) (a*c) 操作数 :((((a / b)+ f)-((c + d)* e))(a * c)
  • operator : - 操作员 :-
  • pop -, (((a/b)+f)-((c+d)*e)) & (a*c) -> (((a/b)+f)-((c+d)*e)) - (a*c) -> push to operand stack 弹出-,((((a / b)+ f)-((c + d)* e)) (a * c)->((((a / b)+ f)-((c + d)* e)) - (a * c)->推送到操作数堆栈
  • operand : ((((a/b)+f)-((c+d)*e))-(a*c)) 操作数 :(((((a / b)+ f)-((c + d)* e))-(a * c))
  • operator : 操作员

result: ((((a/b)+f)-((c+d)*e))-(a*c)) 结果:(((((a / b)+ f)-((c + d)* e))-(a * c))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM