中缀表达式转后缀、前缀表达式的方法

举一个中缀表达式的例子:a+b-a*((c+d)/e-f)+g

一、中缀表达式转后缀表达式

方法一:括号法

比较简单方便。

①按照运算符的优先级,对所有的运算单位加括号。

于是变成:(((a+b)-(a*(((c+d)/e)-f)))+g)

②从最里面的括号开始,依次把运算符号移动到对应的括号的后面

于是变成:(((ab)+(a(((cd)+e)/f)-)*)-g)+

③最后,把括号都去掉

于是变成:ab+acd+e/f-*-g+

 

方法二:利用语法树

略。

 

方法三:基于堆栈的算法

具体转换方式:

从左到右进行遍历。

1.遇到的是运算数,直接输出。

2.遇到的是左括号'(',直接压入堆栈(括号是最高优先级,无需比较;入栈后优先级降到最低,确保其他符号正常入栈)。

3.遇到的是右括号')',意味着括号已结束。不断弹出栈顶运算符并输出,直到遇到左括号,这个左括号弹出但是不输出。

4.遇到的是运算符('+'、'-'、'*'、'/'),有三种情况

①如果栈为空,直接入栈。

②如果栈顶元素是左括号'(',直接入栈。

③如果栈顶元素是运算符,则需要进行比较,

1-如果优先级大于栈顶运算符,则压入堆栈;

2-如果优先级小于等于栈顶运算符,则将栈顶运算符弹出并输出,然后比较新的栈顶运算符,直到优先级大于栈顶运算符或者栈空,再将该运算符入栈

5.如果对象处理完毕,则按顺序弹出并输出栈中所有运算符

算法如下:

/*
中缀转后缀
思路:
中缀存于一个字符数组infix[]里,有一个辅助栈s1,栈顶元素为top1,有一个结果栈s2,栈顶元素为top2。
从左向右扫描。i=0,当infix[i]!='\0'时,
1、碰到'0'-'9',存入s2中。
2、碰到'(',存入s1中。
3、碰到'+'、'-'、'*'、'/',
	如果栈为空,或者top1='(',或者运算符的优先级大于top1栈顶元素的优先级,存入s1中;否则s2[++top2]=s1[top1--]。
4、碰到')',将s1里截止到'('以前的元素全部放到s2中,并把'('丢掉
*/

//判断运算符的优先级
int getPriority(char op){
	if(op=='+'||op=='-')
		return 0; //+或-的优先级比较低
	else
		return 1;
}

void infixToPostFix(char infix[], char s2[], int &top2) //infix[]是中缀表达式存在数组里,s2是结果栈
{
	char s1[maxSize]; int top1=-1; //s1是辅助栈
	int i=0;
	while(infix[i]!='\0'){
		if('0'<=infix[i]&&infix[i]<='9'){ //如果扫描到'0'-'9'字符,将它放入s2
			s2[++top2]==infix[i];
			++i;
		}
		else if(infix[i]=='('){ //如果扫描到'(',将它放入s1
			s1[++top1]='(';
			++i;
		}
		else if(infix[i]=='+'|| //如果扫描到'+','-','*','/'字符,需要和s1里的元素进行判断
				infix[i]=='-'||
				infix[i]=='*'||
				infix[i]=='/'){
				if(top1==-1|| //判断s1是否为空
					s1[top1]=='('|| //判断辅助栈的栈顶元素是否为'('
					getPriority(infix[i])>getPriority(top1[top1])){ //判断表达式里元素的优先级是否大于s1元素的优先级
					s1[++top1]=infix[i];
					++i;
				}
				else //如果不是,将辅助站的运算符放入结果栈里
					s2[++top2]==s1[top1--];
		}
		else if(infix[i]==')'){
			while(s1[top1]!='(')
				s2[++top2]=s1[top1--];
			--top1; //删除s1里的'('
			++i;
		}
	}
	while(top1!=-1)
		s2[++top2]=s1[top1--]; //将s1中的元素都放入s2
}

 

二、中缀表达式转前缀表达式

和中缀表达式转后缀表达式类似,稍微有点区别。

方法一:括号法

比较简单方便。

①按照运算符的优先级,对所有的运算单位加括号。

于是变成:(((a+b)-(a*(((c+d)/e)-f)))+g)

②从最里面的括号开始,依次把运算符号移动到对应的括号的前面

于是变成:+(-(+(ab)*(a-(/(+(cd)e)f)))g)

③最后,把括号都去掉

于是变成:+-+ab*a-/+cdefg

 

方法二:利用语法树

略。

 

方法三:基于堆栈的算法

具体转换方式:

从右到左进行遍历。

1.遇到的是运算数,直接输出。

2.遇到的是右括号')',直接压入堆栈(括号是最高优先级,无需比较;入栈后优先级降到最低,确保其他符号正常入栈)。

3.遇到的是左括号'(',意味着括号已结束。不断弹出栈顶运算符并输出,直到遇到右括号,这个右括号弹出但是不输出。

4.遇到的是运算符('+'、'-'、'*'、'/'),有三种情况

①如果栈为空,直接入栈。

②如果栈顶元素是右括号')',直接入栈。

③如果栈顶元素是运算符,则需要进行比较,

1-如果优先级大于等于栈顶运算符,则压入堆栈;

2-如果优先级小于栈顶运算符,则将栈顶运算符弹出并输出,然后比较新的栈顶运算符,直到优先级大于等于栈顶运算符或者栈空,再将该运算符入栈

5.如果对象处理完毕,则按顺序弹出并输出栈中所有运算符

算法如下:

/*
中缀转前缀
思路:
中缀存于一个字符数组infix[]里,有一个辅助栈s1,栈顶元素为top1,有一个结果栈s2,栈顶元素为top2。
从右向左扫描。i=len-1,当i>=0时,
1、碰到'0'-'9',存入s2中。
2、碰到')',存入s1中。
3、碰到'+'、'-'、'*'、'/',
	如果栈为空,或者top1=')',运算符的优先级大于等于top1栈顶元素的优先级,存入s1中;否则s2[++top2]=s1[top1--]。
4、碰到'(',将s1里截止到')'以前的元素全部放到s2中,并把')'丢掉
*/

//判断运算符的优先级
int getPriority(char op){
	if(op=='+'||op=='-')
		return 0; //+或-的优先级比较低
	else
		return 1;
}

void infixToPreFix(char infix[], int len, char s2[], int top2){
	char s1[maxSize]; int top1=-1;
	int i=len-1;
	while(i>=0){
		if('0'<=infix[i]&&infix[i]<='9'){
			s2[++top2]=infix[i];
			--i;
		}
		else if(infix[i]==')'){
			s1[++top1]=')';
			--i;
		}
		else if(infix[i]=='+'||
				infix[i]=='-'||
				infix[i]=='*'||
				infix[i]=='/'){
			if(top1==-1||
				s1[top1]==')'||
				getPriority(infix[i])>=getPriority(s1[top1])){
				s1[++top1]=infix[i];
				--i;
			}
			else 
				s2[++top2]=s1[top1--];
		}
		if(infix[i]=='('){
			while(s1[top1]!=')')
				s2[++top2]=s1[top1--];
			--top1;
			--i;
		}
	}
	while(top1!=-1)
		s2[++top2]=s1[top1--];
}
  • 11
    点赞
  • 83
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
中缀表达式是我们常见的数学表达式的一种写法,它是以操作符位于操作数的两侧的形式来示计算顺序。而前缀表达式后缀表达式中缀表达式的另外两种等价的写法。 将中缀表达式换为前缀表达式方法如下: 1. 从右到左遍历中缀表达式的每个字符。 2. 如果字符是操作数,直接输出到前缀表达式。 3. 如果字符是操作符,有两种情况: - 如果操作符的优先级比栈顶操作符的优先级高,将操作符入栈。 - 如果操作符的优先级比栈顶操作符的优先级低或相等,弹出栈顶操作符,并将弹出的操作符和操作数组合为一个前缀表达式,再将该前缀表达式入栈。 4. 当遍历完中缀表达式后,将栈中的操作符依次弹出,并将每个弹出的操作符和操作数组合为一个前缀表达式,再将该前缀表达式入栈。 5. 最后得到的栈顶即为换后的前缀表达式。 将中缀表达式换为后缀表达式方法基本相同,只需将步骤3中操作符的优先级比较符号调整为"低或相等"即可。 中缀表达式后缀表达式方法如下: 1. 从左到右遍历中缀表达式的每个字符。 2. 如果字符是操作数,直接输出到后缀表达式。 3. 如果字符是操作符,有两种情况: - 如果操作符的优先级比栈顶操作符的优先级高或栈为空,将操作符入栈。 - 如果操作符的优先级比栈顶操作符的优先级低或相等,弹出栈顶操作符,并将弹出的操作符和操作数组合为一个后缀表达式,再将该后缀表达式入栈。 4. 当遍历完中缀表达式后,将栈中的操作符依次弹出,并将每个弹出的操作符和操作数组合为一个后缀表达式,再将该后缀表达式入栈。 5. 最后得到的栈顶即为换后的后缀表达式。 通过上述步骤,我们可以将中缀表达式换为前缀后缀表达式

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值