利用栈将中缀表达式转换成后缀表达式

步骤:

              1).初始化两个栈:运算符栈s1和存储中间结果的栈s2;

    2).从左到右扫描中缀表达式;

    3).遇到操作数时,将其压入s2;

    4).遇到运算符时,比较其与s1栈顶运算符的优先级;

               1.如果s1为空,或栈顶运算符为左括号"(",则直接将此运算符入栈

               2.否则,若优先级比栈顶运算符的高,也将运算符压入s1

              3.否则,将s1栈顶的运算符弹出并压入s2中,再次转到(4-1)与s1中新的栈顶运算符相比较;

    5)遇到括号时:

      1如果时左括号"(",则直接压入s1

      2如果是右括号")",则依次弹出s1栈顶的运算符,并压入s2,直到遇到左括号为止,此时将这一对括号丢弃

    6)重复2至5,直到表达式的最右边

    7)将s1中剩余的运算符依次弹出并压入s2

    8)依次弹出s2中的元素并输出,结果的逆序为中缀表达式对应的后缀表达式

例如:将1+((2+3)*4)-5转换为后缀表达式"123+4*+5-" 

//将中缀表达式转为后缀表达式
#include <stdio.h>
#include <stdbool.h>
#define MAXSIZE 20

struct Stack
{
    int top;
    char arr[MAXSIZE];
}stack1,stack2,temp;          //stack1为符号栈,stack2为存放结果的栈,temp是临时使用的栈

void Push_stack(struct Stack* stack,char c)          //入栈
{
    if(stack->top < MAXSIZE)
    {
        stack->top++;
        stack->arr[stack->top] = c;
    }
    else
        printf("stack over flow!\n");
}

void Pop_stack(struct Stack* stack)      //出栈
{
    if(stack->top != -1)
    {
        stack->top--;
    }
    else 
        printf("stack under flow!\n");

}

bool Isempty(struct Stack* stack)    //判断栈是否为空
{
    if(stack->top == -1)
        return true;   //空
    else
        return false;  //非空
}

void Reverse_print(struct Stack* stack)        //逆序输出栈,需要使用另外一个临时栈
{
    temp.top = -1;
    while(stack->top != -1)
    { 
        Push_stack(&temp,stack->arr[stack->top]);
        Pop_stack(stack);
    }
    while(temp.top != -1)
    {
        printf("%c",temp.arr[temp.top]);
        Pop_stack(&temp);
    }
}

bool Isnum(char ch)         //判断是否是数字
{
    if(ch >= '0' && ch <= '9')
        return true;
    else
        return false;

}

int Cmp_level(char mark1,char mark2)            //比较两个运算符的优先级,mark1>mark2 返回正数,mark1==mark2 返回0,mark1<mark2,返回负数
{
    char mark_table[]={'+','-','*','/','(',')'};         //运算符集
    int mark_level_table[]={1,1,2,2,3,3};               //将对应运算符的优先级存储
    int table_len = sizeof(mark_table)/sizeof(mark_table[0]);       //运算符集的长度
    int mark_index,mark1_index,mark2_index;
    for(mark_index = 0; mark_index < table_len; mark_index++)      //找出需要比较的两个运算符的下标
    {
        if(mark1 == mark_table[mark_index])
            mark1_index = mark_index;
        if(mark2 == mark_table[mark_index])
            mark2_index = mark_index;
    }
    return mark_level_table[mark1_index] - mark_level_table[mark2_index];    //返回两个运算符的优先级差值
}

bool Ispush(char mark, struct Stack* stack)       //判断运算符是否能入栈
{
    if(Isempty(stack))             //栈为空就进栈
        return true;  
    else if(stack->arr[stack->top] == '(')           //栈顶是'('就进栈
        return true;  
    else if(Cmp_level(mark,stack->arr[stack->top]) > 0 && mark != ')')       //优先级大于并且不是')'栈顶也进栈
        return true;
    else 
        return false;

}

void Right_ope(struct Stack* stack)                 //右括号的操作
{
    while(stack->arr[stack->top] != '(')           //一直取出运算符栈顶元素到结果栈中,直到遇到'('为止
    {
        Push_stack(&stack2,stack->arr[stack->top]);
        Pop_stack(stack);
    }
    Pop_stack(stack);                   //将'('也出栈
}

void Switch(const char *exp, int  len)                //将中缀表达式转换为后缀表达式
{
    stack1.top = stack2.top = -1;
    for(int i = 0; i < len-1;  i++)
    {
        if(Isnum(exp[i]))     //如果是数字就如栈到结果栈中
        {
            Push_stack(&stack2,exp[i]);
        }
        else if(!Isnum(exp[i]))       //如果是运算符
        {
          
             if(Ispush(exp[i],&stack1))   //先判断是否满足运算符如栈条件
            {
                Push_stack(&stack1,exp[i]);
                printf("%c   %d\n",stack1.arr[stack1.top],stack1.top);
            }
             else if(exp[i] == ')')       //判断是否遇到了')'
            {
                Right_ope(&stack1);
            }
            else if(Cmp_level(exp[i],stack1.arr[stack1.top]) == 0) //表达式与符号栈顶元素如果是相同的优先级,那么就将符号栈顶元素出栈并入栈到结果中,且再将表达式如栈到符号栈
            {
                Push_stack(&stack2,stack1.arr[stack1.top]);
                Pop_stack(&stack1);
                Push_stack(&stack1,exp[i]);
            }
        }
    }
    while(stack1.top != -1)         //当遍历完表达式后,还需要将运算符栈中的内容全部导入结果栈中
    {
        Push_stack(&stack2,stack1.arr[stack1.top]);
        Pop_stack(&stack1);
    }
    Reverse_print(&stack2);        //逆序输出结果
}

int main(int argc, char *argv[])
{ 
    char str[]="1+((2+3)*4)-5";
    int len = sizeof(str)/sizeof(str[1]);
    Switch(str,len);
    return 0;
} 

结果输出:

 

猜你喜欢

转载自blog.csdn.net/guishangppy/article/details/126801674
今日推荐