中缀表达式转换为后缀表达式

本文介绍了一种算法,用于将中缀表达式转换为后缀表达式,包括使用栈来处理运算符的优先级,并提供了完整的C语言实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、基本概念

中缀表达式如1*2+(2-1), 其运算符一般出现在操作数之间, 因此称为中缀表达式,也就是大家编程中写的表达式。

将中缀表达式进行改写,变为后缀表达式 如上面的表达式1*2+(2-1), 就变为12*21-+;后缀表达式中不含有括号, 且后缀表达式的操作数和中缀表达式的操作数排列次序完全相同, 只是运算符的次序发生了改变。

如果你想做一个计算器,那么首先需要用户输入一串表达式,该表达式一般是中缀表达式,我们可以讲表达式记录下来,可是如何才能计算其值呢?需要两步,第一步就是将其装换为后缀表达式,第二步是计算值。今天来学习如何转换为后缀表达式。


二、问题描述
请编写程序将一个中缀表达式转换为后缀表达式。
输入:仅一行,是一个中缀表达式。输入的符号中只有这些基本符号“0123456789+-*/()”,并且不会出现形如2*-3的格式,所有数字都是个位数,“/”表示整除运算。
输出:仅一行,是转换后的后缀表达式。数字之间、运算符之间、数字和运算符之间都用一个空格隔开(参见样例)。
样例:in:8-(3+2*6)/5+4           out:8 3 2 6 * + 5 / - 4 +


三、算法分析

转换后的后缀表达式的操作数之间的顺序不会改变,但操作符的顺序会改变,我们用数组ans[]来保存转换后的结果。

遍历中缀表达式,当遇到操作数时,直接添加到ans后面;当遇到操作符时,则需要分别来处理如下(这里需要用到栈):

1.如果是‘(’,则直接压入栈;

2.如果是‘)’,则依次从栈中弹出操作符到ans的后面,直到遇到‘(’或者栈为空 {如果中缀表达式正确,则一定会碰到‘(’}

3.如果是其它操作符,若栈为空,则将其压入栈;若栈不空,且栈顶的操作符优先级大于或等于当前操作符的优先级,则将其弹出并添加到ans的后面,并继续与新的栈顶进行比较,直到栈为空或栈顶的优先级小于当前操作符的优先级,此时再将当前操作符入栈;若栈不空,且栈顶的操作符优先级小于当前操作符优先级,直接入栈。

4.遍历结束后,若栈中还有操作符,依次弹出并添加到ans即可。

stack_yutao.h

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

typedef char elemtype;
typedef struct
{
     elemtype *array;
     int size;
     int top;
}stack;

/*
function:initial the stack with the size
input:stack *s, int size
output:void
*/
void initStack(stack *s, int size)
{
     s->size = size;
     s->top = -1;
     s->array = (elemtype *)malloc(sizeof(elemtype) * s->size);
}

/*
function:check whether the stack is full
input:stack *s
output: 1--the stack is full; 0--the stack is not full
*/
int is_stack_full(stack *s)
{
     return (s->size - 1) <= s->top;
}

/*
function:check whether the stack is empty
input:stack *s
output: 1--the stack is empty; 0--the stack is not empty
*/
int is_stack_empty(stack *s)
{
     return s->top < 0;
}
/*
function:push data to the stack,if the stack is full, it will stop
input:stack *s, int data
output:void
*/
void push(stack *s, elemtype data)
{
     if (is_stack_full(s))
     {
          printf("The stack is also full !\n");
          exit(1);
     }else
     {
          s->top ++;
          s->array[s->top] = data;
     }
}

/*
function:pop from the stack and no data will be return ,if the stack is empty, it will stop
input:stac *s
output:void
*/
void pop(stack *s)
{
     if(is_stack_empty(s))
     {
          printf("The stack is also empty !\n");
		  system("pause");
          exit(1);
     }else
     {
          s->top --;
     }
}

/*
function:get the top element of the stack for data, if the stack is empty, it will stop
input:stack *s, int &data
output:void
*/
void get_top(stack *s, elemtype *data)
{
     if(is_stack_empty(s))
     {
          printf("The stack is also empty !\n");
		  system("pause");
          exit(1);
     }else
     {
          *data = s->array[s->top];
     }
}

/*
fucntion:destory the stack
input:stack *s
output:void
*/
void destory_stack(stack *s)
{
     free(s->array);
}

#include <stdio.h>
#include <stdlib.h>
#include "stack_yutao.h"

int compare(elemtype a, elemtype b);
void infix_to_postfix(const char infix_array[],int n, char postfix_array[]);
void display_array(elemtype array[], int n);

void infix_to_postfix(const char infix_array[],int n, char postfix_array[])
{
	int i;
	int index = 0;
	elemtype top_elem;
	elemtype stack_size = 5;
	stack char_stack;
	stack *s = &char_stack;

	initStack(s,stack_size);
	for(i = 0; i < n; i ++)
	{
		if(48 <= infix_array[i] && infix_array[i] <= 57)//若为0-9的数字,则直接将其复制到postfix,并continue到下一次循环
		{
			postfix_array[index ++] = infix_array[i];
			continue;
		}
		switch(infix_array[i])
		{
		case '(':
			if(!is_stack_full(s))
			{
				push(s,infix_array[i]);
			}
			break;
		case ')':
			get_top(s,&top_elem);
			if(!is_stack_empty && top_elem != '(')
			{
				postfix_array[index ++] = top_elem;
				pop(s);
				get_top(s,&top_elem);
			}
			if(top_elem == '(')
			{
				pop(s);
			}
			break;
		case '+':
		case '-':
		case '*':
		case '/':
            if(is_stack_empty(s))
            {
                push(s,infix_array[i]);
            }else
            {
                get_top(s,&top_elem);    
                while(compare(top_elem,infix_array[i]) >= 0 && top_elem != '(')
                {
                    postfix_array[index ++] = top_elem;
                    pop(s);
                    if(is_stack_empty(s))
                    {
                        break;
                    }else
                    {
                        get_top(s,&top_elem);
                    }                
                }
                push(s,infix_array[i]);
            }
            break;
        default:
            printf("There is wrong char in your infix_array !\n");
            break;
        }
    }
    while(!is_stack_empty(s))
    {
        get_top(s,&top_elem);
        postfix_array[index ++] = top_elem;
        pop(s);
    }
    postfix_array[index] = '\0';
}

int compare(elemtype a, elemtype b)
{
    if(a == '+' || a == '-')
    {
        if(b == '+' || b == '-')
        {
            return 0;
        }else
        {
            return -1;
        }
    }
    if(a == '*' || a == '/')
    {
        if(b == '+' || b == '-')
        {
            return 1;
        }
        if(b == '*' || b == '/')
        {
            return 0;
        }
        if(b == '(')
        {
            return -1;
        }
    }
    if(a == '(')
    {
        return 1;
    }
}

int main()
{elemtype infix_array[] = "8-(3+2*6)/5+4";
	int n = 13;
	elemtype postfix_array[13];
	infix_to_postfix(infix_array,n,postfix_array);
	display_array(infix_array,n);

	display_array(postfix_array,n);
	system("pause");
	return 0;
}

void display_array(elemtype array[], int n)
{
	int i;
	for (i = 0; i < n; i ++)
	{
		printf("%c ",array[i]);
	}
	printf("\n");
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值