中缀表达式转 前缀、后缀表达式(java)

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

这里的运算思路跟我代码一样,所以我就直接借鉴的别人的

逆波兰表达式又称作后缀表达式,在四则混合运算的程序设计中用到。

例如:

1+2写成后缀表达式就是12+

4+5*(3-2)的后缀表达式就是4532-*+

后缀表达式在四则运算中带来了意想不到的方便,在生成过程中自动保持了优先级;

生成逆波兰表达式的算法如下:

我们首先的用两个栈结构来存储运算符和操作数,在java中有Stack类可以用;

从做到右遍历我们输入的中缀表达式:

1、如果是操作数的话,那么就直接压入存放操作数的堆栈;

2、如果是"("左括号的话,那么就直接压入存放运算符的堆栈;

3、如果是")"右括号的话,那么就从运算符堆栈中弹数据,并将弹出的数据压入到操作数堆栈中,直到遇到"("为止,这里值得注意的是,"("是必须要从运算符堆栈中弹出的,但是不压入到操作数堆栈,后缀表达式中是不包含括号的;

4、如果是其他符号,就是其他的运算符+-*/这些,那么就:

a、如果运算符堆栈为空,则直接压入运算符堆栈;

b、如果不为空且此时运算符堆栈的栈顶元素为左括号(不可能为')'),那么也是直接压入运算符堆栈中;

c、如果此时遍历到的元素的优先级比此时运算符堆栈栈顶元素的优先级高,则直接压入运算符堆栈;

d、如果正在遍历的元素的优先级和运算符堆栈栈顶的元素的优先级相等或者更小,则需要将栈顶元素弹出并且放到操作数堆栈                中,并且将正在遍历的元素压入到运算符堆栈,其实运算符堆栈中的元素顺序就是优先级的顺序;

5、直到遍历完表达式,此时还需要将运算符堆栈中的所有元素压入到操作数堆栈中,算法完成。


以下是我的代码:

import java.util.*;
public class CPrograms2 {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		char[] input = sc.nextLine().toCharArray();
		char[] operator = new char[input.length];		//运算符栈
		char[] result = new char[input.length];			//用来保存后缀结果
		int ir = 0,io = 0;					//ir为result下标,表示存储下一个元素待插入的位置;io为operator下包,同ir
		
		for (int i=0;i<input.length;i++){	                //遍历每一个字符
			char c = input[i];
			
			if (c >= '0' && c <= '9')		         //c如果是数字,则直接放到result中
				result[ir++] = c;
			else if (c == '(')				//'('直接放到operateor中			
					operator[io++] = c;		
			else if (c == ')'){				//如果c是')',则把上一个'('和c之间的所有运算符都放到result中,最后io指向待插入位置的下标
				while (operator[io] != '(')
					result[ir++] = operator[io--];
			} else if(io == 0)				//c为+-*/时,io为0,直接把c放到operator中
				operator[io++] = c;
			else {						//c为+-*/时,io不为0。注意:( ) * + - /的ASCII码分别为40 41 42 43 45 47
				if (operator[io-1]=='(')	        //如果operator[io-1]为'(',优先级最低,直接放到operator中
					operator[io] = c;
				else{					//c不为'(',则为+-*/,比较c与上一个运算符的优先级。+-为0,*/为1
					int	priorityPre = operator[io-1]==42 || operator[io-1]==47 ? 1 : 0;		//获取上一个运算符的优先级
					int priorityCur = c==42 || c==47 ? 1 : 0;					//获取c的优先级
					if (priorityCur <= priorityPre){						//比上一个优先级低,上一个出栈,c保留
						result[ir++] = operator[io-1];									
						operator[io-1] = c;
					}else										//比上一个优先级高,c直接保留
						operator[io++] = c;
				}
			}
		}
		
		while (io > 0)						//将operator中剩下的运算符按出栈顺序保存到result中
			result[ir++] = operator[--io];
		
		for (int i=0;i<input.length;++i)			//打印结果
			System.out.print(result[i]);
	}
}

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

接下来是中缀表达式转前缀表达式,与转后缀不同的地方是:从右到左遍历(注意'('、')'的互换),求出第一个结果之后,然后再把结果从后往前打印(类似于出栈操作)即是前缀表达式。以下是输入案例,仅供参考。

中序表达式

2*3/(2-1)+3*(4-1)

前序表达式

+/*23-21*3-41

后序表达式

23*21-/341-*+


以下注释“********”的代码是与转后缀表达式代码不同的地方(上面)

import java.util.*;
public class CPrograms2 {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		char[] input = sc.nextLine().toCharArray();
		char[] operator = new char[input.length];		 
		char[] result = new char[input.length];		//用来保存后缀结果
		int ir = 0,io = 0;			        //ir为result下标,表示存储下一个元素待插入的位置;io为operator下包,同ir
		
		for (int i=input.length-1;i>=0;i--){	//**************倒过来遍历每一个字符
			char c = input[i];
			
			if (c >= '0' && c <= '9')		//c如果是数字,则直接放到result中
				result[ir++] = c;
			else if (c == ')')			//*********因为是倒过来的,所以这里和下面程序的'('与')'互换		
					operator[io++] = c;		
			else if (c == '('){			//*********如果c是'(',则把上一个'('和c之间的所有运算符都放到result中,最后io指向待插入位置的下标
				while (operator[io] != ')')	//*********
					result[ir++] = operator[io--];
			} else if(io == 0)			//c为+-*/时,io为0,直接把c放到operator中
				operator[io++] = c;
			else {					//c为+-*/时,io不为0。注意:( ) * + - /的ASCII码分别为40 41 42 43 45 47
				if (operator[io-1]==')')	//**********如果operator[io-1]为'(',优先级最低,直接放到operator中
					operator[io] = c;
				else{						//c不为'(',则为+-*/,比较c与上一个运算符的优先级。+-为0,*/为1
					int	priorityPre = operator[io-1]==42 || operator[io-1]==47 ? 1 : 0;		//获取上一个运算符的优先级
					int priorityCur = c==42 || c==47 ? 1 : 0;	//获取c的优先级
					if (priorityCur <= priorityPre){		//比上一个优先级低,上一个出栈,c保留
						result[ir++] = operator[io-1];								
						operator[io-1] = c;
					}else						//比上一个优先级高,c直接保留
						operator[io++] = c;
				}
			}
		}
		
		while (io > 0)					//将operator中剩下的运算符按出栈顺序保存到result中
			result[ir++] = operator[--io];
		
		for (int i=ir-1;i>=0;i--)			//*********倒过来打印结果
			System.out.print(result[i]);
	}
}

三、如果通过前缀、后缀表达式求中缀表达式的值

对于前缀表达式,从右往左读取,遇到运算符时,把运算符右边最近的两个数进行运算(如‘3*-124’就是‘3*(-1)4’),以此类推,知道只剩下一个数即为结果。

对于后缀表达式,从左往右读取,遇到运算符时,把运算符左边最近的两个数进行运算(如‘412-*3’就是‘4(-1)*3’),以此类推,知道只剩下一个数即为结果。

  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
中缀表达式是我们常见的数学表达式的一种写法,它是以操作符位于操作数的两侧的形式来表示计算顺序。而前缀表达式和后缀表达式中缀表达式的另外两种等价的写法。 将中缀表达式换为前缀表达式的方法如下: 1. 从右到左遍历中缀表达式的每个字符。 2. 如果字符是操作数,直接输出到前缀表达式。 3. 如果字符是操作符,有两种情况: - 如果操作符的优先级比栈顶操作符的优先级高,将操作符入栈。 - 如果操作符的优先级比栈顶操作符的优先级低或相等,弹出栈顶操作符,并将弹出的操作符和操作数组合为一个前缀表达式,再将该前缀表达式入栈。 4. 当遍历完中缀表达式后,将栈中的操作符依次弹出,并将每个弹出的操作符和操作数组合为一个前缀表达式,再将该前缀表达式入栈。 5. 最后得到的栈顶即为换后的前缀表达式。 将中缀表达式换为后缀表达式的方法基本相同,只需将步骤3中操作符的优先级比较符号调整为"低或相等"即可。 中缀表达式后缀表达式的方法如下: 1. 从左到右遍历中缀表达式的每个字符。 2. 如果字符是操作数,直接输出到后缀表达式。 3. 如果字符是操作符,有两种情况: - 如果操作符的优先级比栈顶操作符的优先级高或栈为空,将操作符入栈。 - 如果操作符的优先级比栈顶操作符的优先级低或相等,弹出栈顶操作符,并将弹出的操作符和操作数组合为一个后缀表达式,再将该后缀表达式入栈。 4. 当遍历完中缀表达式后,将栈中的操作符依次弹出,并将每个弹出的操作符和操作数组合为一个后缀表达式,再将该后缀表达式入栈。 5. 最后得到的栈顶即为换后的后缀表达式。 通过上述步骤,我们可以将中缀表达式换为前缀和后缀表达式

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值