3.9 用栈实现中缀表达式转化成后缀表达式、后缀表达式求值

算法阐述:

voidtrans(char exp[ ],char postexp[ ])

{     

形参设计:传进2个字符数组的地址,第一个为中缀表达式的数组地址,将此       中缀表达式转化为后缀表达式赋给第二个地址所在的字符数组。

 

while(*exp!=’\0’)

{

switch(*exp)

{

(1)扫描为‘(’:进栈,exp++,break;

(2)扫描为‘)’:while(栈非空下){

此时不管栈顶是加减乘除还是‘(’ ,都要出栈,二者的区别在于非左括号的出栈后要添加到postexp数组中去,左括号则不用。

Pop(Optr,e);

while(e!=’(’)

{

postexp[i++] =e;

Pop(Optr,e);圆括号内的操作符逐一全部出栈进行判断

}

遇到‘(’跳出while循环,不对e做任何操作,继续遍历exp数组,

exp++;

break;

(1)     扫描为‘+’||‘-’:通过与此时栈顶元素比较优先级进而决定‘+’||‘-’直接进栈还是栈顶元素出栈后再让其进栈,故要

GotTop(optr,e);

while(!StackEmpty(optr))

{

  栈顶元素e为加减或乘除是其后操作相同都是让e先出栈,添加到postexp数组,只有当e为‘(’时,此时扫描到的加减后才直接进栈

  if(e!=’(’)

         Pop(optr,e);

         postexp[i++]=e;

  else

         break;

}

Push(optr,*exp);

exp++;

break;

 

 

(2)     扫描为’×’||‘÷’:通过与此时栈顶元素比较优先级进而决定’×’||‘÷’直接进栈还是栈顶元素出栈后再让其进栈,故要

GotTop(optr,e);

while(!StackEmpty(optr))

{

  栈顶元素e为加减或‘(’其后操作相同都是将此时扫描到的’×’||‘÷’直接进栈,

                     只有当e为乘除号时,才需让e出栈,添加到postexp数组,后该’×’||‘÷’才进栈。

  if(e==’*’||e==‘\’)

         postexp[i++]=e;

         Pop(optr,e);

  else

         break;

}

Push(optr,*exp);

exp++;

break;

 

(6) 其他扫描结果时(为数字):判断是否是数字,若是添加到postexp数组,后再往下扫描,若是继续做是否为数字的判断,若不是则跳出循环,后在数字串后加‘#’。

              default:while(*exp>=0&&*exp<=9)

                            {

                                   postexp[i++]==*exp;

                                   exp++;

}

postexp[i++]==’#’;

break;

}

 

}

 

扫描结束但栈不空,则要将栈中的操作符添加进postexp数组

while(!StackEmpty(optr))

{

       Pop(optr,e);

    postexp[i++]=e;

      

}

 

postexp[i]='\0';                 //给postexp表达式添加结束标识

DestroyStack(Optr);                 //销毁栈      


}

 

//求简单表达式的值
#include <stdio.h>
#include <stdlib.h>
#define MaxSize 100
//---------------------------------------------------------
//--运算符栈基本运算---------------------------------------
//---------------------------------------------------------
typedef struct 
{	char data[MaxSize];			//存放运算符
	int top;					//栈顶指针
} SqStack;
void InitStack(SqStack *&s)		//初始化栈
{	s=(SqStack *)malloc(sizeof(SqStack));
	s->top=-1;
}
void DestroyStack(SqStack *&s)	//销毁栈
{
	free(s);
}
bool StackEmpty(SqStack *s)		//判断栈是否为空 
{
	return(s->top==-1);
}
bool Push(SqStack *&s,char e)	//进栈元素e
{	if (s->top==MaxSize-1)
		return false;
	s->top++;
	s->data[s->top]=e;
	return true;
}
bool Pop(SqStack *&s,char &e)	//出栈元素e
{	if (s->top==-1)	
		return false;
	e=s->data[s->top];
	s->top--;
	return true;
}
bool GetTop(SqStack *s,char &e)	//取栈顶元素e
{	if (s->top==-1)	
		return false;
	e=s->data[s->top];
	return true;
}
//---------------------------------------------------------

void trans(char exp[],char postexp[])	//将算术表达式exp转换成后缀表达式postexp,形参设计为字符串数组 
{
	char e;
	SqStack *Optr;						//定义运算符栈
	InitStack(Optr);					//初始化运算符栈
	int i=0;							//i作为postexp的下标
	
	while (*exp!='\0')					//exp表达式未扫描完时循环
	{	switch(*exp)
		{
		case '(':						//判定为左括号
			Push(Optr,'(');				//左括号进栈
			exp++;						//继续扫描其他字符
			break;
		case ')':						//判定为右括号
			Pop(Optr,e);				//出栈元素e
			while (e!='(')				//不为'('时循环
			{
				postexp[i++]=e;			//将e存放到postexp中
				Pop(Optr,e);			//继续出栈元素e
			}
			exp++;						//继续扫描其他字符
			break;
		case '+':						//判定为加或减号
		case '-':
			while (!StackEmpty(Optr))	//栈不空循环
			{
				GetTop(Optr,e);			//取栈顶元素e
				if (e!='(')				//e不是'('
				{
					postexp[i++]=e;		//将e存放到postexp中
					Pop(Optr,e);		//出栈元素e
				}
				else					//e是'(时退出循环
					break;
			}
			Push(Optr,*exp);			//将'+'或'-'进栈
			exp++;						//继续扫描其他字符
			break;
		case '*':						//判定为'*'或'/'号
		case '/':
			while (!StackEmpty(Optr))	//栈不空循环
			{
				GetTop(Optr,e);			//取栈顶元素e
				if (e=='*' || e=='/')	//将栈顶'*'或'/'运算符出栈并存放到postexp中
				{
					postexp[i++]=e;		//将e存放到postexp中
					Pop(Optr,e);		//出栈元素e
				}
				else					//e为非'*'或'/'运算符时退出循环
					break;
			}
			Push(Optr,*exp);			//将'*'或'/'进栈
			exp++;						//继续扫描其他字符
			break;
		default:						 //处理数字字符
			while (*exp>='0' && *exp<='9') //判定为数字
			{	postexp[i++]=*exp;
				exp++;
			}
			postexp[i++]='#';	//用#标识一个数值串结束
		}
	}
	
	while (!StackEmpty(Optr))	//此时exp扫描完毕,栈不空时循环
	{
		Pop(Optr,e);			//出栈元素e
		postexp[i++]=e;			//将e存放到postexp中
	}
	postexp[i]='\0';			//给postexp表达式添加结束标识
	DestroyStack(Optr);			//销毁栈		
}
 

计算后缀表达式的值算法设计:

//---------------------------------------------------------

double compvalue(char *postexp)	//计算后缀表达式的值
{
	double d,a,b,c,e;
	SqStack1 *Opnb;				//定义操作数栈
	InitStack1(Opnb);			//初始化操作数栈
	while (*postexp!='\0')		//postexp字符串未扫描完时循环
	{	
		switch (*postexp)
		{
		case '+':				//判定为'+'号
			Pop1(Opnb,a);		//出栈元素a
			Pop1(Opnb,b);		//出栈元素b
			c=b+a;				//计算c
			Push1(Opnb,c);		//将计算结果c进栈
			break;
		case '-':				//判定为'-'号
			Pop1(Opnb,a);		//出栈元素a
			Pop1(Opnb,b);		//出栈元素b
			c=b-a;				//计算c
			Push1(Opnb,c);		//将计算结果c进栈
			break;
		case '*':				//判定为'*'号
			Pop1(Opnb,a);		//出栈元素a
			Pop1(Opnb,b);		//出栈元素b
			c=b*a;				//计算c
			Push1(Opnb,c);		//将计算结果c进栈
			break;
		case '/':				//判定为'/'号
			Pop1(Opnb,a);		//出栈元素a
			Pop1(Opnb,b);		//出栈元素b
			if (a!=0)
			{
				c=b/a;			//计算c
				Push1(Opnb,c);	//将计算结果c进栈
				break;
			}
			else
		    {	
				printf("\n\t除零错误!\n");
				exit(0);		//异常退出
			}
			break;
		default:				//处理数字字符
			d=0;				//将连续的数字字符转换成对应的数值存放到d中
			while (*postexp>='0' && *postexp<='9')   //判定为数字字符
			{	
				d=10*d+*postexp-'0';  
				postexp++;
			}
			Push1(Opnb,d);		//将数值d进栈

			break;
		}
		postexp++;				//继续处理其他字符
	}
	GetTop1(Opnb,e);			//取栈顶元素e
	DestroyStack1(Opnb);		//销毁栈		
	return e;					//返回e
}


int main()
{
	char exp[]="(4/2)*3";
	char postexp[MaxSize];
	trans(exp,postexp);
	printf("中缀表达式:%s\n",exp);
	printf("后缀表达式:%s\n",postexp);
	printf("表达式的值:%g\n",compvalue(postexp));
	return 1;
}




  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是使用C语言实现中缀表达式转化成后缀表达式的示例代码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> // 定义操作符的优先级 #define ADD_SUB 1 #define MUL_DIV 2 #define POWER 3 // 定义的最大容量 #define MAX_STACK_SIZE 100 // 定义结构体 typedef struct { int top; char data[MAX_STACK_SIZE]; } Stack; // 初始化 void initStack(Stack *stack) { stack->top = -1; } // 判断是否为空 int isEmpty(Stack *stack) { return stack->top == -1; } // 判断是否已满 int isFull(Stack *stack) { return stack->top == MAX_STACK_SIZE - 1; } // 入 void push(Stack *stack, char c) { if (isFull(stack)) { printf("Error: Stack is full\n"); exit(-1); } stack->data[++stack->top] = c; } // 出 char pop(Stack *stack) { if (isEmpty(stack)) { printf("Error: Stack is empty\n"); exit(-1); } return stack->data[stack->top--]; } // 获取顶元素 char peek(Stack *stack) { if (isEmpty(stack)) { printf("Error: Stack is empty\n"); exit(-1); } return stack->data[stack->top]; } // 判断是否为操作符 int isOperator(char c) { return c == '+' || c == '-' || c == '*' || c == '/' || c == '^'; } // 获取操作符的优先级 int getPriority(char c) { if (c == '+' || c == '-') { return ADD_SUB; } else if (c == '*' || c == '/') { return MUL_DIV; } else if (c == '^') { return POWER; } else { printf("Error: Invalid operator '%c'\n", c); exit(-1); } } // 中缀表达式转化成后缀表达式 void infixToPostfix(char *infix, char *postfix) { Stack stack; initStack(&stack); int i, j; for (i = 0, j = 0; infix[i] != '\0'; i++) { if (isdigit(infix[i])) { // 如果是数字,直接添加到后缀表达式中 postfix[j++] = infix[i]; } else if (isOperator(infix[i])) { // 如果是操作符,弹出中优先级大于等于该操作符的所有操作符,添加到后缀表达式中 while (!isEmpty(&stack) && isOperator(peek(&stack)) && getPriority(peek(&stack)) >= getPriority(infix[i])) { postfix[j++] = pop(&stack); } // 将该操作符入 push(&stack, infix[i]); } else if (infix[i] == '(') { // 如果是左括号,直接入 push(&stack, infix[i]); } else if (infix[i] == ')') { // 如果是右括号,弹出中所有左括号之前的操作符,添加到后缀表达式中 while (!isEmpty(&stack) && peek(&stack) != '(') { postfix[j++] = pop(&stack); } // 弹出左括号 if (!isEmpty(&stack) && peek(&stack) == '(') { pop(&stack); } else { printf("Error: Mismatched parentheses\n"); exit(-1); } } else { printf("Error: Invalid character '%c'\n", infix[i]); exit(-1); } } // 弹出中所有操作符,添加到后缀表达式中 while (!isEmpty(&stack)) { if (peek(&stack) == '(') { printf("Error: Mismatched parentheses\n"); exit(-1); } postfix[j++] = pop(&stack); } postfix[j] = '\0'; // 添加字符串结束符 } int main() { char infix[100], postfix[100]; printf("Enter an infix expression: "); scanf("%s", infix); infixToPostfix(infix, postfix); printf("Postfix expression: %s\n", postfix); return 0; } ``` 使用示例: ``` Enter an infix expression: 3+4*5-6/2^(1+2) Postfix expression: 345*+612+/^- ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值