第二十四节 表达式计算器(2)




    最近事情比较多,有几天没有更新了,朱兆祺今天抽点时间,无论如何也得更新下。
    承接上一节所讲,这一节我们应该到了中缀表达式转化为后缀表达式。这个数据结构在计算器表达式的项目中是非常经典的。这里我就再啰嗦几句,中缀表达式也叫做中缀记法,如1+2*3便是,因为操作符在中间嘛,所以就叫做中缀表达式。那么什么叫做后缀表达式,举一反三,即为操作数在后面嘛,那么即是:123*+。后缀表达式也叫做逆波兰表达式。
    中缀表达式转化为后缀表达式,栈的用武之地来了,说到栈,第一个词语就是FILO,先进后出。中缀表达式转化为后缀表达式也正是用了这一个特点。


/***************************************************
** 函数名称:*mid_to_bk
** 函数功能:中缀转换成后缀表达式
** 入口参数:node *head
** 出口参数:
***************************************************/
node *mid_to_bk(node *head)
{
        node *mid = Separate_str(head);    /* 处理后的中缀表达式链表*/

        node *bk  = NULL;                  /* 后缀表达式头指针*/
        
        node *ptr = bk; 

        node *oper = NULL;                 /* 符号堆栈 */

        node *newnode  = NULL;

        node *code_node = NULL;           /* 用来记录,保存地址 */
        
        /* 开始转换*/
        for(; mid; mid=mid->next){

                /* 将节点数据拷贝到新节点去*/
                        newnode = new node;
                        init_node(newnode);
                        copy_node_data(newnode,mid); 
                        
                /* 如果遇到数字就直接入栈*/
                if(NUM == newnode->type){ 
                                        
                        /*加入链表*/
                        if(NULL == bk){
                                ptr = bk = add_node(ptr,newnode);
                        } else{
                                ptr = add_node(ptr,newnode);
                        }
                        
                }

                /* 如果遇到特殊表达式*/
                else if(SP_OPERATOR == newnode->type){
                        
                        /* 如果前一个运算符也是特殊运算符就要出栈 */
                        while(oper){
                                
                                if(SP_OPERATOR == oper->type){
                                        
                                        code_node = oper->befor;   /* 将这个节点换到后缀表达式里面*/
                                        ptr  = add_node(ptr,oper);
                                        oper = code_node;
                                
                                } else break;
                                
                        }
                        
                        oper = add_node(oper,newnode);
                        
                }


                /*如果遇到普通运算符*/
                else if(OPERATOR == newnode->type){
                        
                        /*'('直接进栈*/
                        if('(' == newnode->ch){
                                oper = add_node(oper,newnode);
                        }

                        /*')'直接退栈到')'*/
                        else if(')' == newnode->ch){
                                while(oper){
                                        if('(' == oper->ch)break;/* 遇到'('退栈结束*/
                                        code_node = oper->befor;   /* 将这个节点换到后缀表达式里面*/
                                        ptr  = add_node(ptr,oper);
                                        oper = code_node;
                                }
                                
                                oper = del_node(oper);  /* 删除掉'('符号*/
                        }

                        /* 遇到+-全部退栈,直到遇到'(',或者退完为止*/
                        else if(('+' == newnode->ch) || ('-' == newnode->ch)){
                                while(oper){
                                        
                                        if('(' == oper->ch)break;  /* 遇到'('退栈结束*/
                                        code_node = oper->befor;   /* 将这个节点换到后缀表达式里面*/
                                        ptr  = add_node(ptr,oper);
                                        oper = code_node;
                                
                                }                                
                                oper = add_node(oper,newnode);
                        }

                        /* 遇到/* 把特殊运算符全部退栈处理*/
                        else if(('*' == newnode->ch) || ('/' == newnode->ch)){
                                while(oper){
                                        
                                        if('(' == oper->ch)break;  /* 遇到'('和特殊运算符截止*/
                                        if(('+' == oper->ch) || ('-' == oper->ch))break;
                                        code_node = oper->befor;   /* 将这个节点换到后缀表达式里面*/
                                        ptr  = add_node(ptr,oper);
                                        oper = code_node;
                        
                                }
                                oper = add_node(oper,newnode);
                        }
                        
/*
*  下面这段程序是调试使用 
*/
#if 0
    cout<<"mid: ";
    print_link_data(test);
    getchar();
#endif        

                }
        
        }
        
        
        /* 把最后留在堆栈里面的东西退出来*/
        while(oper){
                
                code_node = oper->befor;   /* 将这个节点换到后缀表达式里面*/
                ptr  = add_node(ptr,oper);
                oper = code_node;

        }
        
        
    ptr->next = NULL;

/*
*  下面这段程序是调试使用 
*/
#if 0
     cout<<"mid: ";
     print_link_data(bk);
#endif

        return bk;
}




你可能感兴趣的:(c学习)