栈的应用——中缀转后缀表达式


 1. 当遇到数字时直接输出
 2. 当遇到运算符时,依次输出栈中比当前运算级别更高或相等的运算符,直到遇到栈中的 ‘(’或栈底。然后把当前运算符压入栈
 3. 当遇到 ‘)’ 直接输出栈中的元素,直到遇到 '(' 结束 
 4. 当表达式字符串都遍历完成之后,把栈中元素依次出栈

// An highlighted block
/*
栈在表达式中的应用   中缀转后缀
实现方式,栈+链表
*/
#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
#define MAXSIZE 60
#define datatype char
struct Stack
{
    datatype data[MAXSIZE];
    int top;
    /* data */
};
struct String
{
    datatype data;
    String *next;
    /* data */
};

int CreateStack(Stack &s){
    s.top = -1;
    return 1;
}
int Push(Stack &s,datatype data){
    
    if(s.top == MAXSIZE-1)
        return 0;
    s.data[++s.top] = data;
    return 1;
}

int Pop(Stack &s,datatype &data){
    
    if(s.top == -1)
        return 0;
    data = s.data[s.top--];
    return 1;
}
datatype GetTop(Stack &s){          //获取栈顶元素
    if(s.top!=-1)
        return s.data[s.top];
    return NULL;
}
int GetLength(char data[]){
    return sizeof(data)/sizeof(char);
}
bool FindChar(Stack s){                 //查找栈内是否有'('
    
    while(s.top!=-1){
        if(s.data[s.top--] == '(')
            return true;
    }
    return false;
}
bool GetError(datatype data[],int length){  ///相连的操作符为非法

    if(length<=0)
        printf("Expression is Empty!\n");
    if(length>MAXSIZE)
        printf("Expression's Length is Over Max!\n");
    for(int i =0;i+1<=length;i++){
        if(data[i]=='+'||data[i]=='-'||data[i]=='*'||data[i]=='/'){
            if(data[i] == data[i+1])
                return true;
        }
    }
    return false;
}
String *GetInierElement(Stack &s){        //依次弹出()中的运算符

    String *Inier = NULL;
    String *head = Inier;
    int i = 0;
    while(s.data[s.top]!='('&&s.top!=-1){
        datatype res;
        Pop(s,res);
        String *node = (String*)malloc(sizeof(String));
        node->data = res;
        node->next = NULL;
        if(!Inier)          //如果头为空,赋值
        {
            Inier = node;
            head = Inier;
            continue;
        }
            
        head->next = node;  //不为空时进行插入
        head = node;
    }
    datatype da;
    Pop(s,da);
    return Inier;
}
String *PopAllPriorityLevel(Stack &s,datatype data){  //依次弹出比data高的以及相等优先级的运算符,并且最后把data入栈

    String *Outer = NULL;
    String *head = Outer;
    int j = 0;
    if(data == '+'||data == '-'){
        while(s.top!=-1&&s.data[s.top]!='(')
        {
            datatype res;
            Pop(s,res);

            String *node = (String*)malloc(sizeof(String));
            node->data = res;
            node->next = NULL;
            if(!Outer)          //如果头为空,赋值
            {
                Outer = node;
                head = Outer;
                continue;
            }
                
            head->next = node;  //不为空时进行插入
            head = node;
        }
        Push(s,data);
        return Outer;
    }
    if(data == '/'||data == '*'){
        while(s.top!=-1&&(s.data[s.top]!='-'&&s.data[s.top]!='+')&&s.data[s.top]!='(')
        {
            datatype res;
            Pop(s,res);

            String *node = (String*)malloc(sizeof(String));
            node->data = res;
            node->next = NULL;
            if(!Outer)          //如果头为空,赋值
            {
                Outer = node;
                head = node;
                continue;
            }
                
            head->next = node;  //不为空时进行插入
            head = node;
        }
        Push(s,data);
        return Outer;
    }
    return NULL;
}
String *GetRPN(Stack &s,datatype data[],int length){      //得到后缀表达式

    String *result = NULL;
    String *head = result;
    int j = 0;

    if(GetError(data,length)){      //如果输入非法,则失败
        return NULL;
    }

    for(int i = 0;i<length;i++){
        if(data[i]!='+'
        &&data[i]!='-'
        &&data[i]!='*'
        &&data[i]!='/'
        &&data[i]!='('
        &&data[i]!=')'){

            String *node = (String*)malloc(sizeof(String));
            node->data = data[i];
            node->next = NULL;
            if(!result)          //如果头为空,赋值
            {
                result = node;
                head = node;
                continue;
            }
                
            head->next = node;  //不为空时进行插入
            head = node;
        }else{

            if(data[i]==')'){
                if(!FindChar(s))
                    return NULL;
                String *res = GetInierElement(s);
                if(!res)            //返回为空时,说明进行了入栈操作,此时不需要链接链表
                    continue;
                if(!result){
                    result = res;
                    while(res->next)
                        res = res->next;
                    head = res;
                    continue;
                }
                head->next = res;
                while(res->next)
                    res = res->next;
                head = res;

            }else if(data[i]=='('){
                Push(s,data[i]);  
            }else{
                String *res = PopAllPriorityLevel(s,data[i]);
                if(!res)
                    continue;
                if(!result){
                    result = res;
                    while(res->next)
                        res = res->next;
                    head = res;
                    continue;
                }
                head->next = res;
                while(res->next)
                    res = res->next;
                head = res;
            }
        }
    }
    while(s.top!=-1)
    {
        datatype dl;
        Pop(s,dl);
        String *node = (String*)malloc(sizeof(String));
        node->data = dl;
        node->next = NULL;
        head->next = node;
        head = node;
    }
    return result;
}
void OutPut(datatype data[],int length,String *result){         //输出信息
    if(!result)
    {
        printf("Input Error!\n");
        return;
    }
    printf("Infix Expression: ");
    for (int i = 0; i < length; i++)
    {
        printf("%c",data[i]);
    }
    printf("\n");

    printf("Postfix Expression: ");
    while(result){
        printf("%c",result->data);
        result = result->next;
    }
    printf("\n");
}
int main(){

    Stack s;
    datatype data[] = {"3*(5-2)+7"};
    CreateStack(s);
    int length = 0;
    length = sizeof(data)/sizeof(datatype) - 1;
    String *result = GetRPN(s,data,length);
    OutPut(data,length,result);
    system("pause");
}
/*
测试:  a+b*c+(d*e+f)*g         答案:       abc*+de*f+g*+
        A+B*(C-D)-E/F                       ABCD-*+EF/-
        1+(2+3*4-5)+6                       1234*+5-+6+
        3*(5-2)+7                           352-*7+
        ((3+5*2)+3)/5+6/4*2+3               352*+3+5/64/2*+3+
        (((6+2)+2*4)+2*(1+9)+3/5)+2*5*(1+2) 62+24*+219+*+35/+25*12+*+
*/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值